Преглед на файлове

Ignore device-side asm constraint errors while compiling CUDA code for host and vice versa.

Differential Revision: http://reviews.llvm.org/D8392

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@232747 91177308-0d34-0410-b5e6-96231b3b80d8
Artem Belevich преди 10 години
родител
ревизия
c9b35c96b9
променени са 3 файла, в които са добавени 55 реда и са изтрити 3 реда
  1. 16 3
      lib/Sema/SemaStmtAsm.cpp
  2. 24 0
      test/SemaCUDA/asm-constraints-device.cu
  3. 15 0
      test/SemaCUDA/asm-constraints-mixed.cu

+ 16 - 3
lib/Sema/SemaStmtAsm.cpp

@@ -124,6 +124,17 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
   // The parser verifies that there is a string literal here.
   // The parser verifies that there is a string literal here.
   assert(AsmString->isAscii());
   assert(AsmString->isAscii());
 
 
+  bool ValidateConstraints = true;
+  if (getLangOpts().CUDA) {
+    // In CUDA mode don't verify asm constraints in device functions during host
+    // compilation and vice versa.
+    bool InDeviceMode = getLangOpts().CUDAIsDevice;
+    FunctionDecl *FD = getCurFunctionDecl();
+    bool IsDeviceFunction =
+        FD && (FD->hasAttr<CUDADeviceAttr>() || FD->hasAttr<CUDAGlobalAttr>());
+    ValidateConstraints = IsDeviceFunction == InDeviceMode;
+  }
+
   for (unsigned i = 0; i != NumOutputs; i++) {
   for (unsigned i = 0; i != NumOutputs; i++) {
     StringLiteral *Literal = Constraints[i];
     StringLiteral *Literal = Constraints[i];
     assert(Literal->isAscii());
     assert(Literal->isAscii());
@@ -133,7 +144,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
       OutputName = Names[i]->getName();
       OutputName = Names[i]->getName();
 
 
     TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
     TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
-    if (!Context.getTargetInfo().validateOutputConstraint(Info))
+    if (ValidateConstraints &&
+        !Context.getTargetInfo().validateOutputConstraint(Info))
       return StmtError(Diag(Literal->getLocStart(),
       return StmtError(Diag(Literal->getLocStart(),
                             diag::err_asm_invalid_output_constraint)
                             diag::err_asm_invalid_output_constraint)
                        << Info.getConstraintStr());
                        << Info.getConstraintStr());
@@ -207,8 +219,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
       InputName = Names[i]->getName();
       InputName = Names[i]->getName();
 
 
     TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
     TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
-    if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos.data(),
-                                                NumOutputs, Info)) {
+    if (ValidateConstraints &&
+        !Context.getTargetInfo().validateInputConstraint(
+            OutputConstraintInfos.data(), NumOutputs, Info)) {
       return StmtError(Diag(Literal->getLocStart(),
       return StmtError(Diag(Literal->getLocStart(),
                             diag::err_asm_invalid_input_constraint)
                             diag::err_asm_invalid_input_constraint)
                        << Info.getConstraintStr());
                        << Info.getConstraintStr());

+ 24 - 0
test/SemaCUDA/asm-constraints-device.cu

@@ -0,0 +1,24 @@
+// Verify that we do check for constraints in device-side inline
+// assembly. Passing an illegal input/output constraint and look 
+// for corresponding error
+// RUN: %clang_cc1 -triple nvptx-unknown-cuda -fsyntax-only -fcuda-is-device -verify %s
+
+__attribute__((device)) void df() {
+  short h;
+  int a;
+  // asm with PTX constraints. Some of them are PTX-specific.
+  __asm__("output constraints"
+          : "=h"(h), // .u16 reg, OK
+            "=a"(a)  // expected-error {{invalid output constraint '=a' in asm}}
+          :          // None
+          );
+  __asm__("input constraints"
+          :           // None
+          : "f"(0.0), // .f32 reg, OK
+            "d"(0.0), // .f64 reg, OK
+            "h"(0),   // .u16 reg, OK
+            "r"(0),   // .u32 reg, OK
+            "l"(0),   // .u64 reg, OK
+            "a"(0)    // expected-error {{invalid input constraint 'a' in asm}}
+          );
+}

+ 15 - 0
test/SemaCUDA/asm-constraints-mixed.cu

@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple nvptx-unknown-cuda -fsyntax-only -fcuda-is-device -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+__attribute__((device)) void df() {
+  short h;
+  // asm with PTX constraints. Some of them are PTX-specific.
+  __asm__("dont care" : "=h"(h): "f"(0.0), "d"(0.0), "h"(0), "r"(0), "l"(0));
+}
+
+void hf() {
+  int a;
+  // Asm with x86 constraints that are not supported by PTX.
+  __asm__("dont care" : "=a"(a): "a"(0), "b"(0), "c"(0));
+}