]> granicus.if.org Git - clang/commitdiff
[CUDA] Check register names on appropriate side of cuda compilation only.
authorArtem Belevich <tra@google.com>
Thu, 27 Aug 2015 19:54:21 +0000 (19:54 +0000)
committerArtem Belevich <tra@google.com>
Thu, 27 Aug 2015 19:54:21 +0000 (19:54 +0000)
Differential Revision: http://reviews.llvm.org/D11950

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@246193 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaStmtAsm.cpp
test/SemaCUDA/asm-constraints-mixed.cu

index a91980c9f5638cdad9ab57b0f1d529fcaaaefae8..c94d2dd5a9e6ba0cc7740cc4386238e0038d86fe 100644 (file)
@@ -5998,7 +5998,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
         break;
       case SC_Register:
         // Local Named register
-        if (!Context.getTargetInfo().isValidGCCRegisterName(Label))
+        if (!Context.getTargetInfo().isValidGCCRegisterName(Label) &&
+            DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl()))
           Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
         break;
       case SC_Static:
@@ -6009,7 +6010,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
       }
     } else if (SC == SC_Register) {
       // Global Named register
-      if (!Context.getTargetInfo().isValidGCCRegisterName(Label))
+      if (!Context.getTargetInfo().isValidGCCRegisterName(Label) &&
+          DeclAttrsMatchCUDAMode(getLangOpts(), NewVD))
         Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
       if (!R->isIntegralType(Context) && !R->isPointerType()) {
         Diag(D.getLocStart(), diag::err_asm_bad_register_type);
index 52987cc13164ffe2a90255d62a2f5619723650d7..9f944abb49aca74bd3d12249b368009b476bd10b 100644 (file)
@@ -155,8 +155,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
   // The parser verifies that there is a string literal here.
   assert(AsmString->isAscii());
 
-  bool ValidateConstraints =
-      DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl());
+  // If we're compiling CUDA file and function attributes indicate that it's not
+  // for this compilation side, skip all the checks.
+  if (!DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl())) {
+    GCCAsmStmt *NS = new (Context) GCCAsmStmt(
+        Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
+        Constraints, Exprs.data(), AsmString, NumClobbers, Clobbers, RParenLoc);
+    return NS;
+  }
 
   for (unsigned i = 0; i != NumOutputs; i++) {
     StringLiteral *Literal = Constraints[i];
@@ -167,8 +173,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
       OutputName = Names[i]->getName();
 
     TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
-    if (ValidateConstraints &&
-        !Context.getTargetInfo().validateOutputConstraint(Info))
+    if (!Context.getTargetInfo().validateOutputConstraint(Info))
       return StmtError(Diag(Literal->getLocStart(),
                             diag::err_asm_invalid_output_constraint)
                        << Info.getConstraintStr());
@@ -247,8 +252,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
       InputName = Names[i]->getName();
 
     TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
-    if (ValidateConstraints &&
-        !Context.getTargetInfo().validateInputConstraint(
+    if (!Context.getTargetInfo().validateInputConstraint(
             OutputConstraintInfos.data(), NumOutputs, Info)) {
       return StmtError(Diag(Literal->getLocStart(),
                             diag::err_asm_invalid_input_constraint)
index a4ac9c65c99f8be636e5d6e2d54fea0c6e7cf126..ebf44243d9d68b3047cb3251a8dbe5ae4c4c6821 100644 (file)
@@ -1,15 +1,39 @@
+// REQUIRES: x86-registered-target
+// REQUIRES: nvptx-registered-target
 // 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)) register long global_dev_reg asm("r0");
+__attribute__((device)) register long
+    global_dev_hreg asm("rax"); // device-side error
+
+register long global_host_reg asm("rax");
+register long global_host_dreg asm("r0"); // host-side error
 
 __attribute__((device)) void df() {
+  register long local_dev_reg asm("r0");
+  register long local_host_reg asm("rax"); // device-side error
   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));
+  __asm__("dont care" : "=h"(h) : "f"(0.0), "d"(0.0), "h"(0), "r"(0), "l"(0));
 }
 
 void hf() {
+  register long local_dev_reg asm("r0"); // host-side error
+  register long local_host_reg asm("rax");
   int a;
-  // Asm with x86 constraints that are not supported by PTX.
-  __asm__("dont care" : "=a"(a): "a"(0), "b"(0), "c"(0));
+  // Asm with x86 constraints and registers that are not supported by PTX.
+  __asm__("dont care" : "=a"(a) : "a"(0), "b"(0), "c"(0) : "flags");
 }
+
+// Check errors in named register variables.
+// We should only see errors relevant to current compilation mode.
+#if defined(__CUDA_ARCH__)
+// Device-side compilation:
+// expected-error@8 {{unknown register name 'rax' in asm}}
+// expected-error@15 {{unknown register name 'rax' in asm}}
+#else
+// Host-side compilation:
+// expected-error@11 {{unknown register name 'r0' in asm}}
+// expected-error@22 {{unknown register name 'r0' in asm}}
+#endif