steven_wu updated this revision to Diff 121795.
steven_wu added a comment.

Add testcase for CUDA driver


https://reviews.llvm.org/D39502

Files:
  lib/Driver/Compilation.cpp
  test/Driver/cuda-bail-out.cu
  test/Driver/output-file-cleanup.c
  test/Driver/unix-conformance.c

Index: test/Driver/unix-conformance.c
===================================================================
--- /dev/null
+++ test/Driver/unix-conformance.c
@@ -0,0 +1,24 @@
+// Check UNIX conformance for cc/c89/c99
+// When c99 encounters a compilation error that causes an object file not to be
+// created, it shall write a diagnostic to standard error and continue to
+// compile other source code operands, but it shall not perform the link phase
+// and it shall return a non-zero exit status.
+
+// When given multiple .c files to compile, clang compiles them in order until
+// it hits an error, at which point it stops.
+//
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
+// RUN: cd %t-dir
+//
+// RUN: touch %t-dir/1.c
+// RUN: echo "invalid C code" > %t-dir/2.c
+// RUN: touch %t-dir/3.c
+// RUN: echo "invalid C code" > %t-dir/4.c
+// RUN: touch %t-dir/5.c
+// RUN: not %clang -S %t-dir/1.c %t-dir/2.c %t-dir/3.c %t-dir/4.c %t-dir/5.c
+// RUN: test -f %t-dir/1.s
+// RUN: test ! -f %t-dir/2.s
+// RUN: test -f %t-dir/3.s
+// RUN: test ! -f %t-dir/4.s
+// RUN: test -f %t-dir/5.s
Index: test/Driver/output-file-cleanup.c
===================================================================
--- test/Driver/output-file-cleanup.c
+++ test/Driver/output-file-cleanup.c
@@ -41,18 +41,3 @@
 // RUN: not %clang -S %t-dir/1.c %t-dir/2.c
 // RUN: test -f %t-dir/1.s
 // RUN: test ! -f %t-dir/2.s
-
-// When given multiple .c files to compile, clang compiles them in order until
-// it hits an error, at which point it stops.
-//
-// RUN: touch %t-dir/1.c
-// RUN: echo "invalid C code" > %t-dir/2.c
-// RUN: touch %t-dir/3.c
-// RUN: echo "invalid C code" > %t-dir/4.c
-// RUN: touch %t-dir/5.c
-// RUN: not %clang -S %t-dir/1.c %t-dir/2.c %t-dir/3.c %t-dir/4.c %t-dir/5.c
-// RUN: test -f %t-dir/1.s
-// RUN: test ! -f %t-dir/2.s
-// RUN: test ! -f %t-dir/3.s
-// RUN: test ! -f %t-dir/4.s
-// RUN: test ! -f %t-dir/5.s
Index: test/Driver/cuda-bail-out.cu
===================================================================
--- /dev/null
+++ test/Driver/cuda-bail-out.cu
@@ -0,0 +1,31 @@
+// Test cland driver bailed out after one error during CUDA compilation
+
+// REQUIRES: clang-driver
+// REQUIRES: powerpc-registered-target
+// REQUIRES: nvptx-registered-target
+
+# if __CUDA_ARCH__ == 350
+#error Error during compilation for sm_35
+#endif
+
+# if __CUDA_ARCH__ == 600
+#error Error during compilation for sm_60
+#endif
+
+#ifndef __CUDA_ARCH__
+#error Error during host compilation
+#endif
+
+
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -nocudalib -nocudainc \
+// RUN:   --cuda-gpu-arch=sm_35 %s 2>&1 | FileCheck %s
+
+// CHECK: Error during compilation for sm_35
+// CHECK-NOT: Error during host compilation
+
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -nocudalib -nocudainc \
+// RUN:   --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 %s 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-TWO-ARCHES %s
+// CHECK-TWO-ARCHES: Error during compilation for sm_35
+// CHECK-TWO-ARCHES-NOT: Error during compilation for sm_60
+// CHECK-TWO-ARCHES-NOT Error during host compilation
Index: lib/Driver/Compilation.cpp
===================================================================
--- lib/Driver/Compilation.cpp
+++ lib/Driver/Compilation.cpp
@@ -182,16 +182,51 @@
   return ExecutionFailed ? 1 : Res;
 }
 
-void Compilation::ExecuteJobs(
-    const JobList &Jobs,
-    SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const {
+using FailingCommandList = SmallVectorImpl<std::pair<int, const Command *>>;
+
+static bool ActionFailed(const Action *A,
+                         const FailingCommandList &FailingCommands) {
+
+  if (FailingCommands.empty())
+    return false;
+
+  // CUDA can have the same input source code compiled multiple times so do not
+  // compiled again if there are already failures. It is OK to abort the CUDA
+  // pipeline on errors.
+  if (A->isOffloading(Action::OFK_Cuda))
+    return true;
+
+  for (const auto &CI : FailingCommands)
+    if (A == &(CI.second->getSource()))
+      return true;
+
+  for (const Action *AI : A->inputs())
+    if (ActionFailed(AI, FailingCommands))
+      return true;
+
+  return false;
+}
+
+static bool InputsOk(const Command &C,
+                     const FailingCommandList &FailingCommands) {
+  return !ActionFailed(&C.getSource(), FailingCommands);
+}
+
+void Compilation::ExecuteJobs(const JobList &Jobs,
+                              FailingCommandList &FailingCommands) const {
+  // According to UNIX standard, driver need to continue compiling all the
+  // inputs on the command line even one of them failed.
+  // In all but CLMode, execute all the jobs unless the necessary inputs for the
+  // job is missing due to previous failures.
   for (const auto &Job : Jobs) {
+    if (!InputsOk(Job, FailingCommands))
+      continue;
     const Command *FailingCommand = nullptr;
     if (int Res = ExecuteCommand(Job, FailingCommand)) {
       FailingCommands.push_back(std::make_pair(Res, FailingCommand));
-      // Bail as soon as one command fails, so we don't output duplicate error
-      // messages if we die on e.g. the same file.
-      return;
+      // Bail as soon as one command fails in cl driver mode.
+      if (TheDriver.IsCLMode())
+        return;
     }
   }
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to