Skip to content

Commit

Permalink
[OpenMP] Fix passing of -m arguments correctly
Browse files Browse the repository at this point in the history
The recent fix in D38258 was wrong: getAuxTriple() only returns
non-null values for the CUDA toolchain. That is why the now added
test for PPC and X86 failed.

Differential Revision: https://reviews.llvm.org/D38372

llvm-svn: 314902
  • Loading branch information
hahnjo committed Oct 4, 2017
1 parent bd5d2f0 commit bbf56fb
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 70 deletions.
9 changes: 2 additions & 7 deletions clang/include/clang/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,9 @@ class ToolChain {
/// TranslateOpenMPTargetArgs - Create a new derived argument list for
/// that contains the OpenMP target specific flags passed via
/// -Xopenmp-target -opt=val OR -Xopenmp-target=<triple> -opt=val
/// Translation occurs only when the \p DeviceOffloadKind is specified.
///
/// \param DeviceOffloadKind - The device offload kind used for the
/// translation.
virtual llvm::opt::DerivedArgList *TranslateOpenMPTargetArgs(
const llvm::opt::DerivedArgList &Args,
Action::OffloadKind DeviceOffloadKind,
SmallVector<llvm::opt::Arg *, 4> &AllocatedArgs) const;
const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,
SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const;

/// Choose a tool to use to handle the action \p JA.
///
Expand Down
10 changes: 8 additions & 2 deletions clang/lib/Driver/Compilation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,15 @@ Compilation::getArgsForToolChain(const ToolChain *TC, StringRef BoundArch,
DerivedArgList *&Entry = TCArgs[{TC, BoundArch, DeviceOffloadKind}];
if (!Entry) {
SmallVector<Arg *, 4> AllocatedArgs;
DerivedArgList *OpenMPArgs = nullptr;
// Translate OpenMP toolchain arguments provided via the -Xopenmp-target flags.
DerivedArgList *OpenMPArgs = TC->TranslateOpenMPTargetArgs(
*TranslatedArgs, DeviceOffloadKind, AllocatedArgs);
if (DeviceOffloadKind == Action::OFK_OpenMP) {
const ToolChain *HostTC = getSingleOffloadToolChain<Action::OFK_Host>();
bool SameTripleAsHost = (TC->getTriple() == HostTC->getTriple());
OpenMPArgs = TC->TranslateOpenMPTargetArgs(
*TranslatedArgs, SameTripleAsHost, AllocatedArgs);
}

if (!OpenMPArgs) {
Entry = TC->TranslateArgs(*TranslatedArgs, BoundArch, DeviceOffloadKind);
if (!Entry)
Expand Down
116 changes: 55 additions & 61 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -801,74 +801,68 @@ ToolChain::computeMSVCVersion(const Driver *D,
}

llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs(
const llvm::opt::DerivedArgList &Args,
Action::OffloadKind DeviceOffloadKind,
SmallVector<llvm::opt::Arg *, 4> &AllocatedArgs) const {
if (DeviceOffloadKind == Action::OFK_OpenMP) {
DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
const OptTable &Opts = getDriver().getOpts();
bool Modified = false;

// Handle -Xopenmp-target flags
for (Arg *A : Args) {
// Exclude flags which may only apply to the host toolchain.
// Do not exclude flags when the host triple (AuxTriple)
// matches the current toolchain triple. If it is not present
// at all, target and host share a toolchain.
if (A->getOption().matches(options::OPT_m_Group)) {
if (!getAuxTriple() || getAuxTriple()->str() == getTriple().str())
DAL->append(A);
else
Modified = true;
continue;
}

unsigned Index;
unsigned Prev;
bool XOpenMPTargetNoTriple = A->getOption().matches(
options::OPT_Xopenmp_target);

if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
// Passing device args: -Xopenmp-target=<triple> -opt=val.
if (A->getValue(0) == getTripleString())
Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
else
continue;
} else if (XOpenMPTargetNoTriple) {
// Passing device args: -Xopenmp-target -opt=val.
Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
} else {
const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,
SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const {
DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
const OptTable &Opts = getDriver().getOpts();
bool Modified = false;

// Handle -Xopenmp-target flags
for (Arg *A : Args) {
// Exclude flags which may only apply to the host toolchain.
// Do not exclude flags when the host triple (AuxTriple)
// matches the current toolchain triple. If it is not present
// at all, target and host share a toolchain.
if (A->getOption().matches(options::OPT_m_Group)) {
if (SameTripleAsHost)
DAL->append(A);
else
Modified = true;
continue;
}

unsigned Index;
unsigned Prev;
bool XOpenMPTargetNoTriple =
A->getOption().matches(options::OPT_Xopenmp_target);

if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
// Passing device args: -Xopenmp-target=<triple> -opt=val.
if (A->getValue(0) == getTripleString())
Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
else
continue;
}

// Parse the argument to -Xopenmp-target.
Prev = Index;
std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
if (!XOpenMPTargetArg || Index > Prev + 1) {
getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
<< A->getAsString(Args);
continue;
}
if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&
Args.getAllArgValues(
options::OPT_fopenmp_targets_EQ).size() != 1) {
getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple);
continue;
}
XOpenMPTargetArg->setBaseArg(A);
A = XOpenMPTargetArg.release();
AllocatedArgs.push_back(A);
} else if (XOpenMPTargetNoTriple) {
// Passing device args: -Xopenmp-target -opt=val.
Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
} else {
DAL->append(A);
Modified = true;
continue;
}

if (Modified) {
return DAL;
} else {
delete DAL;
// Parse the argument to -Xopenmp-target.
Prev = Index;
std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
if (!XOpenMPTargetArg || Index > Prev + 1) {
getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
<< A->getAsString(Args);
continue;
}
if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&
Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) {
getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple);
continue;
}
XOpenMPTargetArg->setBaseArg(A);
A = XOpenMPTargetArg.release();
AllocatedArgs.push_back(A);
DAL->append(A);
Modified = true;
}

if (Modified)
return DAL;

delete DAL;
return nullptr;
}
8 changes: 8 additions & 0 deletions clang/test/Driver/openmp-offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@

/// ###########################################################################

/// Check -march=pwr7 is NOT passed to x86_64-unknown-linux-gnu.
// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=x86_64-unknown-linux-gnu -march=pwr7 %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-FOPENMP-MARCH-TO-X86 %s

// CHK-FOPENMP-MARCH-TO-X86-NOT: clang{{.*}} "-target-cpu" "pwr7" {{.*}}"-fopenmp-is-device"

/// ###########################################################################

/// Check -Xopenmp-target triggers error when multiple triples are used.
// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu,powerpc64le-unknown-linux-gnu -Xopenmp-target -mcpu=pwr8 %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-FOPENMP-TARGET-AMBIGUOUS-ERROR %s
Expand Down

0 comments on commit bbf56fb

Please sign in to comment.