[Clang] Fix the new driver crashing when using '-fsyntax-only'
authorJoseph Huber <jhuber6@vols.utk.edu>
Thu, 1 Sep 2022 22:04:49 +0000 (17:04 -0500)
committerJoseph Huber <jhuber6@vols.utk.edu>
Wed, 7 Sep 2022 00:49:47 +0000 (19:49 -0500)
The new driver currently crashses when attempting to use the
'-fsyntax-only' option. This is because the option causes all output to
be given the `TY_Nothing' type which should signal the end of the
pipeline. The new driver was not treating this correctly and attempting
to use empty input. This patch fixes the handling so we do not attempt
to continue when the input is nothing.

One concession is that we must now check when generating the arguments
for Clang if the input is of 'TY_Nothing'. This is because the new
driver will only create code if the device code is a dependency on the
host, creating the output without the dependency would require a
complete rewrite of the logic as we do not maintain any state between
calls to 'BuildOffloadingActions' so I believe this is the most
straightforward method.

Reviewed By: tra

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

clang/lib/Driver/Driver.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/test/Driver/cuda-bindings.cu
clang/test/Driver/hip-binding.hip
clang/test/Driver/openmp-offload.c

index 36fba5d91eaf45791acb9c513a3aec7d4c63f1b1..9517331ade26b36663d39e5e4c8b7b5c1c223ca6 100644 (file)
@@ -4309,10 +4309,14 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
 
       auto TCAndArch = TCAndArchs.begin();
       for (Action *&A : DeviceActions) {
+        if (A->getType() == types::TY_Nothing)
+          continue;
+
         A = ConstructPhaseAction(C, Args, Phase, A, Kind);
 
         if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
-            Kind == Action::OFK_OpenMP) {
+            Kind == Action::OFK_OpenMP &&
+            HostAction->getType() != types::TY_Nothing) {
           // OpenMP offloading has a dependency on the host compile action to
           // identify which declarations need to be emitted. This shouldn't be
           // collapsed with any other actions so we can use it in the device.
@@ -4380,11 +4384,15 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
              nullptr, Action::OFK_None);
   }
 
+  // If we are unable to embed a single device output into the host, we need to
+  // add each device output as a host dependency to ensure they are still built.
+  bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](Action *A) {
+    return A->getType() == types::TY_Nothing;
+  }) && isa<CompileJobAction>(HostAction);
   OffloadAction::HostDependence HDep(
       *HostAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
       /*BoundArch=*/nullptr, isa<CompileJobAction>(HostAction) ? DDep : DDeps);
-  return C.MakeAction<OffloadAction>(
-      HDep, isa<CompileJobAction>(HostAction) ? DDep : DDeps);
+  return C.MakeAction<OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
 }
 
 Action *Driver::ConstructPhaseAction(
index d3b5f82cb5c2095086960203d598a675e55d840d..837486971d1127691bf2b71866e32da1e514ad3e 100644 (file)
@@ -4496,8 +4496,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   const InputInfo *CudaDeviceInput = nullptr;
   const InputInfo *OpenMPDeviceInput = nullptr;
   for (const InputInfo &I : Inputs) {
-    if (&I == &Input) {
-      // This is the primary input.
+    if (&I == &Input || I.getType() == types::TY_Nothing) {
+      // This is the primary input or contains nothing.
     } else if (IsHeaderModulePrecompile &&
                types::getPrecompiledType(I.getType()) == types::TY_PCH) {
       types::ID Expected = HeaderModuleInput.getType();
index 6c4398b706973f016f7e38695c2c1f8776204b58..3cc65b8cf98bc5796c149da48bbd7d67bcceb288 100644 (file)
 // RUN:        --offload-arch=sm_70 --offload-arch=sm_52 --offload-device-only -c -o %t %s 2>&1 \
 // RUN: | FileCheck -check-prefix=MULTI-D-ONLY-O %s
 // MULTI-D-ONLY-O: error: cannot specify -o when generating multiple output files
+
+//
+// Check to ensure that we can use '-fsyntax-only' for CUDA output with the new
+// driver.
+// 
+// RUN: %clang -### -target powerpc64le-ibm-linux-gnu --offload-new-driver \
+// RUN:        -fsyntax-only --offload-arch=sm_70 --offload-arch=sm_52 -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=SYNTAX-ONLY %s
+// SYNTAX-ONLY: "-cc1" "-triple" "nvptx64-nvidia-cuda"{{.*}}"-fsyntax-only"
+// SYNTAX-ONLY: "-cc1" "-triple" "nvptx64-nvidia-cuda"{{.*}}"-fsyntax-only"
+// SYNTAX-ONLY: "-cc1" "-triple" "powerpc64le-ibm-linux-gnu"{{.*}}"-fsyntax-only"
index 0790fc89c422720f04bfedbc9dbc314b912fc300..6875af6a85c108c76ae89489fb7707ee5e2a6f91 100644 (file)
 // RUN:        --offload-arch=gfx90a --offload-arch=gfx908 --offload-device-only -c -o %t %s 2>&1 \
 // RUN: | FileCheck -check-prefix=MULTI-D-ONLY-O %s
 // MULTI-D-ONLY-O: error: cannot specify -o when generating multiple output files
+
+//
+// Check to ensure that we can use '-fsyntax-only' for HIP output with the new
+// driver.
+// 
+// RUN: %clang -### -target x86_64-unknown-linux-gnu --offload-new-driver \
+// RUN:        -fsyntax-only --offload-arch=gfx90a --offload-arch=gfx908 -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=SYNTAX-ONLY %s
+// SYNTAX-ONLY: "-cc1" "-triple" "amdgcn-amd-amdhsa"{{.*}}"-fsyntax-only"
+// SYNTAX-ONLY: "-cc1" "-triple" "amdgcn-amd-amdhsa"{{.*}}"-fsyntax-only"
+// SYNTAX-ONLY: "-cc1" "-triple" "x86_64-unknown-linux-gnu"{{.*}}"-fsyntax-only"
index 5567699ed03b041c20e2e3cf3b58a6b3d73e5f8b..377359d1332244e1dd95010bbdafa73ac2f90626 100644 (file)
 // RUN:     -mllvm -abc %s 2>&1 | FileCheck -check-prefix=CHK-NEW-DRIVER-MLLVM %s
 
 // CHK-NEW-DRIVER-MLLVM: clang-linker-wrapper{{.*}} "-abc"
+
+//
+// Ensure that we generate the correct bindings for '-fsyntax-only' for OpenMP.
+//
+// RUN:   %clang -### --target=powerpc64le-linux -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu \
+// RUN:     -fsyntax-only -ccc-print-bindings %s 2>&1 | FileCheck -check-prefix=CHK-SYNTAX-ONLY %s
+// CHK-SYNTAX-ONLY: # "powerpc64le-ibm-linux-gnu" - "clang", inputs: ["[[INPUT:.+]]"], output: (nothing)
+// CHK-SYNTAX-ONLY: # "powerpc64le-unknown-linux" - "clang", inputs: ["[[INPUT]]", (nothing)], output: (nothing)
+
+//
+// Ensure that we can generate the correct arguments for '-fsyntax-only' for
+// OpenMP.
+//
+// RUN:   %clang -### --target=powerpc64le-linux -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu \
+// RUN:     -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHK-SYNTAX-ONLY-ARGS %s
+// CHK-SYNTAX-ONLY-ARGS: "-cc1" "-triple" "powerpc64le-ibm-linux-gnu"{{.*}}"-fsyntax-only"
+// CHK-SYNTAX-ONLY-ARGS: "-cc1" "-triple" "powerpc64le-unknown-linux"{{.*}}"-fsyntax-only"