[PATCH] D53602: [IRVerifier] Allow StructRet in statepoint

Than McIntosh via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 16 06:30:46 PST 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rL347050: [IRVerifier] Allow StructRet in statepoint (authored by thanm, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D53602?vs=170732&id=174364#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D53602

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


Index: llvm/trunk/lib/IR/Verifier.cpp
===================================================================
--- llvm/trunk/lib/IR/Verifier.cpp
+++ llvm/trunk/lib/IR/Verifier.cpp
@@ -1930,13 +1930,20 @@
 
   // 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();
     Assert(ArgType == ParamType,
            "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 @@
         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!",
Index: llvm/trunk/test/Verifier/statepoint.ll
===================================================================
--- llvm/trunk/test/Verifier/statepoint.ll
+++ llvm/trunk/test/Verifier/statepoint.ll
@@ -4,6 +4,7 @@
 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 @@
   %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
+}


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D53602.174364.patch
Type: text/x-patch
Size: 3197 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181116/8a0b41be/attachment.bin>


More information about the llvm-commits mailing list