diff --git a/llvm/docs/Statepoints.rst b/llvm/docs/Statepoints.rst index 49389b6e2685e2..e857d6f50ba3b6 100644 --- a/llvm/docs/Statepoints.rst +++ b/llvm/docs/Statepoints.rst @@ -449,8 +449,7 @@ Syntax: func_type , i64 <#call args>, i64 , ... (call parameters), - i64 0, i64 0, - ... (gc parameters)) + i64 0, i64 0) Overview: """"""""" @@ -520,15 +519,6 @@ These were originally the length prefixes for 'gc transition parameter' and entirely replaced with the corresponding operand bundles. In a future revision, these now redundant arguments will be removed. -The 'gc parameters' arguments contain every pointer to a garbage -collector object which potentially needs to be updated by the garbage -collector. Note that the argument list must explicitly contain a base -pointer for every derived pointer listed. The order of arguments is -unimportant. Unlike the other variable length parameter sets, this -list is not length prefixed. Use of the 'gc parameters' list is -deprecated and will eventually be replaced entirely with the -:ref:`gc-live ` operand bundle. - Semantics: """""""""" diff --git a/llvm/include/llvm/IR/Statepoint.h b/llvm/include/llvm/IR/Statepoint.h index 1ace39c107016f..6ce15839df4687 100644 --- a/llvm/include/llvm/IR/Statepoint.h +++ b/llvm/include/llvm/IR/Statepoint.h @@ -136,7 +136,7 @@ class GCStatepointInst : public CallBase { /// Return an end iterator of the arguments to the underlying call const_op_iterator actual_arg_end() const { auto I = actual_arg_begin() + actual_arg_size(); - assert((arg_end() - I) >= 0); + assert((arg_end() - I) == 2); return I; } /// range adapter for actual call arguments @@ -147,16 +147,12 @@ class GCStatepointInst : public CallBase { const_op_iterator gc_transition_args_begin() const { if (auto Opt = getOperandBundle(LLVMContext::OB_gc_transition)) return Opt->Inputs.begin(); - auto I = actual_arg_end() + 1; - assert((arg_end() - I) >= 0); - return I; + return arg_end(); } const_op_iterator gc_transition_args_end() const { if (auto Opt = getOperandBundle(LLVMContext::OB_gc_transition)) return Opt->Inputs.end(); - auto I = gc_transition_args_begin() + getNumDeoptArgs(); - assert((arg_end() - I) >= 0); - return I; + return arg_end(); } /// range adapter for GC transition arguments @@ -167,19 +163,12 @@ class GCStatepointInst : public CallBase { const_op_iterator deopt_begin() const { if (auto Opt = getOperandBundle(LLVMContext::OB_deopt)) return Opt->Inputs.begin(); - // The current format has two length prefix bundles between call args and - // start of gc args. This will be removed in the near future. - uint64_t NumTrans = getNumGCTransitionArgs(); - const_op_iterator I = actual_arg_end() + 2 + NumTrans; - assert((arg_end() - I) >= 0); - return I; + return arg_end(); } const_op_iterator deopt_end() const { if (auto Opt = getOperandBundle(LLVMContext::OB_deopt)) return Opt->Inputs.end(); - auto I = deopt_begin() + getNumDeoptArgs(); - assert((arg_end() - I) >= 0); - return I; + return arg_end(); } /// range adapter for vm state arguments @@ -192,30 +181,16 @@ class GCStatepointInst : public CallBase { const_op_iterator gc_args_begin() const { if (auto Opt = getOperandBundle(LLVMContext::OB_gc_live)) return Opt->Inputs.begin(); - - // The current format has two length prefix bundles between call args and - // start of gc args. This will be removed in the near future. - uint64_t NumTrans = getNumGCTransitionArgs(); - uint64_t NumDeopt = getNumDeoptArgs(); - auto I = actual_arg_end() + 2 + NumTrans + NumDeopt; - assert((arg_end() - I) >= 0); - return I; + return arg_end(); } /// Return an end iterator for the gc argument range const_op_iterator gc_args_end() const { if (auto Opt = getOperandBundle(LLVMContext::OB_gc_live)) return Opt->Inputs.end(); - return arg_end(); } - /// Return the operand index at which the gc args begin - unsigned gcArgsStartIdx() const { - assert(!getOperandBundle(LLVMContext::OB_gc_live)); - return gc_args_begin() - op_begin(); - } - /// range adapter for gc arguments iterator_range gc_args() const { return make_range(gc_args_begin(), gc_args_end()); @@ -236,19 +211,6 @@ class GCStatepointInst : public CallBase { return GRI; return nullptr; } - -private: - int getNumGCTransitionArgs() const { - const Value *NumGCTransitionArgs = *actual_arg_end(); - return cast(NumGCTransitionArgs)->getZExtValue(); - } - - int getNumDeoptArgs() const { - uint64_t NumTrans = getNumGCTransitionArgs(); - const_op_iterator trans_end = actual_arg_end() + 1 + NumTrans; - const Value *NumDeoptArgs = *trans_end; - return cast(NumDeoptArgs)->getZExtValue(); - } }; /// Common base class for representing values projected from a statepoint. diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 52166a53c6fd5b..db52f36e4f1092 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -2136,10 +2136,9 @@ void Verifier::verifyStatepoint(const CallBase &Call) { Assert(NumDeoptArgs == 0, "gc.statepoint w/inline deopt operands is deprecated", Call); - const int ExpectedNumArgs = - 7 + NumCallArgs + NumTransitionArgs + NumDeoptArgs; - Assert(ExpectedNumArgs <= (int)Call.arg_size(), - "gc.statepoint too few arguments according to length fields", Call); + const int ExpectedNumArgs = 7 + NumCallArgs; + Assert(ExpectedNumArgs == (int)Call.arg_size(), + "gc.statepoint too many arguments", Call); // Check that the only uses of this gc.statepoint are gc.result or // gc.relocate calls which are tied to this statepoint and thus part @@ -4803,45 +4802,6 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { "gc.relocate: statepoint base index out of bounds", Call); Assert(DerivedIndex < Opt->Inputs.size(), "gc.relocate: statepoint derived index out of bounds", Call); - } else { - Assert(BaseIndex < StatepointCall.arg_size(), - "gc.relocate: statepoint base index out of bounds", Call); - Assert(DerivedIndex < StatepointCall.arg_size(), - "gc.relocate: statepoint derived index out of bounds", Call); - - // Check that BaseIndex and DerivedIndex fall within the 'gc parameters' - // section of the statepoint's argument. - Assert(StatepointCall.arg_size() > 0, - "gc.statepoint: insufficient arguments"); - Assert(isa(StatepointCall.getArgOperand(3)), - "gc.statement: number of call arguments must be constant integer"); - const uint64_t NumCallArgs = - cast(StatepointCall.getArgOperand(3))->getZExtValue(); - Assert(StatepointCall.arg_size() > NumCallArgs + 5, - "gc.statepoint: mismatch in number of call arguments"); - Assert(isa(StatepointCall.getArgOperand(NumCallArgs + 5)), - "gc.statepoint: number of transition arguments must be " - "a constant integer"); - const uint64_t NumTransitionArgs = - cast(StatepointCall.getArgOperand(NumCallArgs + 5)) - ->getZExtValue(); - const uint64_t DeoptArgsStart = 4 + NumCallArgs + 1 + NumTransitionArgs + 1; - Assert(isa(StatepointCall.getArgOperand(DeoptArgsStart)), - "gc.statepoint: number of deoptimization arguments must be " - "a constant integer"); - const uint64_t NumDeoptArgs = - cast(StatepointCall.getArgOperand(DeoptArgsStart)) - ->getZExtValue(); - const uint64_t GCParamArgsStart = DeoptArgsStart + 1 + NumDeoptArgs; - const uint64_t GCParamArgsEnd = StatepointCall.arg_size(); - Assert(GCParamArgsStart <= BaseIndex && BaseIndex < GCParamArgsEnd, - "gc.relocate: statepoint base index doesn't fall within the " - "'gc parameters' section of the statepoint call", - Call); - Assert(GCParamArgsStart <= DerivedIndex && DerivedIndex < GCParamArgsEnd, - "gc.relocate: statepoint derived index doesn't fall within the " - "'gc parameters' section of the statepoint call", - Call); } // Relocated value must be either a pointer type or vector-of-pointer type, diff --git a/llvm/test/CodeGen/Generic/overloaded-intrinsic-name.ll b/llvm/test/CodeGen/Generic/overloaded-intrinsic-name.ll index b0ab95edec435e..e3f120412e04cc 100644 --- a/llvm/test/CodeGen/Generic/overloaded-intrinsic-name.ll +++ b/llvm/test/CodeGen/Generic/overloaded-intrinsic-name.ll @@ -12,75 +12,75 @@ ; will serve the purpose. ; function and integer -define i32* @test_iAny(i32* %v) gc "statepoint-example" { - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32* %v)] - %v-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 0) - ret i32* %v-new +define i32 addrspace(1)* @test_iAny(i32 addrspace(1)* %v) gc "statepoint-example" { + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32 addrspace(1)* %v)] + %v-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0) + ret i32 addrspace(1)* %v-new } ; float -define float* @test_fAny(float* %v) gc "statepoint-example" { - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(float* %v)] - %v-new = call float* @llvm.experimental.gc.relocate.p0f32(token %tok, i32 0, i32 0) - ret float* %v-new +define float addrspace(1)* @test_fAny(float addrspace(1)* %v) gc "statepoint-example" { + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(float addrspace(1)* %v)] + %v-new = call float addrspace(1)* @llvm.experimental.gc.relocate.p1f32(token %tok, i32 0, i32 0) + ret float addrspace(1)* %v-new } ; array of integers -define [3 x i32]* @test_aAny([3 x i32]* %v) gc "statepoint-example" { - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"([3 x i32]* %v)] - %v-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token %tok, i32 0, i32 0) - ret [3 x i32]* %v-new +define [3 x i32] addrspace(1)* @test_aAny([3 x i32] addrspace(1)* %v) gc "statepoint-example" { + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"([3 x i32] addrspace(1)* %v)] + %v-new = call [3 x i32] addrspace(1)* @llvm.experimental.gc.relocate.p1a3i32(token %tok, i32 0, i32 0) + ret [3 x i32] addrspace(1)* %v-new } ; vector of integers -define <3 x i32>* @test_vAny(<3 x i32>* %v) gc "statepoint-example" { - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(<3 x i32>* %v)] - %v-new = call <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(token %tok, i32 0, i32 0) - ret <3 x i32>* %v-new +define <3 x i32> addrspace(1)* @test_vAny(<3 x i32> addrspace(1)* %v) gc "statepoint-example" { + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(<3 x i32> addrspace(1)* %v)] + %v-new = call <3 x i32> addrspace(1)* @llvm.experimental.gc.relocate.p1v3i32(token %tok, i32 0, i32 0) + ret <3 x i32> addrspace(1)* %v-new } %struct.test = type { i32, i1 } ; struct -define %struct.test* @test_struct(%struct.test* %v) gc "statepoint-example" { - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(%struct.test* %v)] - %v-new = call %struct.test* @llvm.experimental.gc.relocate.p0s_struct.tests(token %tok, i32 0, i32 0) - ret %struct.test* %v-new +define %struct.test addrspace(1)* @test_struct(%struct.test addrspace(1)* %v) gc "statepoint-example" { + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(%struct.test addrspace(1)* %v)] + %v-new = call %struct.test addrspace(1)* @llvm.experimental.gc.relocate.p1s_struct.tests(token %tok, i32 0, i32 0) + ret %struct.test addrspace(1)* %v-new } ; literal struct with nested literal struct -define {i64, i64, {i64} }* @test_literal_struct({i64, i64, {i64}}* %v) gc "statepoint-example" { - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"({i64, i64, {i64}} *%v)] - %v-new = call {i64, i64, {i64}}* @llvm.experimental.gc.relocate.p0sl_i64i64sl_i64ss.test(token %tok, i32 0, i32 0) - ret {i64, i64, {i64}}* %v-new +define {i64, i64, {i64} } addrspace(1)* @test_literal_struct({i64, i64, {i64}} addrspace(1)* %v) gc "statepoint-example" { + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"({i64, i64, {i64}} addrspace(1)* %v)] + %v-new = call {i64, i64, {i64}} addrspace(1)* @llvm.experimental.gc.relocate.p1sl_i64i64sl_i64ss.test(token %tok, i32 0, i32 0) + ret {i64, i64, {i64}} addrspace(1)* %v-new } ; struct with a horrible name, broken when structs were unprefixed %i32 = type { i32 } -define %i32* @test_i32_struct(%i32* %v) gc "statepoint-example" { +define %i32 addrspace(1)* @test_i32_struct(%i32 addrspace(1)* %v) gc "statepoint-example" { entry: - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(%i32* %v)] - %v-new = call %i32* @llvm.experimental.gc.relocate.p0s_i32s(token %tok, i32 0, i32 0) - ret %i32* %v-new + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(%i32 addrspace(1)* %v)] + %v-new = call %i32 addrspace(1)* @llvm.experimental.gc.relocate.p1s_i32s(token %tok, i32 0, i32 0) + ret %i32 addrspace(1)* %v-new } ; completely broken intrinsic naming due to needing remangling. Just use random naming to test -define %i32* @test_broken_names(%i32* %v) gc "statepoint-example" { +define %i32 addrspace(1)* @test_broken_names(%i32 addrspace(1)* %v) gc "statepoint-example" { entry: - %tok = call fastcc token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.deadbeef(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(%i32* %v)] + %tok = call fastcc token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.deadbeef(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(%i32 addrspace(1)* %v)] ; Make sure we do not destroy the calling convention when remangling ; CHECK: fastcc - %v-new = call %i32* @llvm.experimental.gc.relocate.beefdead(token %tok, i32 0, i32 0) - ret %i32* %v-new + %v-new = call %i32 addrspace(1)* @llvm.experimental.gc.relocate.beefdead(token %tok, i32 0, i32 0) + ret %i32 addrspace(1)* %v-new } declare zeroext i1 @return_i1() declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) -declare i32* @llvm.experimental.gc.relocate.p0i32(token, i32, i32) -declare float* @llvm.experimental.gc.relocate.p0f32(token, i32, i32) -declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token, i32, i32) -declare <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(token, i32, i32) -declare %struct.test* @llvm.experimental.gc.relocate.p0s_struct.tests(token, i32, i32) -declare {i64, i64, {i64}}* @llvm.experimental.gc.relocate.p0sl_i64i64sl_i64ss.test(token, i32, i32) -declare %i32* @llvm.experimental.gc.relocate.p0s_i32s(token, i32, i32) -declare %i32* @llvm.experimental.gc.relocate.beefdead(token, i32, i32) +declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32) +declare float addrspace(1)* @llvm.experimental.gc.relocate.p1f32(token, i32, i32) +declare [3 x i32] addrspace(1)* @llvm.experimental.gc.relocate.p1a3i32(token, i32, i32) +declare <3 x i32> addrspace(1)* @llvm.experimental.gc.relocate.p1v3i32(token, i32, i32) +declare %struct.test addrspace(1)* @llvm.experimental.gc.relocate.p1s_struct.tests(token, i32, i32) +declare {i64, i64, {i64}} addrspace(1)* @llvm.experimental.gc.relocate.p1sl_i64i64sl_i64ss.test(token, i32, i32) +declare %i32 addrspace(1)* @llvm.experimental.gc.relocate.p1s_i32s(token, i32, i32) +declare %i32 addrspace(1)* @llvm.experimental.gc.relocate.beefdead(token, i32, i32) declare token @llvm.experimental.gc.statepoint.deadbeef(i64, i32, i1 ()*, i32, i32, ...) diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/statepoint-relocate.ll b/llvm/test/Transforms/CodeGenPrepare/X86/statepoint-relocate.ll index 092410cf260b1f..eda8a8e84beb15 100644 --- a/llvm/test/Transforms/CodeGenPrepare/X86/statepoint-relocate.ll +++ b/llvm/test/Transforms/CodeGenPrepare/X86/statepoint-relocate.ll @@ -5,145 +5,145 @@ target triple = "x86_64-pc-linux-gnu" declare zeroext i1 @return_i1() -define i32 @test_sor_basic(i32* %base) gc "statepoint-example" { -; CHECK: getelementptr i32, i32* %base, i32 15 -; CHECK: getelementptr i32, i32* %base-new, i32 15 +define i32 @test_sor_basic(i32 addrspace(1)* %base) gc "statepoint-example" { +; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15 +; CHECK: getelementptr i32, i32 addrspace(1)* %base-new, i32 15 entry: - %ptr = getelementptr i32, i32* %base, i32 15 - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32* %base, i32* %ptr)] - %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 0) - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 1) - %ret = load i32, i32* %ptr-new + %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15 + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32 addrspace(1)* %base, i32 addrspace(1)* %ptr)] + %base-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0) + %ptr-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 1) + %ret = load i32, i32 addrspace(1)* %ptr-new ret i32 %ret } -define i32 @test_sor_two_derived(i32* %base) gc "statepoint-example" { -; CHECK: getelementptr i32, i32* %base, i32 15 -; CHECK: getelementptr i32, i32* %base, i32 12 -; CHECK: getelementptr i32, i32* %base-new, i32 12 -; CHECK: getelementptr i32, i32* %base-new, i32 15 +define i32 @test_sor_two_derived(i32 addrspace(1)* %base) gc "statepoint-example" { +; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15 +; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 12 +; CHECK: getelementptr i32, i32 addrspace(1)* %base-new, i32 12 +; CHECK: getelementptr i32, i32 addrspace(1)* %base-new, i32 15 entry: - %ptr = getelementptr i32, i32* %base, i32 15 - %ptr2 = getelementptr i32, i32* %base, i32 12 - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32* %base, i32* %ptr, i32* %ptr2)] - %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 0) - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 1) - %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 2) - %ret = load i32, i32* %ptr-new + %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15 + %ptr2 = getelementptr i32, i32 addrspace(1)* %base, i32 12 + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32 addrspace(1)* %base, i32 addrspace(1)* %ptr, i32 addrspace(1)* %ptr2)] + %base-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0) + %ptr-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 1) + %ptr2-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 2) + %ret = load i32, i32 addrspace(1)* %ptr-new ret i32 %ret } -define i32 @test_sor_ooo(i32* %base) gc "statepoint-example" { -; CHECK: getelementptr i32, i32* %base, i32 15 -; CHECK: getelementptr i32, i32* %base-new, i32 15 +define i32 @test_sor_ooo(i32 addrspace(1)* %base) gc "statepoint-example" { +; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15 +; CHECK: getelementptr i32, i32 addrspace(1)* %base-new, i32 15 entry: - %ptr = getelementptr i32, i32* %base, i32 15 - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32* %base, i32* %ptr)] - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 1) - %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 0) - %ret = load i32, i32* %ptr-new + %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15 + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32 addrspace(1)* %base, i32 addrspace(1)* %ptr)] + %ptr-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 1) + %base-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0) + %ret = load i32, i32 addrspace(1)* %ptr-new ret i32 %ret } -define i32 @test_sor_gep_smallint([3 x i32]* %base) gc "statepoint-example" { -; CHECK: getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 2 -; CHECK: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 2 +define i32 @test_sor_gep_smallint([3 x i32] addrspace(1)* %base) gc "statepoint-example" { +; CHECK: getelementptr [3 x i32], [3 x i32] addrspace(1)* %base, i32 0, i32 2 +; CHECK: getelementptr [3 x i32], [3 x i32] addrspace(1)* %base-new, i32 0, i32 2 entry: - %ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 2 - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"([3 x i32]* %base, i32* %ptr)] - %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token %tok, i32 0, i32 0) - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 1) - %ret = load i32, i32* %ptr-new + %ptr = getelementptr [3 x i32], [3 x i32] addrspace(1)* %base, i32 0, i32 2 + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"([3 x i32] addrspace(1)* %base, i32 addrspace(1)* %ptr)] + %base-new = call [3 x i32] addrspace(1)* @llvm.experimental.gc.relocate.p1a3i32(token %tok, i32 0, i32 0) + %ptr-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 1) + %ret = load i32, i32 addrspace(1)* %ptr-new ret i32 %ret } -define i32 @test_sor_gep_largeint([3 x i32]* %base) gc "statepoint-example" { -; CHECK: getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 21 -; CHECK-NOT: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 21 +define i32 @test_sor_gep_largeint([3 x i32] addrspace(1)* %base) gc "statepoint-example" { +; CHECK: getelementptr [3 x i32], [3 x i32] addrspace(1)* %base, i32 0, i32 21 +; CHECK-NOT: getelementptr [3 x i32], [3 x i32] addrspace(1)* %base-new, i32 0, i32 21 entry: - %ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 21 - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"([3 x i32]* %base, i32* %ptr)] - %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token %tok, i32 0, i32 0) - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 1) - %ret = load i32, i32* %ptr-new + %ptr = getelementptr [3 x i32], [3 x i32] addrspace(1)* %base, i32 0, i32 21 + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"([3 x i32] addrspace(1)* %base, i32 addrspace(1)* %ptr)] + %base-new = call [3 x i32] addrspace(1)* @llvm.experimental.gc.relocate.p1a3i32(token %tok, i32 0, i32 0) + %ptr-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 1) + %ret = load i32, i32 addrspace(1)* %ptr-new ret i32 %ret } -define i32 @test_sor_noop(i32* %base) gc "statepoint-example" { -; CHECK: getelementptr i32, i32* %base, i32 15 -; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 1) -; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 2) +define i32 @test_sor_noop(i32 addrspace(1)* %base) gc "statepoint-example" { +; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15 +; CHECK: call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 1) +; CHECK: call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 2) entry: - %ptr = getelementptr i32, i32* %base, i32 15 - %ptr2 = getelementptr i32, i32* %base, i32 12 - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32* %base, i32* %ptr, i32* %ptr2)] - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 1) - %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 2) - %ret = load i32, i32* %ptr-new + %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15 + %ptr2 = getelementptr i32, i32 addrspace(1)* %base, i32 12 + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32 addrspace(1)* %base, i32 addrspace(1)* %ptr, i32 addrspace(1)* %ptr2)] + %ptr-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 1) + %ptr2-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 2) + %ret = load i32, i32 addrspace(1)* %ptr-new ret i32 %ret } -define i32 @test_sor_basic_wrong_order(i32* %base) gc "statepoint-example" { +define i32 @test_sor_basic_wrong_order(i32 addrspace(1)* %base) gc "statepoint-example" { ; CHECK-LABEL: @test_sor_basic_wrong_order ; Here we have base relocate inserted after derived. Make sure that we don't ; produce uses of the relocated base pointer before it's definition. entry: - %ptr = getelementptr i32, i32* %base, i32 15 - ; CHECK: getelementptr i32, i32* %base, i32 15 - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32* %base, i32* %ptr)] - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 1) - %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 0) - ; CHECK: %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 0) - ; CHECK-NEXT: getelementptr i32, i32* %base-new, i32 15 - %ret = load i32, i32* %ptr-new + %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15 + ; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15 + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32 addrspace(1)* %base, i32 addrspace(1)* %ptr)] + %ptr-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 1) + %base-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0) + ; CHECK: %base-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0) + ; CHECK-NEXT: getelementptr i32, i32 addrspace(1)* %base-new, i32 15 + %ret = load i32, i32 addrspace(1)* %ptr-new ret i32 %ret } -define i32 @test_sor_noop_cross_bb(i1 %external-cond, i32* %base) gc "statepoint-example" { +define i32 @test_sor_noop_cross_bb(i1 %external-cond, i32 addrspace(1)* %base) gc "statepoint-example" { ; CHECK-LABEL: @test_sor_noop_cross_bb ; Here base relocate doesn't dominate derived relocate. Make sure that we don't ; produce undefined use of the relocated base pointer. entry: - %ptr = getelementptr i32, i32* %base, i32 15 - ; CHECK: getelementptr i32, i32* %base, i32 15 - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32* %base, i32* %ptr)] + %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15 + ; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15 + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32 addrspace(1)* %base, i32 addrspace(1)* %ptr)] br i1 %external-cond, label %left, label %right left: - %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 1) - ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 1) - %ret-new = load i32, i32* %ptr-new + %ptr-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 1) + ; CHECK: call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 1) + %ret-new = load i32, i32 addrspace(1)* %ptr-new ret i32 %ret-new right: - %ptr-base = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 0) - ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 0) - %ret-base = load i32, i32* %ptr-base + %ptr-base = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0) + ; CHECK: call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0) + %ret-base = load i32, i32 addrspace(1)* %ptr-base ret i32 %ret-base } -define i32 @test_sor_noop_same_bb(i1 %external-cond, i32* %base) gc "statepoint-example" { +define i32 @test_sor_noop_same_bb(i1 %external-cond, i32 addrspace(1)* %base) gc "statepoint-example" { ; CHECK-LABEL: @test_sor_noop_same_bb ; Here base relocate doesn't dominate derived relocate. Make sure that we don't ; produce undefined use of the relocated base pointer. entry: - %ptr1 = getelementptr i32, i32* %base, i32 15 - ; CHECK: getelementptr i32, i32* %base, i32 15 - %ptr2 = getelementptr i32, i32* %base, i32 5 - ; CHECK: getelementptr i32, i32* %base, i32 5 - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32* %base, i32* %ptr1, i32* %ptr2)] - ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 0) - %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 2) - %ret2-new = load i32, i32* %ptr2-new - ; CHECK: getelementptr i32, i32* %base-new, i32 5 - %ptr1-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 1) - %ret1-new = load i32, i32* %ptr1-new - ; CHECK: getelementptr i32, i32* %base-new, i32 15 - %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 0, i32 0) + %ptr1 = getelementptr i32, i32 addrspace(1)* %base, i32 15 + ; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15 + %ptr2 = getelementptr i32, i32 addrspace(1)* %base, i32 5 + ; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 5 + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(i32 addrspace(1)* %base, i32 addrspace(1)* %ptr1, i32 addrspace(1)* %ptr2)] + ; CHECK: call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0) + %ptr2-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 2) + %ret2-new = load i32, i32 addrspace(1)* %ptr2-new + ; CHECK: getelementptr i32, i32 addrspace(1)* %base-new, i32 5 + %ptr1-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 1) + %ret1-new = load i32, i32 addrspace(1)* %ptr1-new + ; CHECK: getelementptr i32, i32 addrspace(1)* %base-new, i32 15 + %base-new = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0) %ret-new = add i32 %ret2-new, %ret1-new ret i32 %ret-new } declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) -declare i32* @llvm.experimental.gc.relocate.p0i32(token, i32, i32) -declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token, i32, i32) +declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32) +declare [3 x i32] addrspace(1)* @llvm.experimental.gc.relocate.p1a3i32(token, i32, i32) diff --git a/llvm/test/Transforms/InstCombine/statepoint-iter.ll b/llvm/test/Transforms/InstCombine/statepoint-iter.ll index 72f889a2f97e76..53025a472b9f54 100644 --- a/llvm/test/Transforms/InstCombine/statepoint-iter.ll +++ b/llvm/test/Transforms/InstCombine/statepoint-iter.ll @@ -13,14 +13,14 @@ right: br label %merge left: - %safepoint_token = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32* null) - %pnew = call i32* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 7, i32 7) + %safepoint_token = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32* null)] + %pnew = call i32* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 0, i32 0) br label %merge merge: %pnew_phi = phi i32* [null, %right], [%pnew, %left] - %safepoint_token2 = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32* %pnew_phi) - %pnew2 = call i32* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token2, i32 7, i32 7) + %safepoint_token2 = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32* %pnew_phi)] + %pnew2 = call i32* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token2, i32 0, i32 0) %cmp = icmp eq i32* %pnew2, null ret i1 %cmp ; CHECK-LABEL: test_null @@ -37,14 +37,14 @@ right: br label %merge left: - %safepoint_token = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32* undef) - %pnew = call i32* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 7, i32 7) + %safepoint_token = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32* undef)] + %pnew = call i32* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 0, i32 0) br label %merge merge: %pnew_phi = phi i32* [undef, %right], [%pnew, %left] - %safepoint_token2 = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0, i32* %pnew_phi) - %pnew2 = call i32* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token2, i32 7, i32 7) + %safepoint_token2 = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32* %pnew_phi)] + %pnew2 = call i32* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token2, i32 0, i32 0) ret i32* %pnew2 ; CHECK-LABEL: test_undef ; CHECK-NOT: %pnew diff --git a/llvm/test/Verifier/invalid-statepoint.ll b/llvm/test/Verifier/invalid-statepoint.ll index 6b4bc087b3e0cf..c0e25c1aab3253 100644 --- a/llvm/test/Verifier/invalid-statepoint.ll +++ b/llvm/test/Verifier/invalid-statepoint.ll @@ -1,6 +1,6 @@ ; RUN: not opt -verify 2>&1 < %s | FileCheck %s -; CHECK: gc.statepoint: mismatch in number of call arguments +; CHECK: gc.statepoint mismatch in number of call args declare zeroext i1 @return0i1() @@ -10,11 +10,11 @@ declare token @llvm.experimental.gc.statepoint.p0f0i1f(i64, i32, i1 ()*, i32, i3 ; Function Attrs: nounwind declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32) #0 -define i32 addrspace(1)* @0(i32 addrspace(1)* %dparam) { +define i32 addrspace(1)* @0(i32 addrspace(1)* %dparam) gc "statepoint-example" { %a00 = load i32, i32 addrspace(1)* %dparam - %to0 = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f0i1f(i64 0, i32 0, i1 ()* @return0i1, i32 9, i32 0, i2 0, i32 addrspace(1)* %dparam) - %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %to0, i32 2, i32 6) + %to0 = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f0i1f(i64 0, i32 0, i1 ()* @return0i1, i32 9, i32 0, i2 0) ["gc-live" (i32 addrspace(1)* %dparam)] + %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %to0, i32 0, i32 0) ret i32 addrspace(1)* %relocate } -attributes #0 = { nounwind } \ No newline at end of file +attributes #0 = { nounwind } diff --git a/llvm/test/Verifier/invalid-statepoint2.ll b/llvm/test/Verifier/invalid-statepoint2.ll deleted file mode 100644 index 10bcd4f4f318f5..00000000000000 --- a/llvm/test/Verifier/invalid-statepoint2.ll +++ /dev/null @@ -1,18 +0,0 @@ -; RUN: not opt -S < %s -verify 2>&1 | FileCheck %s - -; CHECK: gc.statepoint: number of deoptimization arguments must be a constant integer - -declare void @use(...) -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 i32 @"personality_function"() - -;; Basic usage -define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg, i32 %val) gc "statepoint-example" { -entry: - %cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)* - %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 %val, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg) - %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 12, i32 13) - ret i64 addrspace(1)* %reloc -} diff --git a/llvm/test/Verifier/statepoint.ll b/llvm/test/Verifier/statepoint.ll index 79c11c8e711647..96ab02ff458197 100644 --- a/llvm/test/Verifier/statepoint.ll +++ b/llvm/test/Verifier/statepoint.ll @@ -11,11 +11,11 @@ declare i32 @"personality_function"() define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg) gc "statepoint-example" { entry: %cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)* - %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg) ["deopt" (i32 0, i32 0, i32 0, i32 10, i32 0)] - %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 7, i32 8) + %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg), "deopt" (i32 0, i32 0, i32 0, i32 10, i32 0)] + %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 0, i32 1) ;; It is perfectly legal to relocate the same value multiple times... - %reloc2 = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 7, i32 8) - %reloc3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token, i32 8, i32 7) + %reloc2 = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 0, i32 1) + %reloc3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token, i32 1, i32 0) ret i64 addrspace(1)* %reloc ; CHECK-LABEL: test1 ; CHECK: statepoint @@ -40,8 +40,8 @@ notequal: ret void equal: - %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg) ["deopt" (i32 0, i32 0, i32 0, i32 10, i32 0)] - %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 7, i32 7) + %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg), "deopt" (i32 0, i32 0, i32 0, i32 10, i32 0)] + %reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 0, i32 0) call void undef(i64 addrspace(1)* %reloc) ret void ; CHECK-LABEL: test2 @@ -58,7 +58,7 @@ define i8 addrspace(1)* @test3(i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1) gc entry: ; CHECK-LABEL: entry ; CHECK: statepoint - %0 = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1) ["deopt" (i32 0, i32 -1, i32 0, i32 0, i32 0)] + %0 = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1), "deopt" (i32 0, i32 -1, i32 0, i32 0, i32 0)] to label %normal_dest unwind label %exceptional_return normal_dest: @@ -66,8 +66,8 @@ normal_dest: ; CHECK: gc.relocate ; CHECK: gc.relocate ; CHECK: ret - %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 7, i32 7) - %obj1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 8, i32 8) + %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 0, i32 0) + %obj1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 1, i32 1) ret i8 addrspace(1)* %obj.relocated exceptional_return: @@ -76,8 +76,8 @@ exceptional_return: ; CHECK: gc.relocate %landing_pad = landingpad token cleanup - %obj.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %landing_pad, i32 7, i32 7) - %obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %landing_pad, i32 8, i32 8) + %obj.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %landing_pad, i32 0, i32 0) + %obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %landing_pad, i32 1, i32 1) ret i8 addrspace(1)* %obj1.relocated1 }