Index: llvm/include/llvm/IR/IRBuilder.h =================================================================== --- llvm/include/llvm/IR/IRBuilder.h +++ llvm/include/llvm/IR/IRBuilder.h @@ -789,7 +789,7 @@ CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, ArrayRef CallArgs, - ArrayRef DeoptArgs, + Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); @@ -798,8 +798,8 @@ CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags, ArrayRef CallArgs, - ArrayRef TransitionArgs, - ArrayRef DeoptArgs, + Optional> TransitionArgs, + Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); @@ -808,7 +808,7 @@ /// .get()'ed to get the Value pointer. CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, ArrayRef CallArgs, - ArrayRef DeoptArgs, + Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); @@ -818,7 +818,7 @@ CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef InvokeArgs, - ArrayRef DeoptArgs, + Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); /// Create an invoke to the experimental.gc.statepoint intrinsic to @@ -826,8 +826,8 @@ InvokeInst *CreateGCStatepointInvoke( uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags, - ArrayRef InvokeArgs, ArrayRef TransitionArgs, - ArrayRef DeoptArgs, ArrayRef GCArgs, + ArrayRef InvokeArgs, Optional> TransitionArgs, + Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); // Convenience function for the common case when CallArgs are filled in using @@ -837,7 +837,7 @@ CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef InvokeArgs, - ArrayRef DeoptArgs, + Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); /// Create a call to the experimental.gc.result intrinsic to extract Index: llvm/lib/IR/IRBuilder.cpp =================================================================== --- llvm/lib/IR/IRBuilder.cpp +++ llvm/lib/IR/IRBuilder.cpp @@ -575,12 +575,11 @@ return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, OverloadedTypes); } -template +template static std::vector getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags, ArrayRef CallArgs, - ArrayRef TransitionArgs, ArrayRef DeoptArgs, - ArrayRef GCArgs) { + ArrayRef GCArgs) { std::vector Args; Args.push_back(B.getInt64(ID)); Args.push_back(B.getInt32(NumPatchBytes)); @@ -588,20 +587,40 @@ Args.push_back(B.getInt32(CallArgs.size())); Args.push_back(B.getInt32(Flags)); Args.insert(Args.end(), CallArgs.begin(), CallArgs.end()); - Args.push_back(B.getInt32(TransitionArgs.size())); - Args.insert(Args.end(), TransitionArgs.begin(), TransitionArgs.end()); - Args.push_back(B.getInt32(DeoptArgs.size())); - Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end()); + // GC Transition and Deopt args are now always handled via operand bundle. + // They will be removed from the signature of gc.statepoint shortly. + Args.push_back(B.getInt32(0)); + Args.push_back(B.getInt32(0)); Args.insert(Args.end(), GCArgs.begin(), GCArgs.end()); return Args; } +template +static std::vector +getStatepointBundles(Optional> TransitionArgs, + Optional> DeoptArgs) { + std::vector Rval; + if (DeoptArgs) { + SmallVector DeoptValues; + DeoptValues.insert(DeoptValues.end(), DeoptArgs->begin(), DeoptArgs->end()); + Rval.emplace_back("deopt", DeoptValues); + } + if (TransitionArgs) { + SmallVector TransitionValues; + TransitionValues.insert(TransitionValues.end(), + TransitionArgs->begin(), TransitionArgs->end()); + Rval.emplace_back("gc-transition", TransitionValues); + } + return Rval; +} + template static CallInst *CreateGCStatepointCallCommon( IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags, ArrayRef CallArgs, - ArrayRef TransitionArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, + Optional> TransitionArgs, + Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name) { // Extract out the type of the callee. auto *FuncPtrType = cast(ActualCallee->getType()); @@ -617,13 +636,16 @@ std::vector Args = getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags, - CallArgs, TransitionArgs, DeoptArgs, GCArgs); - return createCallHelper(FnStatepoint, Args, Builder, Name); + CallArgs, GCArgs); + + return Builder->CreateCall(FnStatepoint, Args, + getStatepointBundles(TransitionArgs, DeoptArgs), + Name); } CallInst *IRBuilderBase::CreateGCStatepointCall( uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, - ArrayRef CallArgs, ArrayRef DeoptArgs, + ArrayRef CallArgs, Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name) { return CreateGCStatepointCallCommon( this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None), @@ -632,8 +654,9 @@ CallInst *IRBuilderBase::CreateGCStatepointCall( uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags, - ArrayRef CallArgs, ArrayRef TransitionArgs, - ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { + ArrayRef CallArgs, Optional> TransitionArgs, + Optional> DeoptArgs, ArrayRef GCArgs, + const Twine &Name) { return CreateGCStatepointCallCommon( this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs, DeoptArgs, GCArgs, Name); @@ -641,7 +664,7 @@ CallInst *IRBuilderBase::CreateGCStatepointCall( uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, - ArrayRef CallArgs, ArrayRef DeoptArgs, + ArrayRef CallArgs, Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name) { return CreateGCStatepointCallCommon( this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None), @@ -652,8 +675,9 @@ static InvokeInst *CreateGCStatepointInvokeCommon( IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, - uint32_t Flags, ArrayRef InvokeArgs, ArrayRef TransitionArgs, - ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { + uint32_t Flags, ArrayRef InvokeArgs, + Optional> TransitionArgs, Optional> DeoptArgs, + ArrayRef GCArgs, const Twine &Name) { // Extract out the type of the callee. auto *FuncPtrType = cast(ActualInvokee->getType()); assert(isa(FuncPtrType->getElementType()) && @@ -666,15 +690,17 @@ std::vector Args = getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags, - InvokeArgs, TransitionArgs, DeoptArgs, GCArgs); + InvokeArgs, GCArgs); + return Builder->CreateInvoke(FnStatepoint, NormalDest, UnwindDest, Args, + getStatepointBundles(TransitionArgs, DeoptArgs), Name); } InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, - ArrayRef InvokeArgs, ArrayRef DeoptArgs, + ArrayRef InvokeArgs, Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name) { return CreateGCStatepointInvokeCommon( this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, @@ -685,8 +711,8 @@ InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags, - ArrayRef InvokeArgs, ArrayRef TransitionArgs, - ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { + ArrayRef InvokeArgs, Optional> TransitionArgs, + Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name) { return CreateGCStatepointInvokeCommon( this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags, InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name); @@ -695,7 +721,7 @@ InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef InvokeArgs, - ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { + Optional> DeoptArgs, ArrayRef GCArgs, const Twine &Name) { return CreateGCStatepointInvokeCommon( this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs, Index: llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp =================================================================== --- llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -1490,12 +1490,14 @@ uint32_t Flags = uint32_t(StatepointFlags::None); ArrayRef CallArgs(Call->arg_begin(), Call->arg_end()); - ArrayRef DeoptArgs = GetDeoptBundleOperands(Call); - ArrayRef TransitionArgs; - if (auto TransitionBundle = - Call->getOperandBundle(LLVMContext::OB_gc_transition)) { + Optional> DeoptArgs; + if (auto Bundle = Call->getOperandBundle(LLVMContext::OB_deopt)) + DeoptArgs = Bundle->Inputs; + Optional> TransitionArgs; + if (auto Bundle = Call->getOperandBundle(LLVMContext::OB_gc_transition)) { + TransitionArgs = Bundle->Inputs; + // TODO: This flag no longer serves a purpose and can be removed later Flags |= uint32_t(StatepointFlags::GCTransition); - TransitionArgs = TransitionBundle->Inputs; } // Instead of lowering calls to @llvm.experimental.deoptimize as normal calls Index: llvm/test/Transforms/RewriteStatepointsForGC/base-pointers-4.ll =================================================================== --- llvm/test/Transforms/RewriteStatepointsForGC/base-pointers-4.ll +++ llvm/test/Transforms/RewriteStatepointsForGC/base-pointers-4.ll @@ -15,7 +15,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, i64 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* ()* @generate_obj, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0) +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, i64 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* ()* @generate_obj, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] ; CHECK-NEXT: [[TMP0:%.*]] = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(token [[STATEPOINT_TOKEN]]) ; CHECK-NEXT: switch i32 [[CONDITION:%.*]], label [[DEST_A:%.*]] [ ; CHECK-NEXT: i32 0, label [[DEST_B:%.*]] @@ -30,14 +30,14 @@ ; CHECK: merge: ; CHECK-NEXT: [[OBJ_TO_CONSUME_BASE:%.*]] = phi i64 addrspace(1)* [ [[TMP0]], [[DEST_A]] ], [ null, [[DEST_B]] ], [ null, [[DEST_C]] ], !is_base_value !0 ; CHECK-NEXT: [[OBJ_TO_CONSUME:%.*]] = phi i64 addrspace(1)* [ [[TMP0]], [[DEST_A]] ], [ null, [[DEST_B]] ], [ null, [[DEST_C]] ] -; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 2882400000, i32 0, void (i64 addrspace(1)*)* @consume_obj, i32 1, i32 0, i64 addrspace(1)* [[OBJ_TO_CONSUME]], i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i64 addrspace(1)* [[OBJ_TO_CONSUME_BASE]], i64 addrspace(1)* [[OBJ_TO_CONSUME]]) -; CHECK-NEXT: [[OBJ_TO_CONSUME_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 13, i32 13) +; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 2882400000, i32 0, void (i64 addrspace(1)*)* @consume_obj, i32 1, i32 0, i64 addrspace(1)* [[OBJ_TO_CONSUME]], i32 0, i32 0, i64 addrspace(1)* [[OBJ_TO_CONSUME_BASE]], i64 addrspace(1)* [[OBJ_TO_CONSUME]]) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] +; CHECK-NEXT: [[OBJ_TO_CONSUME_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 8, i32 8) ; CHECK-NEXT: [[OBJ_TO_CONSUME_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_TO_CONSUME_BASE_RELOCATED]] to i64 addrspace(1)* -; CHECK-NEXT: [[OBJ_TO_CONSUME_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 13, i32 14) +; CHECK-NEXT: [[OBJ_TO_CONSUME_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 8, i32 9) ; CHECK-NEXT: [[OBJ_TO_CONSUME_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_TO_CONSUME_RELOCATED]] to i64 addrspace(1)* ; CHECK-NEXT: br label [[MERGE_SPLIT:%.*]] ; CHECK: merge.split: -; CHECK-NEXT: [[STATEPOINT_TOKEN2:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0) +; CHECK-NEXT: [[STATEPOINT_TOKEN2:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] ; CHECK-NEXT: br label [[LOOP]] ; entry: Index: llvm/test/Transforms/RewriteStatepointsForGC/basic.ll =================================================================== --- llvm/test/Transforms/RewriteStatepointsForGC/basic.ll +++ llvm/test/Transforms/RewriteStatepointsForGC/basic.ll @@ -8,8 +8,8 @@ define i32 addrspace(1)* @f0(i32 addrspace(1)* %arg) gc "statepoint-example" { ; CHECK-LABEL: @f0( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @g, i32 0, i32 0, i32 0, i32 1, i32 100, i32 addrspace(1)* [[ARG:%.*]]) -; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 8, i32 8) +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @g, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* [[ARG:%.*]]) [ "deopt"(i32 100) ] +; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 7, i32 7) ; CHECK-NEXT: [[ARG_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED]] to i32 addrspace(1)* ; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED_CASTED]] ; @@ -22,16 +22,16 @@ define i32 addrspace(1)* @f1(i32 addrspace(1)* %arg) gc "statepoint-example" personality i32 8 { ; CHECK-LABEL: @f1( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @g, i32 0, i32 0, i32 0, i32 1, i32 100, i32 addrspace(1)* [[ARG:%.*]]) +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @g, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* [[ARG:%.*]]) [ "deopt"(i32 100) ] ; CHECK-NEXT: to label [[NORMAL_DEST:%.*]] unwind label [[UNWIND_DEST:%.*]] ; CHECK: normal_dest: -; CHECK-NEXT: [[ARG_RELOCATED1:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 8, i32 8) +; CHECK-NEXT: [[ARG_RELOCATED1:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 7, i32 7) ; CHECK-NEXT: [[ARG_RELOCATED1_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED1]] to i32 addrspace(1)* ; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED1_CASTED]] ; CHECK: unwind_dest: ; CHECK-NEXT: [[LPAD:%.*]] = landingpad token ; CHECK-NEXT: cleanup -; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[LPAD]], i32 8, i32 8) +; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[LPAD]], i32 7, i32 7) ; CHECK-NEXT: [[ARG_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED]] to i32 addrspace(1)* ; CHECK-NEXT: resume token undef ; @@ -49,9 +49,9 @@ define i32 addrspace(1)* @f2(i32 addrspace(1)* %arg) gc "statepoint-example" { ; CHECK-LABEL: @f2( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 2882400000, i32 0, i32 ()* @h, i32 0, i32 0, i32 0, i32 1, i32 100, i32 addrspace(1)* [[ARG:%.*]]) +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 2882400000, i32 0, i32 ()* @h, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* [[ARG:%.*]]) [ "deopt"(i32 100) ] ; CHECK-NEXT: [[VAL1:%.*]] = call i32 @llvm.experimental.gc.result.i32(token [[STATEPOINT_TOKEN]]) -; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 8, i32 8) +; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 7, i32 7) ; CHECK-NEXT: [[ARG_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED]] to i32 addrspace(1)* ; CHECK-NEXT: store i32 [[VAL1]], i32 addrspace(1)* [[ARG_RELOCATED_CASTED]], align 4 ; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED_CASTED]] @@ -67,18 +67,18 @@ define i32 addrspace(1)* @f3(i32 addrspace(1)* %arg) gc "statepoint-example" personality i32 8 { ; CHECK-LABEL: @f3( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 2882400000, i32 0, i32 ()* @h, i32 0, i32 0, i32 0, i32 1, i32 100, i32 addrspace(1)* [[ARG:%.*]]) +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 2882400000, i32 0, i32 ()* @h, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* [[ARG:%.*]]) [ "deopt"(i32 100) ] ; CHECK-NEXT: to label [[NORMAL_DEST:%.*]] unwind label [[UNWIND_DEST:%.*]] ; CHECK: normal_dest: ; CHECK-NEXT: [[VAL1:%.*]] = call i32 @llvm.experimental.gc.result.i32(token [[STATEPOINT_TOKEN]]) -; CHECK-NEXT: [[ARG_RELOCATED2:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 8, i32 8) +; CHECK-NEXT: [[ARG_RELOCATED2:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 7, i32 7) ; CHECK-NEXT: [[ARG_RELOCATED2_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED2]] to i32 addrspace(1)* ; CHECK-NEXT: store i32 [[VAL1]], i32 addrspace(1)* [[ARG_RELOCATED2_CASTED]], align 4 ; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED2_CASTED]] ; CHECK: unwind_dest: ; CHECK-NEXT: [[LPAD:%.*]] = landingpad token ; CHECK-NEXT: cleanup -; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[LPAD]], i32 8, i32 8) +; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[LPAD]], i32 7, i32 7) ; CHECK-NEXT: [[ARG_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED]] to i32 addrspace(1)* ; CHECK-NEXT: resume token undef ; @@ -99,8 +99,8 @@ define i32 addrspace(1)* @f4(i32 addrspace(1)* %arg) gc "statepoint-example" { ; CHECK-LABEL: @f4( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @g, i32 0, i32 1, i32 2, i32 400, i8 90, i32 0, i32 addrspace(1)* [[ARG:%.*]]) -; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 9, i32 9) +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @g, i32 0, i32 1, i32 0, i32 0, i32 addrspace(1)* [[ARG:%.*]]) [ "gc-transition"(i32 400, i8 90) ] +; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 7, i32 7) ; CHECK-NEXT: [[ARG_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED]] to i32 addrspace(1)* ; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED_CASTED]] ; Index: llvm/test/Transforms/RewriteStatepointsForGC/deopt-lowering-attrs.ll =================================================================== --- llvm/test/Transforms/RewriteStatepointsForGC/deopt-lowering-attrs.ll +++ llvm/test/Transforms/RewriteStatepointsForGC/deopt-lowering-attrs.ll @@ -14,9 +14,9 @@ define void @test1() gc "statepoint-example" { ; CHECK-LABEL: @test1( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 1, i32 57) -; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 1, i32 42) -; CHECK-NEXT: [[STATEPOINT_TOKEN2:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @baz, i32 0, i32 0, i32 0, i32 1, i32 13) +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 57) ] +; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) [ "deopt"(i32 42) ] +; CHECK-NEXT: [[STATEPOINT_TOKEN2:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @baz, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 13) ] ; CHECK-NEXT: ret void ; @@ -31,7 +31,7 @@ define void @test2() gc "statepoint-example" { ; CHECK-LABEL: @test2( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 2, i32 0, i32 1, i32 57) #0 +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 2, i32 0, i32 0) #0 [ "deopt"(i32 57) ] ; CHECK-NEXT: ret void ; Index: llvm/test/Transforms/RewriteStatepointsForGC/scalar-base-vector-2.ll =================================================================== --- llvm/test/Transforms/RewriteStatepointsForGC/scalar-base-vector-2.ll +++ llvm/test/Transforms/RewriteStatepointsForGC/scalar-base-vector-2.ll @@ -21,18 +21,18 @@ ; CHECK: bb11: ; CHECK-NEXT: [[TMP12_BASE:%.*]] = phi i8 addrspace(1)* [ [[BASE_EE]], [[BB7]] ], [ [[BASE_EE]], [[BB9]] ], !is_base_value !0 ; CHECK-NEXT: [[TMP12:%.*]] = phi i8 addrspace(1)* [ [[TMP8]], [[BB7]] ], [ [[TMP10]], [[BB9]] ] -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @snork, i32 0, i32 0, i32 0, i32 1, i32 undef, i8 addrspace(1)* [[TMP12_BASE]], i8 addrspace(1)* [[TMP12]]) -; CHECK-NEXT: [[TMP12_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 8, i32 8) -; CHECK-NEXT: [[TMP12_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 8, i32 9) +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @snork, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* [[TMP12_BASE]], i8 addrspace(1)* [[TMP12]]) [ "deopt"(i32 undef) ] +; CHECK-NEXT: [[TMP12_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 7, i32 7) +; CHECK-NEXT: [[TMP12_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 7, i32 8) ; CHECK-NEXT: br label [[BB15]] ; CHECK: bb15: ; CHECK-NEXT: [[TMP16_BASE:%.*]] = phi i8 addrspace(1)* [ [[BASE_EE]], [[BB9]] ], [ [[TMP12_BASE_RELOCATED]], [[BB11]] ], !is_base_value !0 ; CHECK-NEXT: [[TMP16:%.*]] = phi i8 addrspace(1)* [ [[TMP10]], [[BB9]] ], [ [[TMP12_RELOCATED]], [[BB11]] ] ; CHECK-NEXT: br i1 undef, label [[BB17:%.*]], label [[BB20:%.*]] ; CHECK: bb17: -; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @snork, i32 0, i32 0, i32 0, i32 1, i32 undef, i8 addrspace(1)* [[TMP16_BASE]], i8 addrspace(1)* [[TMP16]]) -; CHECK-NEXT: [[TMP16_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 8, i32 8) -; CHECK-NEXT: [[TMP16_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 8, i32 9) +; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @snork, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* [[TMP16_BASE]], i8 addrspace(1)* [[TMP16]]) [ "deopt"(i32 undef) ] +; CHECK-NEXT: [[TMP16_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 7, i32 7) +; CHECK-NEXT: [[TMP16_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 7, i32 8) ; CHECK-NEXT: br label [[BB20]] ; CHECK: bb20: ; CHECK-DAG: [[DOT05:%.*]] = phi i8 addrspace(1)* [ [[TMP16_BASE_RELOCATED]], [[BB17]] ], [ [[TMP16_BASE]], [[BB15]] ] Index: llvm/test/Transforms/RewriteStatepointsForGC/scalar-base-vector.ll =================================================================== --- llvm/test/Transforms/RewriteStatepointsForGC/scalar-base-vector.ll +++ llvm/test/Transforms/RewriteStatepointsForGC/scalar-base-vector.ll @@ -10,7 +10,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 undef, label [[FIRST:%.*]], label [[SECOND:%.*]] ; CHECK: first: -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i64 2882400000, i32 0, i8 addrspace(1)* ()* @def_ptr, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0) +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, i8 addrspace(1)* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8f(i64 2882400000, i32 0, i8 addrspace(1)* ()* @def_ptr, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] ; CHECK-NEXT: [[BASE21:%.*]] = call i8 addrspace(1)* @llvm.experimental.gc.result.p1i8(token [[STATEPOINT_TOKEN]]) ; CHECK-NEXT: br label [[SECOND]] ; CHECK: second: @@ -25,10 +25,10 @@ ; CHECK-NEXT: [[VEC:%.*]] = getelementptr i32, <2 x i32 addrspace(1)*> [[DOTSPLAT]], <2 x i64> [[OFFSETS:%.*]] ; CHECK-NEXT: [[PTR_BASE:%.*]] = extractelement <2 x i32 addrspace(1)*> [[DOTSPLAT_BASE]], i32 1, !is_base_value !0 ; CHECK-NEXT: [[PTR:%.*]] = extractelement <2 x i32 addrspace(1)*> [[VEC]], i32 1 -; CHECK-NEXT: [[STATEPOINT_TOKEN2:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* [[PTR]], i32 addrspace(1)* [[PTR_BASE]]) -; CHECK-NEXT: [[PTR_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN2]], i32 13, i32 12) +; CHECK-NEXT: [[STATEPOINT_TOKEN2:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* [[PTR]], i32 addrspace(1)* [[PTR_BASE]]) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] +; CHECK-NEXT: [[PTR_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN2]], i32 8, i32 7) ; CHECK-NEXT: [[PTR_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[PTR_RELOCATED]] to i32 addrspace(1)* -; CHECK-NEXT: [[PTR_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN2]], i32 13, i32 13) +; CHECK-NEXT: [[PTR_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN2]], i32 8, i32 8) ; CHECK-NEXT: [[PTR_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[PTR_BASE_RELOCATED]] to i32 addrspace(1)* ; CHECK-NEXT: ret i32 addrspace(1)* [[PTR_RELOCATED_CASTED]] ; @@ -151,9 +151,9 @@ ; CHECK-NEXT: [[TMP:%.*]] = phi i8 addrspace(1)* [ [[TMP6:%.*]], [[LATCH]] ], [ undef, [[BB]] ] ; CHECK-NEXT: br label [[BB10:%.*]] ; CHECK: bb10: -; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @spam, i32 0, i32 0, i32 0, i32 1, i8 addrspace(1)* [[TMP]], i8 addrspace(1)* [[TMP]], i8 addrspace(1)* [[TMP_BASE]]) -; CHECK-NEXT: [[TMP_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 9, i32 8) -; CHECK-NEXT: [[TMP_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 9, i32 9) +; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @spam, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* [[TMP]], i8 addrspace(1)* [[TMP_BASE]]) [ "deopt"(i8 addrspace(1)* [[TMP]]) ] +; CHECK-NEXT: [[TMP_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 8, i32 7) +; CHECK-NEXT: [[TMP_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 8, i32 8) ; CHECK-NEXT: br label [[BB25:%.*]] ; CHECK: bb25: ; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, <2 x i8 addrspace(1)*> ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_v2p1i8f(i64 2882400000, i32 0, <2 x i8 addrspace(1)*> ()* @baz, i32 0, i32 0, i32 0, i32 0)