[llvm] r226599 - [GC] Verify-pass void vararg functions in gc.statepoint

Ramkumar Ramachandra artagnon at gmail.com
Tue Jan 20 11:42:46 PST 2015


Author: artagnon
Date: Tue Jan 20 13:42:46 2015
New Revision: 226599

URL: http://llvm.org/viewvc/llvm-project?rev=226599&view=rev
Log:
[GC] Verify-pass void vararg functions in gc.statepoint

With the appropriate Verifier changes, exactracting the result out of a
statepoint wrapping a vararg function crashes. However, a void vararg
function works fine: commit this first step.

Differential Revision: http://reviews.llvm.org/D7071

Modified:
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/test/CodeGen/X86/statepoint-call-lowering.ll

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=226599&r1=226598&r2=226599&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Tue Jan 20 13:42:46 2015
@@ -2639,8 +2639,6 @@ void Verifier::visitIntrinsicFunctionCal
             "gc.statepoint callee must be of function pointer type",
             &CI, Target);
     FunctionType *TargetFuncType = cast<FunctionType>(PT->getElementType());
-    Assert1(!TargetFuncType->isVarArg(),
-            "gc.statepoint support for var arg functions not implemented", &CI);
 
     const Value *NumCallArgsV = CI.getArgOperand(1);
     Assert1(isa<ConstantInt>(NumCallArgsV),
@@ -2650,8 +2648,18 @@ void Verifier::visitIntrinsicFunctionCal
     Assert1(NumCallArgs >= 0,
             "gc.statepoint number of arguments to underlying call "
             "must be positive", &CI);
-    Assert1(NumCallArgs == (int)TargetFuncType->getNumParams(),
-            "gc.statepoint mismatch in number of call args", &CI);
+    const int NumParams = (int)TargetFuncType->getNumParams();
+    if (TargetFuncType->isVarArg()) {
+      Assert1(NumCallArgs >= NumParams,
+              "gc.statepoint mismatch in number of vararg call args", &CI);
+
+      // TODO: Remove this limitation
+      Assert1(TargetFuncType->getReturnType()->isVoidTy(),
+              "gc.statepoint doesn't support wrapping non-void "
+              "vararg functions yet", &CI);
+    } else
+      Assert1(NumCallArgs == NumParams,
+              "gc.statepoint mismatch in number of call args", &CI);
 
     const Value *Unused = CI.getArgOperand(2);
     Assert1(isa<ConstantInt>(Unused) &&
@@ -2660,7 +2668,7 @@ void Verifier::visitIntrinsicFunctionCal
 
     // Verify that the types of the call parameter arguments match
     // the type of the wrapped callee.
-    for (int i = 0; i < NumCallArgs; i++) {
+    for (int i = 0; i < NumParams; i++) {
       Type *ParamType = TargetFuncType->getParamType(i);
       Type *ArgType = CI.getArgOperand(3+i)->getType();
       Assert1(ArgType == ParamType,

Modified: llvm/trunk/test/CodeGen/X86/statepoint-call-lowering.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/statepoint-call-lowering.ll?rev=226599&r1=226598&r2=226599&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/statepoint-call-lowering.ll (original)
+++ llvm/trunk/test/CodeGen/X86/statepoint-call-lowering.ll Tue Jan 20 13:42:46 2015
@@ -9,6 +9,7 @@ declare zeroext i1 @return_i1()
 declare zeroext i32 @return_i32()
 declare i32* @return_i32ptr()
 declare float @return_float()
+declare void @varargf(i32, ...)
 
 define i1 @test_i1_return() gc "statepoint-example" {
 ; CHECK-LABEL: test_i1_return
@@ -75,6 +76,17 @@ entry:
   ret i1 %call2
 }
 
+define void @test_void_vararg() gc "statepoint-example" {
+; CHECK-LABEL: test_void_vararg
+; Check a statepoint wrapping a *void* returning vararg function works
+; CHECK: callq varargf
+entry:
+  %safepoint_token = tail call i32 (void (i32, ...)*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)* @varargf, i32 2, i32 0, i32 42, i32 43, i32 0)
+  ;; if we try to use the result from a statepoint wrapping a
+  ;; non-void-returning varargf, we will experience a crash.
+  ret void
+}
+
 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
 declare i1 @llvm.experimental.gc.result.int.i1(i32)
 
@@ -87,4 +99,6 @@ declare i32* @llvm.experimental.gc.resul
 declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(float ()*, i32, i32, ...)
 declare float @llvm.experimental.gc.result.float.f32(i32)
 
+declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)*, i32, i32, ...)
+
 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)





More information about the llvm-commits mailing list