[llvm] r347050 - [IRVerifier] Allow StructRet in statepoint

Than McIntosh via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 16 06:28:05 PST 2018


Author: thanm
Date: Fri Nov 16 06:28:05 2018
New Revision: 347050

URL: http://llvm.org/viewvc/llvm-project?rev=347050&view=rev
Log:
[IRVerifier] Allow StructRet in statepoint

Summary:
StructRet attribute is not allowed in vararg calls. The statepoint
intrinsic is vararg, but the wrapped function may be not. Allow
calls of statepoint with StructRet arg, as long as the wrapped
function is not vararg.

Reviewers: thanm, anna

Reviewed By: anna

Subscribers: anna, llvm-commits

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

Modified:
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/test/Verifier/statepoint.ll

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=347050&r1=347049&r2=347050&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Fri Nov 16 06:28:05 2018
@@ -1930,6 +1930,7 @@ void Verifier::verifyStatepoint(Immutabl
 
   // Verify that the types of the call parameter arguments match
   // the type of the wrapped callee.
+  AttributeList Attrs = CS.getAttributes();
   for (int i = 0; i < NumParams; i++) {
     Type *ParamType = TargetFuncType->getParamType(i);
     Type *ArgType = CS.getArgument(5 + i)->getType();
@@ -1937,6 +1938,12 @@ void Verifier::verifyStatepoint(Immutabl
            "gc.statepoint call argument does not match wrapped "
            "function type",
            &CI);
+
+    if (TargetFuncType->isVarArg()) {
+      AttributeSet ArgAttrs = Attrs.getParamAttributes(5 + i);
+      Assert(!ArgAttrs.hasAttribute(Attribute::StructRet),
+             "Attribute 'sret' cannot be used for vararg call arguments!", &CI);
+    }
   }
 
   const int EndCallArgsInx = 4 + NumCallArgs;
@@ -2814,8 +2821,13 @@ void Verifier::verifyCallSite(CallSite C
         SawReturned = true;
       }
 
-      Assert(!ArgAttrs.hasAttribute(Attribute::StructRet),
-             "Attribute 'sret' cannot be used for vararg call arguments!", I);
+      // Statepoint intrinsic is vararg but the wrapped function may be not.
+      // Allow sret here and check the wrapped function in verifyStatepoint.
+      if (CS.getCalledFunction() == nullptr ||
+          CS.getCalledFunction()->getIntrinsicID() !=
+            Intrinsic::experimental_gc_statepoint)
+        Assert(!ArgAttrs.hasAttribute(Attribute::StructRet),
+               "Attribute 'sret' cannot be used for vararg call arguments!", I);
 
       if (ArgAttrs.hasAttribute(Attribute::InAlloca))
         Assert(Idx == CS.arg_size() - 1, "inalloca isn't on the last argument!",

Modified: llvm/trunk/test/Verifier/statepoint.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/statepoint.ll?rev=347050&r1=347049&r2=347050&view=diff
==============================================================================
--- llvm/trunk/test/Verifier/statepoint.ll (original)
+++ llvm/trunk/test/Verifier/statepoint.ll Fri Nov 16 06:28:05 2018
@@ -4,6 +4,7 @@ declare void @use(...)
 declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32)
 declare i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token, i32, i32)
 declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
+declare token @llvm.experimental.gc.statepoint.p0f_isVoidp0s_structsf(i64, i32, void (%struct*)*, i32, i32, ...)
 declare i32 @"personality_function"()
 
 ;; Basic usage
@@ -79,3 +80,20 @@ exceptional_return:
   %obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %landing_pad, i32 12, i32 12)
   ret i8 addrspace(1)* %obj1.relocated1
 }
+
+; Test for statepoint with sret attribute.
+; This should be allowed as long as the wrapped function is not vararg.
+%struct = type { i64, i64, i64 }
+
+declare void @fn_sret(%struct* sret)
+
+define void @test_sret() gc "statepoint-example" {
+  %x = alloca %struct
+  %statepoint_token = call token (i64, i32, void (%struct*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp0s_structsf(i64 0, i32 0, void (%struct*)* @fn_sret, i32 1, i32 0, %struct* sret %x, i32 0, i32 0)
+  ret void
+  ; CHECK-LABEL: test_sret
+  ; CHECK: alloca
+  ; CHECK: statepoint
+  ; CHECK-SAME: sret
+  ; CHECK: ret
+}




More information about the llvm-commits mailing list