Home | History | Annotate | Download | only in Util
      1 ; RUN: opt -S -strip-gc-relocates -instcombine < %s | FileCheck %s
      2 ; test utility/debugging pass which removes gc.relocates, inserted by -rewrite-statepoints-for-gc
      3 declare void @use_obj32(i32 addrspace(1)*) "gc-leaf-function"
      4 
      5 declare void @g()
      6 declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
      7 declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32) #0
      8 declare void @do_safepoint()
      9 
     10 declare i32 addrspace(1)* @new_instance() #1
     11 
     12 
     13 ; Simple case: remove gc.relocate
     14 define i32 addrspace(1)* @test1(i32 addrspace(1)* %arg) gc "statepoint-example" {
     15 entry:
     16 ; CHECK-LABEL: test1
     17 ; CHECK: gc.statepoint
     18 ; CHECK-NOT: gc.relocate
     19 ; CHECK: ret i32 addrspace(1)* %arg
     20   %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)
     21   %arg.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 8) ; (%arg, %arg)
     22   %arg.relocated.casted = bitcast i8 addrspace(1)* %arg.relocated to i32 addrspace(1)*
     23   ret i32 addrspace(1)* %arg.relocated.casted
     24 }
     25 
     26 ; Remove gc.relocates in presence of nested relocates.
     27 define void @test2(i32 addrspace(1)* %base) gc "statepoint-example" {
     28 entry:
     29 ; CHECK-LABEL: test2
     30 ; CHECK: statepoint
     31 ; CHECK-NOT: gc.relocate
     32 ; CHECK: call void @use_obj32(i32 addrspace(1)* %ptr.gep1)
     33 ; CHECK: call void @use_obj32(i32 addrspace(1)* %ptr.gep1)
     34   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
     35   %ptr.gep1 = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 15
     36   %statepoint_token = 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.gep1, i32 addrspace(1)* %base)
     37   %ptr.gep1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 7) ; (%base, %ptr.gep1)
     38   %ptr.gep1.relocated.casted = bitcast i8 addrspace(1)* %ptr.gep1.relocated to i32 addrspace(1)*
     39   %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 8) ; (%base, %base)
     40   %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
     41   call void @use_obj32(i32 addrspace(1)* %ptr.gep1.relocated.casted)
     42   %statepoint_token1 = 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.gep1.relocated.casted, i32 addrspace(1)* %base.relocated.casted)
     43   %ptr.gep1.relocated2 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token1, i32 8, i32 7) ; (%base.relocated.casted, %ptr.gep1.relocated.casted)
     44   %ptr.gep1.relocated2.casted = bitcast i8 addrspace(1)* %ptr.gep1.relocated2 to i32 addrspace(1)*
     45   %base.relocated3 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token1, i32 8, i32 8) ; (%base.relocated.casted, %base.relocated.casted)
     46   %base.relocated3.casted = bitcast i8 addrspace(1)* %base.relocated3 to i32 addrspace(1)*
     47   call void @use_obj32(i32 addrspace(1)* %ptr.gep1.relocated2.casted)
     48   ret void
     49 }
     50 
     51 ; landing pad gc.relocates removed by instcombine since it has no uses.
     52 define i32 addrspace(1)* @test3(i32 addrspace(1)* %arg) gc "statepoint-example" personality i32 8 {
     53 ; CHECK-LABEL: test3(
     54 ; CHECK: gc.statepoint
     55 ; CHECK-LABEL: normal_dest:
     56 ; CHECK-NOT: gc.relocate
     57 ; CHECK: ret i32 addrspace(1)* %arg
     58 ; CHECK-LABEL: unwind_dest:
     59 ; CHECK-NOT: gc.relocate
     60 entry:
     61   %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)
     62           to label %normal_dest unwind label %unwind_dest
     63 
     64 normal_dest:                                      ; preds = %entry
     65   %arg.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 8) ; (%arg, %arg)
     66   %arg.relocated1.casted = bitcast i8 addrspace(1)* %arg.relocated1 to i32 addrspace(1)*
     67   ret i32 addrspace(1)* %arg.relocated1.casted
     68 
     69 unwind_dest:                                      ; preds = %entry
     70   %lpad = landingpad token
     71           cleanup
     72   %arg.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %lpad, i32 8, i32 8) ; (%arg, %arg)
     73   %arg.relocated.casted = bitcast i8 addrspace(1)* %arg.relocated to i32 addrspace(1)*
     74   resume token undef
     75 }
     76 
     77 ; in presence of phi
     78 define void @test4(i1 %cond) gc "statepoint-example" {
     79 ; CHECK-LABEL: test4
     80 entry:
     81   %base1 = call i32 addrspace(1)* @new_instance()
     82   %base2 = call i32 addrspace(1)* @new_instance()
     83   br i1 %cond, label %here, label %there
     84 
     85 here:                                             ; preds = %entry
     86   br label %merge
     87 
     88 there:                                            ; preds = %entry
     89   br label %merge
     90 
     91 merge:                                            ; preds = %there, %here
     92 ; CHECK-LABEL: merge:
     93 ; CHECK-NOT: gc.relocate
     94 ; CHECK: %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi.base
     95   %basephi.base = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ], !is_base_value !0
     96   %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ]
     97   %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15
     98   %statepoint_token = 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)* %basephi.base)
     99   %basephi.base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7) ; (%basephi.base, %basephi.base)
    100   %basephi.base.relocated.casted = bitcast i8 addrspace(1)* %basephi.base.relocated to i32 addrspace(1)*
    101   %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15
    102   call void @use_obj32(i32 addrspace(1)* %ptr.gep.remat)
    103   ret void
    104 }
    105 
    106 ; The gc.relocate type is different from %arg, but removing the gc.relocate,
    107 ; needs a bitcast to be added from i32 addrspace(1)* to i8 addrspace(1)*
    108 define i8 addrspace(1)* @test5(i32 addrspace(1)* %arg) gc "statepoint-example" {
    109 entry:
    110 ; CHECK-LABEL: test5
    111 ; CHECK: gc.statepoint
    112 ; CHECK-NOT: gc.relocate
    113   %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)
    114   %arg.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 8) ; (%arg, %arg)
    115   ret i8 addrspace(1)* %arg.relocated
    116 }
    117 
    118 attributes #0 = { nounwind readonly }
    119 attributes #1 = { nounwind "gc-leaf-function" }
    120 !0 = !{}
    121