]> granicus.if.org Git - llvm/commitdiff
Verifier: Check some amdgpu calling convention restrictions
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 4 Apr 2017 18:43:11 +0000 (18:43 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 4 Apr 2017 18:43:11 +0000 (18:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299457 91177308-0d34-0410-b5e6-96231b3b80d8

lib/IR/Verifier.cpp
test/CodeGen/AMDGPU/early-inline.ll
test/Verifier/amdgpu-cc.ll [new file with mode: 0644]

index 4efb7a693b345280677773581a3bf7d8bea26fc0..72e2ed3988b30aa883f57a9dab673fea9fb6b19c 100644 (file)
@@ -2006,6 +2006,18 @@ void Verifier::visitFunction(const Function &F) {
   default:
   case CallingConv::C:
     break;
+  case CallingConv::AMDGPU_KERNEL:
+  case CallingConv::SPIR_KERNEL:
+    Assert(F.getReturnType()->isVoidTy(),
+           "Calling convention requires void return type", &F);
+    LLVM_FALLTHROUGH;
+  case CallingConv::AMDGPU_VS:
+  case CallingConv::AMDGPU_GS:
+  case CallingConv::AMDGPU_PS:
+  case CallingConv::AMDGPU_CS:
+    Assert(!F.hasStructRetAttr(),
+           "Calling convention does not allow sret", &F);
+    LLVM_FALLTHROUGH;
   case CallingConv::Fast:
   case CallingConv::Cold:
   case CallingConv::Intel_OCL_BI:
index db397d9e11b609edfd91c6b78dcdd9138f44a191..c871d54bec7ed623c1c6ab3730da85c5d9c8bc72 100644 (file)
@@ -17,8 +17,9 @@ entry:
 ; CHECK: mul i32
 ; CHECK-NOT: call i32
 
-define amdgpu_kernel i32 @caller(i32 %x) {
+define amdgpu_kernel void @caller(i32 %x) {
 entry:
   %res = call i32 @callee(i32 %x)
-  ret i32 %res
+  store volatile i32 %res, i32 addrspace(1)* undef
+  ret void
 }
diff --git a/test/Verifier/amdgpu-cc.ll b/test/Verifier/amdgpu-cc.ll
new file mode 100644 (file)
index 0000000..68c7f30
--- /dev/null
@@ -0,0 +1,55 @@
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+
+; CHECK: Calling convention requires void return type
+; CHECK-NEXT: i32 ()* @nonvoid_cc_amdgpu_kernel
+define amdgpu_kernel i32 @nonvoid_cc_amdgpu_kernel() {
+  ret i32 0
+}
+
+; CHECK: Calling convention does not support varargs or perfect forwarding!
+; CHECK-NEXT: void (...)* @varargs_amdgpu_kernel
+define amdgpu_kernel void @varargs_amdgpu_kernel(...) {
+  ret void
+}
+
+; CHECK: Calling convention does not allow sret
+; CHECK-NEXT: void (i32*)* @sret_cc_amdgpu_kernel
+define amdgpu_kernel void @sret_cc_amdgpu_kernel(i32* sret %ptr) {
+  ret void
+}
+
+; CHECK: Calling convention does not support varargs or perfect forwarding!
+; CHECK-NEXT: void (...)* @varargs_amdgpu_vs
+define amdgpu_vs void @varargs_amdgpu_vs(...) {
+  ret void
+}
+
+; CHECK: Calling convention does not support varargs or perfect forwarding!
+; CHECK-NEXT: void (...)* @varargs_amdgpu_gs
+define amdgpu_gs void @varargs_amdgpu_gs(...) {
+  ret void
+}
+
+; CHECK: Calling convention does not support varargs or perfect forwarding!
+; CHECK-NEXT: void (...)* @varargs_amdgpu_ps
+define amdgpu_ps void @varargs_amdgpu_ps(...) {
+  ret void
+}
+
+; CHECK: Calling convention does not support varargs or perfect forwarding!
+; CHECK-NEXT: void (...)* @varargs_amdgpu_cs
+define amdgpu_cs void @varargs_amdgpu_cs(...) {
+  ret void
+}
+
+; CHECK: Calling convention requires void return type
+; CHECK-NEXT: i32 ()* @nonvoid_cc_spir_kernel
+define spir_kernel i32 @nonvoid_cc_spir_kernel() {
+  ret i32 0
+}
+
+; CHECK: Calling convention does not support varargs or perfect forwarding!
+; CHECK-NEXT: void (...)* @varargs_spir_kernel
+define spir_kernel void @varargs_spir_kernel(...) {
+  ret void
+}