]> granicus.if.org Git - clang/commitdiff
[CUDA][HIP] Check calling convention based on function target
authorYaxun Liu <Yaxun.Liu@amd.com>
Tue, 26 Feb 2019 22:24:49 +0000 (22:24 +0000)
committerYaxun Liu <Yaxun.Liu@amd.com>
Tue, 26 Feb 2019 22:24:49 +0000 (22:24 +0000)
MSVC header files using vectorcall to differentiate overloaded functions, which
causes failure for AMDGPU target. This is because clang does not check function
calling convention based on function target.

This patch checks calling convention using the proper target info.

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

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

lib/Sema/SemaDeclAttr.cpp
test/SemaCUDA/amdgpu-windows-vectorcall.cu [new file with mode: 0644]

index a0b4c53b1a7dfffbfed65b5636432ff2a63cc650..157c18a9e49492886ae83dc4d46771f106125095 100644 (file)
@@ -4615,8 +4615,36 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
   default: llvm_unreachable("unexpected attribute kind");
   }
 
+  TargetInfo::CallingConvCheckResult A = TargetInfo::CCCR_OK;
   const TargetInfo &TI = Context.getTargetInfo();
-  TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC);
+  auto *Aux = Context.getAuxTargetInfo();
+  if (LangOpts.CUDA) {
+    auto CudaTarget = IdentifyCUDATarget(FD);
+    bool CheckHost = false, CheckDevice = false;
+    switch (CudaTarget) {
+    case CFT_HostDevice:
+      CheckHost = true;
+      CheckDevice = true;
+      break;
+    case CFT_Host:
+      CheckHost = true;
+      break;
+    case CFT_Device:
+    case CFT_Global:
+      CheckDevice = true;
+      break;
+    case CFT_InvalidTarget:
+      llvm_unreachable("unexpected cuda target");
+    }
+    auto *HostTI = LangOpts.CUDAIsDevice ? Aux : &TI;
+    auto *DeviceTI = LangOpts.CUDAIsDevice ? &TI : Aux;
+    if (CheckHost && HostTI)
+      A = HostTI->checkCallingConvention(CC);
+    if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI)
+      A = DeviceTI->checkCallingConvention(CC);
+  } else {
+    A = TI.checkCallingConvention(CC);
+  }
   if (A != TargetInfo::CCCR_OK) {
     if (A == TargetInfo::CCCR_Warning)
       Diag(Attrs.getLoc(), diag::warn_cconv_ignored) << Attrs;
diff --git a/test/SemaCUDA/amdgpu-windows-vectorcall.cu b/test/SemaCUDA/amdgpu-windows-vectorcall.cu
new file mode 100644 (file)
index 0000000..7636572
--- /dev/null
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -aux-triple x86_64-pc-windows-msvc -fms-compatibility -fcuda-is-device -fsyntax-only -verify %s
+
+__cdecl void hostf1();
+__vectorcall void (*hostf2)() = hostf1; // expected-error {{cannot initialize a variable of type 'void ((*))() __attribute__((vectorcall))' with an lvalue of type 'void () __attribute__((cdecl))'}}