[AMDGPU][OpenMP] Fix clang driver crash when provided -c

The offload action is used in four different ways as explained
in Driver.cpp:4495. When -c is present, the final phase will be
assemble (linker when -c is not present). However, this phase
is skipped according to D96769 for amdgcn. So, offload action
arrives into following situation,

 compile (device) ---> offload ---> offload

without -c the chain looks like,
 compile (device) ---> offload ---> linker (device)
				---> offload

The former situation creates an unhandled case which causes
problem. The solution presented in this patch delays the D96769
logic until job creation time. This keeps the offload action
in the 1 of the 4 specified situations.

Reviewed By: JonChesterfield

Differential Revision: https://reviews.llvm.org/D101901
This commit is contained in:
Pushpinder Singh 2021-05-05 12:02:25 +00:00
parent ae2aef1361
commit 1f5cacfcb8
2 changed files with 39 additions and 15 deletions

View File

@ -3100,16 +3100,8 @@ class OffloadingActionBuilder final {
}
// By default, we produce an action for each device arch.
for (unsigned I = 0; I < ToolChains.size(); ++I) {
Action *&A = OpenMPDeviceActions[I];
// AMDGPU does not support linking of object files, so we skip
// assemble and backend actions to produce LLVM IR.
if (ToolChains[I]->getTriple().isAMDGCN() &&
(CurPhase == phases::Assemble || CurPhase == phases::Backend))
continue;
for (Action *&A : OpenMPDeviceActions)
A = C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A);
}
return ABRT_Success;
}
@ -4594,6 +4586,25 @@ InputInfo Driver::BuildJobsForActionNoCache(
if (!T)
return InputInfo();
if (BuildingForOffloadDevice &&
A->getOffloadingDeviceKind() == Action::OFK_OpenMP) {
if (TC->getTriple().isAMDGCN()) {
// AMDGCN treats backend and assemble actions as no-op because
// linker does not support object files.
if (const BackendJobAction *BA = dyn_cast<BackendJobAction>(A)) {
return BuildJobsForAction(C, *BA->input_begin(), TC, BoundArch,
AtTopLevel, MultipleArchs, LinkingOutput,
CachedResults, TargetDeviceOffloadKind);
}
if (const AssembleJobAction *AA = dyn_cast<AssembleJobAction>(A)) {
return BuildJobsForAction(C, *AA->input_begin(), TC, BoundArch,
AtTopLevel, MultipleArchs, LinkingOutput,
CachedResults, TargetDeviceOffloadKind);
}
}
}
// If we've collapsed action list that contained OffloadAction we
// need to build jobs for host/device-side inputs it may have held.
for (const auto *OA : CollapsedOffloadActions)

View File

@ -26,12 +26,14 @@
// CHECK-PHASES: 6: preprocessor, {5}, cpp-output, (device-openmp)
// CHECK-PHASES: 7: compiler, {6}, ir, (device-openmp)
// CHECK-PHASES: 8: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (amdgcn-amd-amdhsa)" {7}, ir
// CHECK-PHASES: 9: linker, {8}, image, (device-openmp)
// CHECK-PHASES: 10: offload, "device-openmp (amdgcn-amd-amdhsa)" {9}, image
// CHECK-PHASES: 11: clang-offload-wrapper, {10}, ir, (host-openmp)
// CHECK-PHASES: 12: backend, {11}, assembler, (host-openmp)
// CHECK-PHASES: 13: assembler, {12}, object, (host-openmp)
// CHECK-PHASES: 14: linker, {4, 13}, image, (host-openmp)
// CHECK-PHASES: 9: backend, {8}, assembler, (device-openmp)
// CHECK-PHASES: 10: assembler, {9}, object, (device-openmp)
// CHECK-PHASES: 11: linker, {10}, image, (device-openmp)
// CHECK-PHASES: 12: offload, "device-openmp (amdgcn-amd-amdhsa)" {11}, image
// CHECK-PHASES: 13: clang-offload-wrapper, {12}, ir, (host-openmp)
// CHECK-PHASES: 14: backend, {13}, assembler, (host-openmp)
// CHECK-PHASES: 15: assembler, {14}, object, (host-openmp)
// CHECK-PHASES: 16: linker, {4, 15}, image, (host-openmp)
// handling of --libomptarget-amdgcn-bc-path
// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 --libomptarget-amdgcn-bc-path=%S/Inputs/hip_dev_lib/libomptarget-amdgcn-gfx803.bc %s 2>&1 | FileCheck %s --check-prefix=CHECK-LIBOMPTARGET
@ -58,3 +60,14 @@
// RUN: | FileCheck %s --check-prefix=CHECK-SAVE-ASM
// CHECK-SAVE-ASM: llc{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906-linked.bc" "-mtriple=amdgcn-amd-amdhsa" "-mcpu=gfx906" "-filetype=asm" "-o"{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906.s"
// CHECK-SAVE-ASM: llc{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906-linked.bc" "-mtriple=amdgcn-amd-amdhsa" "-mcpu=gfx906" "-filetype=obj" "-o"{{.*}}amdgpu-openmp-toolchain-{{.*}}-gfx906.o"
// check the handling of -c
// RUN: env LIBRARY_PATH=%S/Inputs/hip_dev_lib %clang -ccc-print-bindings -c --target=x86_64-unknown-linux-gnu -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx906 -save-temps %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-C
// CHECK-C: "x86_64-unknown-linux-gnu" - "clang",
// CHECK-C: "x86_64-unknown-linux-gnu" - "clang",{{.*}}output: "[[HOST_BC:.*]]"
// CHECK-C: "amdgcn-amd-amdhsa" - "clang",{{.*}}output: "[[DEVICE_I:.*]]"
// CHECK-C: "amdgcn-amd-amdhsa" - "clang", inputs: ["[[DEVICE_I]]", "[[HOST_BC]]"]
// CHECK-C: "x86_64-unknown-linux-gnu" - "clang"
// CHECK-C: "x86_64-unknown-linux-gnu" - "clang::as"
// CHECK-C: "x86_64-unknown-linux-gnu" - "offload bundler"