Default to generating statepoints with deopt and gc-transition bundles if needed

Continues from D80598.

The key point of the change is to default to using operand bundles instead of the inline length prefix argument lists for statepoint nodes. An important subtlety to note is that the presence of a bundle has semantic meaning, even if it is empty. As such, we need to make a somewhat deeper change to the interface than is first obvious.

Existing code treats statepoint deopt arguments and the deopt bundle operands differently during inlining. The former is ignored (resulting in caller state being dropped), the later is merged.

We can't preserve the old behaviour for calls with deopt fed to RS4GC and then inlining, but we can avoid the no-deopt case changing. At least in internal testing, that seem to be the important one. (I'd argue the "stop merging after RS4GC" behaviour for the former was always "unexpected", but that the behaviour for non-deopt calls actually make sense.)

Differential Revision: https://reviews.llvm.org/D80674
This commit is contained in:
Philip Reames 2020-05-28 10:11:08 -07:00
parent f0c2cfe4d0
commit 587fa99cfd
8 changed files with 96 additions and 68 deletions

View File

@ -789,7 +789,7 @@ public:
CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
Value *ActualCallee, Value *ActualCallee,
ArrayRef<Value *> CallArgs, ArrayRef<Value *> CallArgs,
ArrayRef<Value *> DeoptArgs, Optional<ArrayRef<Value *>> DeoptArgs,
ArrayRef<Value *> GCArgs, ArrayRef<Value *> GCArgs,
const Twine &Name = ""); const Twine &Name = "");
@ -798,8 +798,8 @@ public:
CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
Value *ActualCallee, uint32_t Flags, Value *ActualCallee, uint32_t Flags,
ArrayRef<Use> CallArgs, ArrayRef<Use> CallArgs,
ArrayRef<Use> TransitionArgs, Optional<ArrayRef<Use>> TransitionArgs,
ArrayRef<Use> DeoptArgs, Optional<ArrayRef<Use>> DeoptArgs,
ArrayRef<Value *> GCArgs, ArrayRef<Value *> GCArgs,
const Twine &Name = ""); const Twine &Name = "");
@ -808,7 +808,7 @@ public:
/// .get()'ed to get the Value pointer. /// .get()'ed to get the Value pointer.
CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
Value *ActualCallee, ArrayRef<Use> CallArgs, Value *ActualCallee, ArrayRef<Use> CallArgs,
ArrayRef<Value *> DeoptArgs, Optional<ArrayRef<Value *>> DeoptArgs,
ArrayRef<Value *> GCArgs, ArrayRef<Value *> GCArgs,
const Twine &Name = ""); const Twine &Name = "");
@ -818,7 +818,7 @@ public:
CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes,
Value *ActualInvokee, BasicBlock *NormalDest, Value *ActualInvokee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, ArrayRef<Value *> InvokeArgs, BasicBlock *UnwindDest, ArrayRef<Value *> InvokeArgs,
ArrayRef<Value *> DeoptArgs, Optional<ArrayRef<Value *>> DeoptArgs,
ArrayRef<Value *> GCArgs, const Twine &Name = ""); ArrayRef<Value *> GCArgs, const Twine &Name = "");
/// Create an invoke to the experimental.gc.statepoint intrinsic to /// Create an invoke to the experimental.gc.statepoint intrinsic to
@ -826,8 +826,8 @@ public:
InvokeInst *CreateGCStatepointInvoke( InvokeInst *CreateGCStatepointInvoke(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags, BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs, ArrayRef<Use> InvokeArgs, Optional<ArrayRef<Use>> TransitionArgs,
ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs,
const Twine &Name = ""); const Twine &Name = "");
// Convenience function for the common case when CallArgs are filled in using // Convenience function for the common case when CallArgs are filled in using
@ -837,7 +837,7 @@ public:
CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes,
Value *ActualInvokee, BasicBlock *NormalDest, Value *ActualInvokee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
ArrayRef<Value *> DeoptArgs, Optional<ArrayRef<Value *>> DeoptArgs,
ArrayRef<Value *> GCArgs, const Twine &Name = ""); ArrayRef<Value *> GCArgs, const Twine &Name = "");
/// Create a call to the experimental.gc.result intrinsic to extract /// Create a call to the experimental.gc.result intrinsic to extract

