Home | History | Annotate | Download | only in RewriteStatepointsForGC
      1 ; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
      2 
      3 
      4 declare void @use_obj16(i16 addrspace(1)*) "gc-leaf-function"
      5 declare void @use_obj32(i32 addrspace(1)*) "gc-leaf-function"
      6 declare void @use_obj64(i64 addrspace(1)*) "gc-leaf-function"
      7 
      8 declare void @do_safepoint()
      9 
     10 define void @test_gep_const(i32 addrspace(1)* %base) gc "statepoint-example" {
     11 ; CHECK-LABEL: test_gep_const
     12 entry:
     13   %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15
     14 ; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15
     15   call void @do_safepoint() [ "deopt"() ]
     16 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7)
     17 ; CHECK: bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
     18 ; CHECK: getelementptr i32, i32 addrspace(1)* %base.relocated.casted, i32 15
     19   call void @use_obj32(i32 addrspace(1)* %base)
     20   call void @use_obj32(i32 addrspace(1)* %ptr)
     21   ret void
     22 }
     23 
     24 define void @test_gep_idx(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" {
     25 ; CHECK-LABEL: test_gep_idx
     26 entry:
     27   %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 %idx
     28 ; CHECK: getelementptr
     29   call void @do_safepoint() [ "deopt"() ]
     30 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7)
     31 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
     32 ; CHECK: getelementptr i32, i32 addrspace(1)* %base.relocated.casted, i32 %idx
     33   call void @use_obj32(i32 addrspace(1)* %base)
     34   call void @use_obj32(i32 addrspace(1)* %ptr)
     35   ret void
     36 }
     37 
     38 define void @test_bitcast(i32 addrspace(1)* %base) gc "statepoint-example" {
     39 ; CHECK-LABEL: test_bitcast
     40 entry:
     41   %ptr = bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
     42 ; CHECK: bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
     43   call void @do_safepoint() [ "deopt"() ]
     44 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7)
     45 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
     46 ; CHECK: bitcast i32 addrspace(1)* %base.relocated.casted to i64 addrspace(1)*
     47   call void @use_obj32(i32 addrspace(1)* %base)
     48   call void @use_obj64(i64 addrspace(1)* %ptr)
     49   ret void
     50 }
     51 
     52 define void @test_bitcast_bitcast(i32 addrspace(1)* %base) gc "statepoint-example" {
     53 ; CHECK-LABEL: test_bitcast_bitcast
     54 entry:
     55   %ptr1 = bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
     56   %ptr2 = bitcast i64 addrspace(1)* %ptr1 to i16 addrspace(1)*
     57 ; CHECK: bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
     58 ; CHECK: bitcast i64 addrspace(1)* %ptr1 to i16 addrspace(1)*
     59   call void @do_safepoint() [ "deopt"() ]
     60 
     61 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7)
     62 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
     63 ; CHECK: bitcast i32 addrspace(1)* %base.relocated.casted to i64 addrspace(1)*
     64 ; CHECK: bitcast i64 addrspace(1)* %ptr1.remat to i16 addrspace(1)*
     65   call void @use_obj32(i32 addrspace(1)* %base)
     66   call void @use_obj16(i16 addrspace(1)* %ptr2)
     67   ret void
     68 }
     69 
     70 define void @test_addrspacecast_addrspacecast(i32 addrspace(1)* %base) gc "statepoint-example" {
     71 ; CHECK-LABEL: test_addrspacecast_addrspacecast
     72 entry:
     73   %ptr1 = addrspacecast i32 addrspace(1)* %base to i32*
     74   %ptr2 = addrspacecast i32* %ptr1 to i32 addrspace(1)*
     75 ; CHECK: addrspacecast i32 addrspace(1)* %base to i32*
     76 ; CHECK: addrspacecast i32* %ptr1 to i32 addrspace(1)*
     77   call void @do_safepoint() [ "deopt"() ]
     78 
     79 ; CHECK: %ptr2.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 7)
     80 ; CHECK: %ptr2.relocated.casted = bitcast i8 addrspace(1)* %ptr2.relocated to i32 addrspace(1)*
     81 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 8)
     82 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
     83   call void @use_obj32(i32 addrspace(1)* %base)
     84   call void @use_obj32(i32 addrspace(1)* %ptr2)
     85   ret void
     86 }
     87 
     88 define void @test_bitcast_gep(i32 addrspace(1)* %base) gc "statepoint-example" {
     89 ; CHECK-LABEL: test_bitcast_gep
     90 entry:
     91   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
     92 ; CHECK: getelementptr
     93 ; CHECK: bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
     94   %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
     95   call void @do_safepoint() [ "deopt"() ]
     96 
     97 ; CHECK: gc.relocate
     98 ; CHECK: bitcast
     99 ; CHECK: getelementptr
    100 ; CHECK: bitcast
    101   call void @use_obj32(i32 addrspace(1)* %base)
    102   call void @use_obj64(i64 addrspace(1)* %ptr.cast)
    103   ret void
    104 }
    105 
    106 define void @test_intersecting_chains(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" {
    107 ; CHECK-LABEL: test_intersecting_chains
    108 entry:
    109   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
    110 ; CHECK: getelementptr
    111   %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
    112 ; CHECK: bitcast
    113   %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)*
    114 ; CHECK: bitcast
    115   call void @do_safepoint() [ "deopt"() ]
    116 
    117 ; CHECK: getelementptr
    118 ; CHECK: bitcast
    119 ; CHECK: getelementptr
    120 ; CHECK: bitcast
    121   call void @use_obj64(i64 addrspace(1)* %ptr.cast)
    122   call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
    123   ret void
    124 }
    125 
    126 define void @test_cost_threshold(i32 addrspace(1)* %base, i32 %idx1, i32 %idx2, i32 %idx3) gc "statepoint-example" {
    127 ; CHECK-LABEL: test_cost_threshold
    128 entry:
    129   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
    130 ; CHECK: getelementptr
    131   %ptr.gep2 = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 %idx1
    132 ; CHECK: getelementptr
    133   %ptr.gep3 = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 %idx2
    134 ; CHECK: getelementptr
    135   %ptr.gep4 = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 %idx3
    136 ; CHECK: getelementptr
    137   %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep4 to i64 addrspace(1)*
    138   call void @do_safepoint() [ "deopt"() ]
    139 
    140 ; CHECK: gc.relocate
    141 ; CHECK: bitcast
    142 ; CHECK: gc.relocate
    143 ; CHECK: bitcast
    144   call void @use_obj64(i64 addrspace(1)* %ptr.cast)
    145   ret void
    146 }
    147 
    148 define void @test_two_derived(i32 addrspace(1)* %base) gc "statepoint-example" {
    149 ; CHECK-LABEL: test_two_derived
    150 entry:
    151   %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15
    152   %ptr2 = getelementptr i32, i32 addrspace(1)* %base, i32 12
    153 ; CHECK: getelementptr
    154 ; CHECK: getelementptr
    155   call void @do_safepoint() [ "deopt"() ]
    156 
    157 ; CHECK: gc.relocate
    158 ; CHECK: bitcast
    159 ; CHECK: getelementptr
    160 ; CHECK: getelementptr
    161   call void @use_obj32(i32 addrspace(1)* %ptr)
    162   call void @use_obj32(i32 addrspace(1)* %ptr2)
    163   ret void
    164 }
    165 
    166 define void @test_gep_smallint_array([3 x i32] addrspace(1)* %base) gc "statepoint-example" {
    167 ; CHECK-LABEL: test_gep_smallint_array
    168 entry:
    169   %ptr = getelementptr [3 x i32], [3 x i32] addrspace(1)* %base, i32 0, i32 2
    170 ; CHECK: getelementptr
    171   call void @do_safepoint() [ "deopt"() ]
    172 
    173 ; CHECK: gc.relocate
    174 ; CHECK: bitcast
    175 ; CHECK: getelementptr
    176   call void @use_obj32(i32 addrspace(1)* %ptr)
    177   ret void
    178 }
    179 
    180 declare i32 @fake_personality_function()
    181 
    182 define void @test_invoke(i32 addrspace(1)* %base) gc "statepoint-example" personality i32 ()* @fake_personality_function {
    183 ; CHECK-LABEL: test_invoke
    184 entry:
    185   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
    186 ; CHECK: getelementptr
    187   %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
    188 ; CHECK: bitcast
    189   %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)*
    190 ; CHECK: bitcast
    191   invoke void @do_safepoint() [ "deopt"() ]
    192           to label %normal unwind label %exception
    193 
    194 normal:
    195 ; CHECK: normal:
    196 ; CHECK: gc.relocate
    197 ; CHECK: bitcast
    198 ; CHECK: getelementptr
    199 ; CHECK: bitcast
    200 ; CHECK: getelementptr
    201 ; CHECK: bitcast
    202   call void @use_obj64(i64 addrspace(1)* %ptr.cast)
    203   call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
    204   ret void
    205 
    206 exception:
    207 ; CHECK: exception:
    208   %landing_pad4 = landingpad token
    209           cleanup
    210 ; CHECK: gc.relocate
    211 ; CHECK: bitcast
    212 ; CHECK: getelementptr
    213 ; CHECK: bitcast
    214 ; CHECK: getelementptr
    215 ; CHECK: bitcast
    216   call void @use_obj64(i64 addrspace(1)* %ptr.cast)
    217   call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
    218   ret void
    219 }
    220 
    221 define void @test_loop(i32 addrspace(1)* %base) gc "statepoint-example" {
    222 ; CHECK-LABEL: test_loop
    223 entry:
    224   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
    225 ; CHECK: getelementptr
    226   br label %loop
    227 
    228 loop:                                             ; preds = %loop, %entry
    229 ; CHECK: phi i32 addrspace(1)* [ %ptr.gep, %entry ], [ %ptr.gep.remat, %loop ]
    230 ; CHECK: phi i32 addrspace(1)* [ %base, %entry ], [ %base.relocated.casted, %loop ]
    231   call void @use_obj32(i32 addrspace(1)* %ptr.gep)
    232   call void @do_safepoint() [ "deopt"() ]
    233 ; CHECK: gc.relocate
    234 ; CHECK: bitcast
    235 ; CHECK: getelementptr
    236   br label %loop
    237 }
    238 
    239 define void @test_too_long(i32 addrspace(1)* %base) gc "statepoint-example" {
    240 ; CHECK-LABEL: test_too_long
    241 entry:
    242   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
    243   %ptr.gep1 = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 15
    244   %ptr.gep2 = getelementptr i32, i32 addrspace(1)* %ptr.gep1, i32 15
    245   %ptr.gep3 = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 15
    246   %ptr.gep4 = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 15
    247   %ptr.gep5 = getelementptr i32, i32 addrspace(1)* %ptr.gep4, i32 15
    248   %ptr.gep6 = getelementptr i32, i32 addrspace(1)* %ptr.gep5, i32 15
    249   %ptr.gep7 = getelementptr i32, i32 addrspace(1)* %ptr.gep6, i32 15
    250   %ptr.gep8 = getelementptr i32, i32 addrspace(1)* %ptr.gep7, i32 15
    251   %ptr.gep9 = getelementptr i32, i32 addrspace(1)* %ptr.gep8, i32 15
    252   %ptr.gep10 = getelementptr i32, i32 addrspace(1)* %ptr.gep9, i32 15
    253   %ptr.gep11 = getelementptr i32, i32 addrspace(1)* %ptr.gep10, i32 15
    254   call void @do_safepoint() [ "deopt"() ]
    255 ; CHECK: gc.relocate
    256 ; CHECK: bitcast
    257 ; CHECK: gc.relocate
    258 ; CHECK: bitcast
    259   call void @use_obj32(i32 addrspace(1)* %ptr.gep11)
    260   ret void
    261 }
    262