llvm.org GIT mirror llvm / fd98b34
[FastISel][SelectionDAG]Teach fastISel about GC intrinsics Summary: We are crashing in LLC at O0 when gc intrinsics are present in the block. The reason being FastISel performs basic block ISel by modifying GC.relocates to be the first instruction in the block. This can cause us to visit the GC relocate before it's corresponding GC.statepoint is visited, which is incorrect. When we lower the statepoint, we record the base and derived pointers, along with the gc.relocates. After this we can visit the gc.relocate. This patch avoids fastISel from incorrectly creating the block with gc.relocate as the first instruction. Reviewers: qcolombet, skatkov, qikon, reames Reviewed by: skatkov Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D34421 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307084 91177308-0d34-0410-b5e6-96231b3b80d8 Anna Thomas 3 years ago
2 changed file(s) with 60 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
15061506 }
15071507
15081508 // Then handle certain instructions as single-LLVM-Instruction blocks.
1509 if (isa(Inst)) {
1509 // We cannot separate out GCrelocates to their own blocks since we need
1510 // to keep track of gc-relocates for a particular gc-statepoint. This is
1511 // done by SelectionDAGBuilder::LowerAsSTATEPOINT, called before
1512 // visitGCRelocate.
1513 if (isa(Inst) && !isStatepoint(Inst) && !isGCRelocate(Inst)) {
15101514 OptimizationRemarkMissed R("sdagisel", "FastISelFailure",
15111515 Inst->getDebugLoc(), LLVMBB);
15121516
0 ; RUN: llc < %s -fast-isel
1
2 ; Dont crash with gc intrinsics.
3
4 ; gcrelocate call should not be an LLVM Machine Block by itself.
5 define i8 addrspace(1)* @test_gcrelocate(i8 addrspace(1)* %v) gc "statepoint-example" {
6 entry:
7 %tok = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %v)
8 %vnew = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %tok, i32 7, i32 7)
9 ret i8 addrspace(1)* %vnew
10 }
11
12 ; gcresult calls are fine in their own blocks.
13 define i1 @test_gcresult() gc "statepoint-example" {
14 entry:
15 %safepoint_token = tail 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)
16 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
17 ret i1 %call1
18 }
19
20 ; we are okay here because we see the gcrelocate and avoid generating their own
21 ; block.
22 define i1 @test_gcresult_gcrelocate(i8 addrspace(1)* %v) gc "statepoint-example" {
23 entry:
24 %safepoint_token = tail 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, i8 addrspace(1)* %v)
25 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
26 %vnew = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token, i32 7, i32 7)
27 ret i1 %call1
28 }
29
30 define i8 addrspace(1)* @test_non_entry_block(i8 addrspace(1)* %v, i8 %val) gc "statepoint-example" {
31 entry:
32 %load = load i8, i8 addrspace(1)* %v
33 %cmp = icmp eq i8 %load, %val
34 br i1 %cmp, label %func_call, label %exit
35
36 func_call:
37 call void @dummy()
38 %tok = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %v)
39 %vnew = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %tok, i32 7, i32 7)
40 ret i8 addrspace(1)* %vnew
41
42 exit:
43 ret i8 addrspace(1)* %v
44
45 }
46
47 declare void @dummy()
48 declare void @foo()
49
50 declare zeroext i1 @return_i1()
51 declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
52 declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
53 declare i1 @llvm.experimental.gc.result.i1(token)
54 declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32)