diff --git a/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/lib/CodeGen/SelectionDAG/StatepointLowering.cpp index 9184a49c7eb..150dac34f05 100644 --- a/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ b/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -442,27 +442,25 @@ static void lowerStatepointMetaArgs(SmallVectorImpl &Ops, // heap. This is basically just here to help catch errors during statepoint // insertion. TODO: This should actually be in the Verifier, but we can't get // to the GCStrategy from there (yet). - if (Builder.GFI) { - GCStrategy &S = Builder.GFI->getStrategy(); - for (const Value *V : Bases) { - auto Opt = S.isGCManagedPointer(V); - if (Opt.hasValue()) { - assert(Opt.getValue() && - "non gc managed base pointer found in statepoint"); - } + GCStrategy &S = Builder.GFI->getStrategy(); + for (const Value *V : Bases) { + auto Opt = S.isGCManagedPointer(V); + if (Opt.hasValue()) { + assert(Opt.getValue() && + "non gc managed base pointer found in statepoint"); } - for (const Value *V : Ptrs) { - auto Opt = S.isGCManagedPointer(V); - if (Opt.hasValue()) { - assert(Opt.getValue() && - "non gc managed derived pointer found in statepoint"); - } + } + for (const Value *V : Ptrs) { + auto Opt = S.isGCManagedPointer(V); + if (Opt.hasValue()) { + assert(Opt.getValue() && + "non gc managed derived pointer found in statepoint"); } - for (const Value *V : Relocations) { - auto Opt = S.isGCManagedPointer(V); - if (Opt.hasValue()) { - assert(Opt.getValue() && "non gc managed pointer relocated"); - } + } + for (const Value *V : Relocations) { + auto Opt = S.isGCManagedPointer(V); + if (Opt.hasValue()) { + assert(Opt.getValue() && "non gc managed pointer relocated"); } } #endif @@ -581,10 +579,8 @@ SelectionDAGBuilder::LowerStatepoint(ImmutableStatepoint ISP, // TODO: This if should become an assert. For now, we allow the GCStrategy // to be optional for backwards compatibility. This will only last a short // period (i.e. a couple of weeks). - if (GFI) { - assert(GFI->getStrategy().useStatepoints() && - "GCStrategy does not expect to encounter statepoints"); - } + assert(GFI->getStrategy().useStatepoints() && + "GCStrategy does not expect to encounter statepoints"); #endif // Lower statepoint vmstate and gcstate arguments diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 248d1279eaf..bba24c39221 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -2926,6 +2926,8 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { case Intrinsic::experimental_gc_statepoint: Assert(!CI.isInlineAsm(), "gc.statepoint support for inline assembly unimplemented", &CI); + Assert(CI.getParent()->getParent()->hasGC(), + "Enclosing function does not use GC.", &CI); VerifyStatepoint(ImmutableCallSite(&CI)); break; @@ -2933,6 +2935,8 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { case Intrinsic::experimental_gc_result_float: case Intrinsic::experimental_gc_result_ptr: case Intrinsic::experimental_gc_result: { + Assert(CI.getParent()->getParent()->hasGC(), + "Enclosing function does not use GC.", &CI); // Are we tied to a statepoint properly? CallSite StatepointCS(CI.getArgOperand(0)); const Function *StatepointFn = diff --git a/test/Analysis/ValueTracking/memory-dereferenceable.ll b/test/Analysis/ValueTracking/memory-dereferenceable.ll index 51f92654921..76d302ae4c6 100644 --- a/test/Analysis/ValueTracking/memory-dereferenceable.ll +++ b/test/Analysis/ValueTracking/memory-dereferenceable.ll @@ -9,7 +9,7 @@ declare zeroext i1 @return_i1() @globalstr = global [6 x i8] c"hello\00" -define void @test(i32 addrspace(1)* dereferenceable(8) %dparam) { +define void @test(i32 addrspace(1)* dereferenceable(8) %dparam) gc "statepoint-example" { ; CHECK: The following are dereferenceable: ; CHECK: %globalptr ; CHECK: %alloca diff --git a/test/CodeGen/Generic/overloaded-intrinsic-name.ll b/test/CodeGen/Generic/overloaded-intrinsic-name.ll index aa6a031d8b7..722b5643269 100644 --- a/test/CodeGen/Generic/overloaded-intrinsic-name.ll +++ b/test/CodeGen/Generic/overloaded-intrinsic-name.ll @@ -12,28 +12,28 @@ ; will serve the purpose. ; function and integer -define i32* @test_iAny(i32* %v) { +define i32* @test_iAny(i32* %v) gc "statepoint-example" { %tok = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32* %v) %v-new = call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 4) ret i32* %v-new } ; float -define float* @test_fAny(float* %v) { +define float* @test_fAny(float* %v) gc "statepoint-example" { %tok = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, float* %v) %v-new = call float* @llvm.experimental.gc.relocate.p0f32(i32 %tok, i32 4, i32 4) ret float* %v-new } ; array of integers -define [3 x i32]* @test_aAny([3 x i32]* %v) { +define [3 x i32]* @test_aAny([3 x i32]* %v) gc "statepoint-example" { %tok = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, [3 x i32]* %v) %v-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32 %tok, i32 4, i32 4) ret [3 x i32]* %v-new } ; vector of integers -define <3 x i32>* @test_vAny(<3 x i32>* %v) { +define <3 x i32>* @test_vAny(<3 x i32>* %v) gc "statepoint-example" { %tok = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, <3 x i32>* %v) %v-new = call <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(i32 %tok, i32 4, i32 4) ret <3 x i32>* %v-new @@ -42,7 +42,7 @@ define <3 x i32>* @test_vAny(<3 x i32>* %v) { %struct.test = type { i32, i1 } ; struct -define %struct.test* @test_struct(%struct.test* %v) { +define %struct.test* @test_struct(%struct.test* %v) gc "statepoint-example" { %tok = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, %struct.test* %v) %v-new = call %struct.test* @llvm.experimental.gc.relocate.p0struct.test(i32 %tok, i32 4, i32 4) ret %struct.test* %v-new diff --git a/test/CodeGen/X86/statepoint-invoke.ll b/test/CodeGen/X86/statepoint-invoke.ll index 91bf46a2a20..177eb96e0d6 100644 --- a/test/CodeGen/X86/statepoint-invoke.ll +++ b/test/CodeGen/X86/statepoint-invoke.ll @@ -6,7 +6,9 @@ declare i64 addrspace(1)* @"some_other_call"(i64 addrspace(1)*) declare i32 @"personality_function"() -define i64 addrspace(1)* @test_result(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) { +define i64 addrspace(1)* @test_result(i64 addrspace(1)* %obj, + i64 addrspace(1)* %obj1) + gc "statepoint-example" { entry: ; CHECK: .Ltmp{{[0-9]+}}: ; CHECK: callq some_other_call diff --git a/test/CodeGen/X86/statepoint-stack-usage.ll b/test/CodeGen/X86/statepoint-stack-usage.ll index 3ecef3345ff..65343d121ce 100644 --- a/test/CodeGen/X86/statepoint-stack-usage.ll +++ b/test/CodeGen/X86/statepoint-stack-usage.ll @@ -8,7 +8,7 @@ target triple = "x86_64-pc-linux-gnu" ; of GC arguments differ, niave lowering code would insert loads and ; stores to rearrange items on the stack. We need to make sure (for ; performance) that this doesn't happen. -define i32 @back_to_back_calls(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) #1 { +define i32 @back_to_back_calls(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) #1 gc "statepoint-example" { ; CHECK-LABEL: back_to_back_calls ; The exact stores don't matter, but there need to be three stack slots created ; CHECK: movq %rdx, 16(%rsp) @@ -31,7 +31,7 @@ define i32 @back_to_back_calls(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 a ; This test simply checks that minor changes in vm state don't prevent slots ; being reused for gc values. -define i32 @reserve_first(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) #1 { +define i32 @reserve_first(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) #1 gc "statepoint-example" { ; CHECK-LABEL: reserve_first ; The exact stores don't matter, but there need to be three stack slots created ; CHECK: movq %rdx, 16(%rsp) diff --git a/test/Transforms/CodeGenPrepare/statepoint-relocate.ll b/test/Transforms/CodeGenPrepare/statepoint-relocate.ll index 7aa526fdc5e..cc6348af5c6 100644 --- a/test/Transforms/CodeGenPrepare/statepoint-relocate.ll +++ b/test/Transforms/CodeGenPrepare/statepoint-relocate.ll @@ -5,7 +5,7 @@ target triple = "x86_64-pc-linux-gnu" declare zeroext i1 @return_i1() -define i32 @test_sor_basic(i32* %base) { +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 entry: @@ -17,7 +17,7 @@ entry: ret i32 %ret } -define i32 @test_sor_two_derived(i32* %base) { +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 15 @@ -33,7 +33,7 @@ entry: ret i32 %ret } -define i32 @test_sor_ooo(i32* %base) { +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 entry: @@ -45,7 +45,7 @@ entry: ret i32 %ret } -define i32 @test_sor_gep_smallint([3 x i32]* %base) { +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 entry: @@ -57,7 +57,7 @@ entry: ret i32 %ret } -define i32 @test_sor_gep_largeint([3 x i32]* %base) { +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 entry: @@ -69,7 +69,7 @@ entry: ret i32 %ret } -define i32 @test_sor_noop(i32* %base) { +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(i32 %tok, i32 4, i32 5) ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(i32 %tok, i32 4, i32 6) diff --git a/test/Transforms/InstCombine/gc.relocate.ll b/test/Transforms/InstCombine/gc.relocate.ll index 4a7ea2c4234..d6a93e426a9 100644 --- a/test/Transforms/InstCombine/gc.relocate.ll +++ b/test/Transforms/InstCombine/gc.relocate.ll @@ -9,7 +9,7 @@ declare zeroext i1 @return_i1() declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...) declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) -define i32 addrspace(1)* @deref(i32 addrspace(1)* dereferenceable(8) %dparam) { +define i32 addrspace(1)* @deref(i32 addrspace(1)* dereferenceable(8) %dparam) gc "statepoint-example" { ; Checks that a dereferenceabler pointer ; CHECK-LABEL: @deref ; CHECK: call dereferenceable(8) @@ -18,4 +18,4 @@ entry: %tok = tail call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam) %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 4, i32 4) ret i32 addrspace(1)* %relocate -} \ No newline at end of file +} diff --git a/test/Transforms/InstCombine/statepoint.ll b/test/Transforms/InstCombine/statepoint.ll index bee219db9c1..11446fb512f 100644 --- a/test/Transforms/InstCombine/statepoint.ll +++ b/test/Transforms/InstCombine/statepoint.ll @@ -5,7 +5,7 @@ declare void @func() -define i1 @test_negative(i32 addrspace(1)* %p) { +define i1 @test_negative(i32 addrspace(1)* %p) gc "statepoint-example" { entry: %safepoint_token = tail call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 addrspace(1)* %p) %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 4, i32 4) @@ -16,7 +16,7 @@ entry: ; CHECK: ret i1 %cmp } -define i1 @test_nonnull(i32 addrspace(1)* nonnull %p) { +define i1 @test_nonnull(i32 addrspace(1)* nonnull %p) gc "statepoint-example" { entry: %safepoint_token = tail call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 addrspace(1)* %p) %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 4, i32 4) @@ -26,7 +26,7 @@ entry: ; CHECK: ret i1 false } -define i1 @test_null() { +define i1 @test_null() gc "statepoint-example" { entry: %safepoint_token = tail call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 addrspace(1)* null) %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 4, i32 4) @@ -37,7 +37,7 @@ entry: ; CHECK: ret i1 true } -define i1 @test_undef() { +define i1 @test_undef() gc "statepoint-example" { entry: %safepoint_token = tail call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @func, i32 0, i32 0, i32 0, i32 addrspace(1)* undef) %pnew = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 4, i32 4) diff --git a/test/Transforms/RewriteStatepointsForGC/basics.ll b/test/Transforms/RewriteStatepointsForGC/basics.ll index c1a1e4eba55..d8a57b67a5e 100644 --- a/test/Transforms/RewriteStatepointsForGC/basics.ll +++ b/test/Transforms/RewriteStatepointsForGC/basics.ll @@ -75,7 +75,7 @@ merge: } ; When run over a function which doesn't opt in, should do nothing! -define i8 addrspace(1)* @test5(i8 addrspace(1)* %obj) { +define i8 addrspace(1)* @test5(i8 addrspace(1)* %obj) gc "ocaml" { ; CHECK-LABEL: @test5 ; CHECK-LABEL: entry: ; CHECK-NEXT: gc.statepoint