View File

@ -575,12 +575,11 @@ CallInst *IRBuilderBase::CreateMaskedScatter(Value *Data, Value *Ptrs,
return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, OverloadedTypes); return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, OverloadedTypes);
} }
template <typename T0, typename T1, typename T2, typename T3> template <typename T0, typename T1>
static std::vector<Value *> static std::vector<Value *>
getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes, getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs, Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs, ArrayRef<T1> GCArgs) {
ArrayRef<T3> GCArgs) {
std::vector<Value *> Args; std::vector<Value *> Args;
Args.push_back(B.getInt64(ID)); Args.push_back(B.getInt64(ID));
Args.push_back(B.getInt32(NumPatchBytes)); Args.push_back(B.getInt32(NumPatchBytes));
@ -588,20 +587,40 @@ getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
Args.push_back(B.getInt32(CallArgs.size())); Args.push_back(B.getInt32(CallArgs.size()));
Args.push_back(B.getInt32(Flags)); Args.push_back(B.getInt32(Flags));
Args.insert(Args.end(), CallArgs.begin(), CallArgs.end()); Args.insert(Args.end(), CallArgs.begin(), CallArgs.end());
Args.push_back(B.getInt32(TransitionArgs.size())); // GC Transition and Deopt args are now always handled via operand bundle.
Args.insert(Args.end(), TransitionArgs.begin(), TransitionArgs.end()); // They will be removed from the signature of gc.statepoint shortly.
Args.push_back(B.getInt32(DeoptArgs.size())); Args.push_back(B.getInt32(0));
Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end()); Args.push_back(B.getInt32(0));
Args.insert(Args.end(), GCArgs.begin(), GCArgs.end()); Args.insert(Args.end(), GCArgs.begin(), GCArgs.end());
return Args; return Args;
} }
template<typename T1, typename T2>
static std::vector<OperandBundleDef>
getStatepointBundles(Optional<ArrayRef<T1>> TransitionArgs,
Optional<ArrayRef<T2>> DeoptArgs) {
std::vector<OperandBundleDef> Rval;
if (DeoptArgs) {
SmallVector<Value*, 16> DeoptValues;
DeoptValues.insert(DeoptValues.end(), DeoptArgs->begin(), DeoptArgs->end());
Rval.emplace_back("deopt", DeoptValues);
}
if (TransitionArgs) {
SmallVector<Value*, 16> TransitionValues;
TransitionValues.insert(TransitionValues.end(),
TransitionArgs->begin(), TransitionArgs->end());
Rval.emplace_back("gc-transition", TransitionValues);
}
return Rval;
}
template <typename T0, typename T1, typename T2, typename T3> template <typename T0, typename T1, typename T2, typename T3>
static CallInst *CreateGCStatepointCallCommon( static CallInst *CreateGCStatepointCallCommon(
IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes, IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs, Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs, Optional<ArrayRef<T1>> TransitionArgs,
Optional<ArrayRef<T2>> DeoptArgs, ArrayRef<T3> GCArgs,
const Twine &Name) { const Twine &Name) {
// Extract out the type of the callee. // Extract out the type of the callee.
auto *FuncPtrType = cast<PointerType>(ActualCallee->getType()); auto *FuncPtrType = cast<PointerType>(ActualCallee->getType());
@ -617,13 +636,16 @@ static CallInst *CreateGCStatepointCallCommon(
std::vector<Value *> Args = std::vector<Value *> Args =
getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags, getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags,
CallArgs, TransitionArgs, DeoptArgs, GCArgs); CallArgs, GCArgs);
return createCallHelper(FnStatepoint, Args, Builder, Name);
return Builder->CreateCall(FnStatepoint, Args,
getStatepointBundles(TransitionArgs, DeoptArgs),
Name);
} }
CallInst *IRBuilderBase::CreateGCStatepointCall( CallInst *IRBuilderBase::CreateGCStatepointCall(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
ArrayRef<Value *> CallArgs, ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> CallArgs, Optional<ArrayRef<Value *>> DeoptArgs,
ArrayRef<Value *> GCArgs, const Twine &Name) { ArrayRef<Value *> GCArgs, const Twine &Name) {
return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>( return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>(
this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None), this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
@ -632,8 +654,9 @@ CallInst *IRBuilderBase::CreateGCStatepointCall(
CallInst *IRBuilderBase::CreateGCStatepointCall( CallInst *IRBuilderBase::CreateGCStatepointCall(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags, uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags,
ArrayRef<Use> CallArgs, ArrayRef<Use> TransitionArgs, ArrayRef<Use> CallArgs, Optional<ArrayRef<Use>> TransitionArgs,
ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) { Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs,
const Twine &Name) {
return CreateGCStatepointCallCommon<Use, Use, Use, Value *>( return CreateGCStatepointCallCommon<Use, Use, Use, Value *>(
this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs, this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs,
DeoptArgs, GCArgs, Name); DeoptArgs, GCArgs, Name);
@ -641,7 +664,7 @@ CallInst *IRBuilderBase::CreateGCStatepointCall(
CallInst *IRBuilderBase::CreateGCStatepointCall( CallInst *IRBuilderBase::CreateGCStatepointCall(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
ArrayRef<Use> CallArgs, ArrayRef<Value *> DeoptArgs, ArrayRef<Use> CallArgs, Optional<ArrayRef<Value *>> DeoptArgs,
ArrayRef<Value *> GCArgs, const Twine &Name) { ArrayRef<Value *> GCArgs, const Twine &Name) {
return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>( return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>(
this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None), this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
@ -652,8 +675,9 @@ template <typename T0, typename T1, typename T2, typename T3>
static InvokeInst *CreateGCStatepointInvokeCommon( static InvokeInst *CreateGCStatepointInvokeCommon(
IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes, IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
uint32_t Flags, ArrayRef<T0> InvokeArgs, ArrayRef<T1> TransitionArgs, uint32_t Flags, ArrayRef<T0> InvokeArgs,
ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs, const Twine &Name) { Optional<ArrayRef<T1>> TransitionArgs, Optional<ArrayRef<T2>> DeoptArgs,
ArrayRef<T3> GCArgs, const Twine &Name) {
// Extract out the type of the callee. // Extract out the type of the callee.
auto *FuncPtrType = cast<PointerType>(ActualInvokee->getType()); auto *FuncPtrType = cast<PointerType>(ActualInvokee->getType());
assert(isa<FunctionType>(FuncPtrType->getElementType()) && assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
@ -666,15 +690,17 @@ static InvokeInst *CreateGCStatepointInvokeCommon(
std::vector<Value *> Args = std::vector<Value *> Args =
getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags, getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags,
InvokeArgs, TransitionArgs, DeoptArgs, GCArgs); InvokeArgs, GCArgs);
return Builder->CreateInvoke(FnStatepoint, NormalDest, UnwindDest, Args, return Builder->CreateInvoke(FnStatepoint, NormalDest, UnwindDest, Args,
getStatepointBundles(TransitionArgs, DeoptArgs),
Name); Name);
} }
InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
BasicBlock *NormalDest, BasicBlock *UnwindDest, BasicBlock *NormalDest, BasicBlock *UnwindDest,
ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> InvokeArgs, Optional<ArrayRef<Value *>> DeoptArgs,
ArrayRef<Value *> GCArgs, const Twine &Name) { ArrayRef<Value *> GCArgs, const Twine &Name) {
return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>( return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>(
this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
@ -685,8 +711,8 @@ InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags, BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs, ArrayRef<Use> InvokeArgs, Optional<ArrayRef<Use>> TransitionArgs,
ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) { Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
return CreateGCStatepointInvokeCommon<Use, Use, Use, Value *>( return CreateGCStatepointInvokeCommon<Use, Use, Use, Value *>(
this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags, this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags,
InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name); InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name);
@ -695,7 +721,7 @@ InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) { Optional<ArrayRef<Value *>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>( return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>(
this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs, uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs,

View File

@ -1490,12 +1490,14 @@ makeStatepointExplicitImpl(CallBase *Call, /* to replace */
uint32_t Flags = uint32_t(StatepointFlags::None); uint32_t Flags = uint32_t(StatepointFlags::None);
ArrayRef<Use> CallArgs(Call->arg_begin(), Call->arg_end()); ArrayRef<Use> CallArgs(Call->arg_begin(), Call->arg_end());
ArrayRef<Use> DeoptArgs = GetDeoptBundleOperands(Call); Optional<ArrayRef<Use>> DeoptArgs;
ArrayRef<Use> TransitionArgs; if (auto Bundle = Call->getOperandBundle(LLVMContext::OB_deopt))
if (auto TransitionBundle = DeoptArgs = Bundle->Inputs;
Call->getOperandBundle(LLVMContext::OB_gc_transition)) { Optional<ArrayRef<Use>> 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); Flags |= uint32_t(StatepointFlags::GCTransition);
TransitionArgs = TransitionBundle->Inputs;
} }
// Instead of lowering calls to @llvm.experimental.deoptimize as normal calls // Instead of lowering calls to @llvm.experimental.deoptimize as normal calls

View File

@ -15,7 +15,7 @@ define void @test(i32 %condition) gc "statepoint-example" {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: 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: [[TMP0:%.*]] = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(token [[STATEPOINT_TOKEN]])
; CHECK-NEXT: switch i32 [[CONDITION:%.*]], label [[DEST_A:%.*]] [ ; CHECK-NEXT: switch i32 [[CONDITION:%.*]], label [[DEST_A:%.*]] [
; CHECK-NEXT: i32 0, label [[DEST_B:%.*]] ; CHECK-NEXT: i32 0, label [[DEST_B:%.*]]
@ -30,14 +30,14 @@ define void @test(i32 %condition) gc "statepoint-example" {
; CHECK: merge: ; 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_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: [[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: [[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 13, i32 13) ; 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_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: [[OBJ_TO_CONSUME_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_TO_CONSUME_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: br label [[MERGE_SPLIT:%.*]] ; CHECK-NEXT: br label [[MERGE_SPLIT:%.*]]
; CHECK: 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]] ; CHECK-NEXT: br label [[LOOP]]
; ;
entry: entry:

View File

@ -8,8 +8,8 @@ declare i32 @h()
define i32 addrspace(1)* @f0(i32 addrspace(1)* %arg) gc "statepoint-example" { define i32 addrspace(1)* @f0(i32 addrspace(1)* %arg) gc "statepoint-example" {
; CHECK-LABEL: @f0( ; CHECK-LABEL: @f0(
; CHECK-NEXT: entry: ; 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: [[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 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: [[ARG_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED]] to i32 addrspace(1)*
; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED_CASTED]] ; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED_CASTED]]
; ;
@ -22,16 +22,16 @@ define i32 addrspace(1)* @f0(i32 addrspace(1)* %arg) gc "statepoint-example" {
define i32 addrspace(1)* @f1(i32 addrspace(1)* %arg) gc "statepoint-example" personality i32 8 { define i32 addrspace(1)* @f1(i32 addrspace(1)* %arg) gc "statepoint-example" personality i32 8 {
; CHECK-LABEL: @f1( ; CHECK-LABEL: @f1(
; CHECK-NEXT: entry: ; 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-NEXT: to label [[NORMAL_DEST:%.*]] unwind label [[UNWIND_DEST:%.*]]
; CHECK: normal_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: [[ARG_RELOCATED1_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED1]] to i32 addrspace(1)*
; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED1_CASTED]] ; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED1_CASTED]]
; CHECK: unwind_dest: ; CHECK: unwind_dest:
; CHECK-NEXT: [[LPAD:%.*]] = landingpad token ; CHECK-NEXT: [[LPAD:%.*]] = landingpad token
; CHECK-NEXT: cleanup ; 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: [[ARG_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED]] to i32 addrspace(1)*
; CHECK-NEXT: resume token undef ; CHECK-NEXT: resume token undef
; ;
@ -49,9 +49,9 @@ define i32 addrspace(1)* @f1(i32 addrspace(1)* %arg) gc "statepoint-example" pe
define i32 addrspace(1)* @f2(i32 addrspace(1)* %arg) gc "statepoint-example" { define i32 addrspace(1)* @f2(i32 addrspace(1)* %arg) gc "statepoint-example" {
; CHECK-LABEL: @f2( ; CHECK-LABEL: @f2(
; CHECK-NEXT: entry: ; 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: [[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: [[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: store i32 [[VAL1]], i32 addrspace(1)* [[ARG_RELOCATED_CASTED]], align 4
; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED_CASTED]] ; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED_CASTED]]
@ -67,18 +67,18 @@ define i32 addrspace(1)* @f2(i32 addrspace(1)* %arg) gc "statepoint-example" {
define i32 addrspace(1)* @f3(i32 addrspace(1)* %arg) gc "statepoint-example" personality i32 8 { define i32 addrspace(1)* @f3(i32 addrspace(1)* %arg) gc "statepoint-example" personality i32 8 {
; CHECK-LABEL: @f3( ; CHECK-LABEL: @f3(
; CHECK-NEXT: entry: ; 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-NEXT: to label [[NORMAL_DEST:%.*]] unwind label [[UNWIND_DEST:%.*]]
; CHECK: normal_dest: ; CHECK: normal_dest:
; CHECK-NEXT: [[VAL1:%.*]] = call i32 @llvm.experimental.gc.result.i32(token [[STATEPOINT_TOKEN]]) ; 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: [[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: store i32 [[VAL1]], i32 addrspace(1)* [[ARG_RELOCATED2_CASTED]], align 4
; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED2_CASTED]] ; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED2_CASTED]]
; CHECK: unwind_dest: ; CHECK: unwind_dest:
; CHECK-NEXT: [[LPAD:%.*]] = landingpad token ; CHECK-NEXT: [[LPAD:%.*]] = landingpad token
; CHECK-NEXT: cleanup ; 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: [[ARG_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED]] to i32 addrspace(1)*
; CHECK-NEXT: resume token undef ; CHECK-NEXT: resume token undef
; ;
@ -99,8 +99,8 @@ define i32 addrspace(1)* @f3(i32 addrspace(1)* %arg) gc "statepoint-example" pe
define i32 addrspace(1)* @f4(i32 addrspace(1)* %arg) gc "statepoint-example" { define i32 addrspace(1)* @f4(i32 addrspace(1)* %arg) gc "statepoint-example" {
; CHECK-LABEL: @f4( ; CHECK-LABEL: @f4(
; CHECK-NEXT: entry: ; 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: [[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 9, i32 9) ; 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: [[ARG_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[ARG_RELOCATED]] to i32 addrspace(1)*
; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED_CASTED]] ; CHECK-NEXT: ret i32 addrspace(1)* [[ARG_RELOCATED_CASTED]]
; ;

View File

@ -14,9 +14,9 @@ declare void @baz() "deopt-lowering"="live-through"
define void @test1() gc "statepoint-example" { define void @test1() gc "statepoint-example" {
; CHECK-LABEL: @test1( ; CHECK-LABEL: @test1(
; CHECK-NEXT: entry: ; 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_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 1, i32 42) ; 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 1, i32 13) ; 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 ; CHECK-NEXT: ret void
; ;
@ -31,7 +31,7 @@ entry:
define void @test2() gc "statepoint-example" { define void @test2() gc "statepoint-example" {
; CHECK-LABEL: @test2( ; CHECK-LABEL: @test2(
; CHECK-NEXT: entry: ; 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 ; CHECK-NEXT: ret void
; ;

View File

@ -21,18 +21,18 @@ define void @widget() gc "statepoint-example" {
; CHECK: bb11: ; CHECK: bb11:
; CHECK-NEXT: [[TMP12_BASE:%.*]] = phi i8 addrspace(1)* [ [[BASE_EE]], [[BB7]] ], [ [[BASE_EE]], [[BB9]] ], !is_base_value !0 ; 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: [[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: [[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 8, i32 8) ; 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 8, i32 9) ; 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-NEXT: br label [[BB15]]
; CHECK: 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_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: [[TMP16:%.*]] = phi i8 addrspace(1)* [ [[TMP10]], [[BB9]] ], [ [[TMP12_RELOCATED]], [[BB11]] ]
; CHECK-NEXT: br i1 undef, label [[BB17:%.*]], label [[BB20:%.*]] ; CHECK-NEXT: br i1 undef, label [[BB17:%.*]], label [[BB20:%.*]]
; CHECK: bb17: ; 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: [[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 8, i32 8) ; 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 8, i32 9) ; 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-NEXT: br label [[BB20]]
; CHECK: bb20: ; CHECK: bb20:
; CHECK-DAG: [[DOT05:%.*]] = phi i8 addrspace(1)* [ [[TMP16_BASE_RELOCATED]], [[BB17]] ], [ [[TMP16_BASE]], [[BB15]] ] ; CHECK-DAG: [[DOT05:%.*]] = phi i8 addrspace(1)* [ [[TMP16_BASE_RELOCATED]], [[BB17]] ], [ [[TMP16_BASE]], [[BB15]] ]

View File

@ -10,7 +10,7 @@ define i32 addrspace(1)* @test1(i8 addrspace(1)* %base1, <2 x i64> %offsets) gc
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 undef, label [[FIRST:%.*]], label [[SECOND:%.*]] ; CHECK-NEXT: br i1 undef, label [[FIRST:%.*]], label [[SECOND:%.*]]
; CHECK: first: ; 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: [[BASE21:%.*]] = call i8 addrspace(1)* @llvm.experimental.gc.result.p1i8(token [[STATEPOINT_TOKEN]])
; CHECK-NEXT: br label [[SECOND]] ; CHECK-NEXT: br label [[SECOND]]
; CHECK: second: ; CHECK: second:
@ -25,10 +25,10 @@ define i32 addrspace(1)* @test1(i8 addrspace(1)* %base1, <2 x i64> %offsets) gc
; CHECK-NEXT: [[VEC:%.*]] = getelementptr i32, <2 x i32 addrspace(1)*> [[DOTSPLAT]], <2 x i64> [[OFFSETS:%.*]] ; 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_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: [[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: [[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 13, i32 12) ; 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_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: [[PTR_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[PTR_BASE_RELOCATED]] to i32 addrspace(1)*
; CHECK-NEXT: ret i32 addrspace(1)* [[PTR_RELOCATED_CASTED]] ; CHECK-NEXT: ret i32 addrspace(1)* [[PTR_RELOCATED_CASTED]]
; ;
@ -151,9 +151,9 @@ define void @test6() gc "statepoint-example" {
; CHECK-NEXT: [[TMP:%.*]] = phi i8 addrspace(1)* [ [[TMP6:%.*]], [[LATCH]] ], [ undef, [[BB]] ] ; CHECK-NEXT: [[TMP:%.*]] = phi i8 addrspace(1)* [ [[TMP6:%.*]], [[LATCH]] ], [ undef, [[BB]] ]
; CHECK-NEXT: br label [[BB10:%.*]] ; CHECK-NEXT: br label [[BB10:%.*]]
; CHECK: 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: [[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 9, i32 8) ; 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 9, i32 9) ; 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-NEXT: br label [[BB25:%.*]]
; CHECK: 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) ; 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)