Index: lib/Transforms/Scalar/PlaceSafepoints.cpp =================================================================== --- lib/Transforms/Scalar/PlaceSafepoints.cpp +++ lib/Transforms/Scalar/PlaceSafepoints.cpp @@ -738,7 +738,8 @@ // different type inserted previously Function *F = dyn_cast(M->getOrInsertFunction("gc.safepoint_poll", ftype)); - assert(F && !F->empty() && "definition must exist"); + assert(F && "void @gc.safepoint_poll() must be defined"); + assert(!F->empty() && "gc.safepoint_poll must be a non-empty function"); CallInst *poll = CallInst::Create(F, "", term); // Record some information about the call site we're replacing @@ -861,7 +862,7 @@ IRBuilder<> Builder(insertBefore); // First, create the statepoint (with all live ptrs as arguments). std::vector args; - // target, #args, unused, args + // target, #call args, unused, call parameters, #deopt args, deopt parameters Value *Target = CS.getCalledValue(); args.push_back(Target); int callArgSize = CS.arg_size(); @@ -869,6 +870,8 @@ ConstantInt::get(Type::getInt32Ty(M->getContext()), callArgSize)); // TODO: add a 'Needs GC-rewrite' later flag args.push_back(ConstantInt::get(Type::getInt32Ty(M->getContext()), 0)); + // deopt: unused + args.push_back(ConstantInt::get(Type::getInt32Ty(M->getContext()), 0)); // Copy all the arguments of the original call args.insert(args.end(), CS.arg_begin(), CS.arg_end()); Index: test/Transforms/Safepoint/place.ll =================================================================== --- /dev/null +++ test/Transforms/Safepoint/place.ll @@ -0,0 +1,17 @@ +; RUN: opt %s -place-safepoints -S | FileCheck %s + +declare zeroext i1 @return_i1() + +define void @gc.safepoint_poll() { + ret void +} + +define i1 @test_basic() gc "statepoint-example" { +; CHECK-LABEL: test_basic +; This is just checking that a statepoint is inserted +; CHECK: gc.statepoint.p0f_isVoidf +; CHECK: gc.statepoint.p0f_i1f +entry: + %call1 = tail call i1 ()* @return_i1() + ret i1 %call1 +}