Home | History | Annotate | Download | only in JumpThreading
      1 ; RUN: opt < %s -jump-threading -S | FileCheck %s
      2 ; RUN: opt < %s -passes=jump-threading -S | FileCheck %s
      3 
      4 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
      5 target triple = "i386-apple-darwin7"
      6 
      7 ; Test that we can thread through the block with the partially redundant load (%2).
      8 ; rdar://6402033
      9 define i32 @test1(i32* %P) nounwind {
     10 ; CHECK-LABEL: @test1(
     11 entry:
     12 	%0 = tail call i32 (...) @f1() nounwind		; <i32> [#uses=1]
     13 	%1 = icmp eq i32 %0, 0		; <i1> [#uses=1]
     14 	br i1 %1, label %bb1, label %bb
     15 
     16 bb:		; preds = %entry
     17 ; CHECK: bb1.thread:
     18 ; CHECK: store
     19 ; CHECK: br label %bb3
     20 	store i32 42, i32* %P, align 4
     21 	br label %bb1
     22 
     23 bb1:		; preds = %entry, %bb
     24 	%res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]		; <i32> [#uses=2]
     25 	%2 = load i32, i32* %P, align 4		; <i32> [#uses=1]
     26 	%3 = icmp sgt i32 %2, 36		; <i1> [#uses=1]
     27 	br i1 %3, label %bb3, label %bb2
     28 
     29 bb2:		; preds = %bb1
     30 	%4 = tail call i32 (...) @f2() nounwind		; <i32> [#uses=0]
     31 	ret i32 %res.0
     32 
     33 bb3:		; preds = %bb1
     34 ; CHECK: bb3:
     35 ; CHECK: %res.01 = phi i32 [ 1, %bb1.thread ], [ 0, %bb1 ]
     36 ; CHECK: ret i32 %res.01
     37 	ret i32 %res.0
     38 }
     39 
     40 declare i32 @f1(...)
     41 
     42 declare i32 @f2(...)
     43 
     44 
     45 ;; Check that we preserve TBAA information.
     46 ; rdar://11039258
     47 
     48 define i32 @test2(i32* %P) nounwind {
     49 ; CHECK-LABEL: @test2(
     50 entry:
     51 	%0 = tail call i32 (...) @f1() nounwind		; <i32> [#uses=1]
     52 	%1 = icmp eq i32 %0, 0		; <i1> [#uses=1]
     53 	br i1 %1, label %bb1, label %bb
     54 
     55 bb:		; preds = %entry
     56 ; CHECK: bb1.thread:
     57 ; CHECK: store{{.*}}, !tbaa !0
     58 ; CHECK: br label %bb3
     59 	store i32 42, i32* %P, align 4, !tbaa !0
     60 	br label %bb1
     61 
     62 bb1:		; preds = %entry, %bb
     63 	%res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
     64 	%2 = load i32, i32* %P, align 4, !tbaa !0
     65 	%3 = icmp sgt i32 %2, 36
     66 	br i1 %3, label %bb3, label %bb2
     67 
     68 bb2:		; preds = %bb1
     69 	%4 = tail call i32 (...) @f2() nounwind
     70 	ret i32 %res.0
     71 
     72 bb3:		; preds = %bb1
     73 ; CHECK: bb3:
     74 ; CHECK: %res.01 = phi i32 [ 1, %bb1.thread ], [ 0, %bb1 ]
     75 ; CHECK: ret i32 %res.01
     76 	ret i32 %res.0
     77 }
     78 
     79 define i32 @test3(i8** %x, i1 %f) {
     80 ; Correctly thread loads of different (but compatible) types, placing bitcasts
     81 ; as necessary in the predecessors. This is especially tricky because the same
     82 ; predecessor ends up with two entries in the PHI node and they must share
     83 ; a single cast.
     84 ; CHECK-LABEL: @test3(
     85 entry:
     86   %0 = bitcast i8** %x to i32**
     87   %1 = load i32*, i32** %0, align 8
     88   br i1 %f, label %if.end57, label %if.then56
     89 ; CHECK: %[[LOAD:.*]] = load i32*, i32**
     90 ; CHECK: %[[CAST:.*]] = bitcast i32* %[[LOAD]] to i8*
     91 
     92 if.then56:
     93   br label %if.end57
     94 
     95 if.end57:
     96   %2 = load i8*, i8** %x, align 8
     97   %tobool59 = icmp eq i8* %2, null
     98   br i1 %tobool59, label %return, label %if.then60
     99 ; CHECK: %[[PHI:.*]] = phi i8* [ %[[CAST]], %[[PRED:[^ ]+]] ], [ %[[CAST]], %[[PRED]] ]
    100 ; CHECK-NEXT: %[[CMP:.*]] = icmp eq i8* %[[PHI]], null
    101 ; CHECK-NEXT: br i1 %[[CMP]]
    102 
    103 if.then60:
    104   ret i32 42
    105 
    106 return:
    107   ret i32 13
    108 }
    109 
    110 define i32 @test4(i32* %P) {
    111 ; CHECK-LABEL: @test4(
    112 entry:
    113   %v0 = tail call i32 (...) @f1()
    114   %v1 = icmp eq i32 %v0, 0
    115   br i1 %v1, label %bb1, label %bb
    116 
    117 bb:
    118 ; CHECK: bb1.thread:
    119 ; CHECK: store atomic
    120 ; CHECK: br label %bb3
    121   store atomic i32 42, i32* %P unordered, align 4
    122   br label %bb1
    123 
    124 bb1:
    125 ; CHECK: bb1:
    126 ; CHECK-NOT: phi
    127 ; CHECK: load atomic
    128   %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
    129   %v2 = load atomic i32, i32* %P unordered, align 4
    130   %v3 = icmp sgt i32 %v2, 36
    131   br i1 %v3, label %bb3, label %bb2
    132 
    133 bb2:
    134   %v4 = tail call i32 (...) @f2()
    135   ret i32 %res.0
    136 
    137 bb3:
    138   ret i32 %res.0
    139 }
    140 
    141 define i32 @test5(i32* %P) {
    142 ; Negative test
    143 
    144 ; CHECK-LABEL: @test5(
    145 entry:
    146   %v0 = tail call i32 (...) @f1()
    147   %v1 = icmp eq i32 %v0, 0
    148   br i1 %v1, label %bb1, label %bb
    149 
    150 bb:
    151 ; CHECK: bb:
    152 ; CHECK-NEXT:   store atomic i32 42, i32* %P release, align 4
    153 ; CHECK-NEXT:   br label %bb1
    154   store atomic i32 42, i32* %P release, align 4
    155   br label %bb1
    156 
    157 bb1:
    158 ; CHECK: bb1:
    159 ; CHECK-NEXT:  %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
    160 ; CHECK-NEXT:  %v2 = load atomic i32, i32* %P acquire, align 4
    161 ; CHECK-NEXT:  %v3 = icmp sgt i32 %v2, 36
    162 ; CHECK-NEXT:  br i1 %v3, label %bb3, label %bb2
    163 
    164   %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
    165   %v2 = load atomic i32, i32* %P acquire, align 4
    166   %v3 = icmp sgt i32 %v2, 36
    167   br i1 %v3, label %bb3, label %bb2
    168 
    169 bb2:
    170   %v4 = tail call i32 (...) @f2()
    171   ret i32 %res.0
    172 
    173 bb3:
    174   ret i32 %res.0
    175 }
    176 
    177 define i32 @test6(i32* %P) {
    178 ; Negative test
    179 
    180 ; CHECK-LABEL: @test6(
    181 entry:
    182   %v0 = tail call i32 (...) @f1()
    183   %v1 = icmp eq i32 %v0, 0
    184   br i1 %v1, label %bb1, label %bb
    185 
    186 bb:
    187 ; CHECK: bb:
    188 ; CHECK-NEXT:   store i32 42, i32* %P
    189 ; CHECK-NEXT:   br label %bb1
    190   store i32 42, i32* %P
    191   br label %bb1
    192 
    193 bb1:
    194 ; CHECK: bb1:
    195 ; CHECK-NEXT:  %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
    196 ; CHECK-NEXT:  %v2 = load atomic i32, i32* %P acquire, align 4
    197 ; CHECK-NEXT:  %v3 = icmp sgt i32 %v2, 36
    198 ; CHECK-NEXT:  br i1 %v3, label %bb3, label %bb2
    199 
    200   %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
    201   %v2 = load atomic i32, i32* %P acquire, align 4
    202   %v3 = icmp sgt i32 %v2, 36
    203   br i1 %v3, label %bb3, label %bb2
    204 
    205 bb2:
    206   %v4 = tail call i32 (...) @f2()
    207   ret i32 %res.0
    208 
    209 bb3:
    210   ret i32 %res.0
    211 }
    212 
    213 define i32 @test7(i32* %P) {
    214 ; Negative test
    215 
    216 ; CHECK-LABEL: @test7(
    217 entry:
    218   %v0 = tail call i32 (...) @f1()
    219   %v1 = icmp eq i32 %v0, 0
    220   br i1 %v1, label %bb1, label %bb
    221 
    222 bb:
    223 ; CHECK: bb:
    224 ; CHECK-NEXT:   %val = load i32, i32* %P
    225 ; CHECK-NEXT:   br label %bb1
    226   %val = load i32, i32* %P
    227   br label %bb1
    228 
    229 bb1:
    230 ; CHECK: bb1:
    231 ; CHECK-NEXT:  %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
    232 ; CHECK-NEXT:  %v2 = load atomic i32, i32* %P acquire, align 4
    233 ; CHECK-NEXT:  %v3 = icmp sgt i32 %v2, 36
    234 ; CHECK-NEXT:  br i1 %v3, label %bb3, label %bb2
    235 
    236   %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
    237   %v2 = load atomic i32, i32* %P acquire, align 4
    238   %v3 = icmp sgt i32 %v2, 36
    239   br i1 %v3, label %bb3, label %bb2
    240 
    241 bb2:
    242   %v4 = tail call i32 (...) @f2()
    243   ret i32 %res.0
    244 
    245 bb3:
    246   ret i32 %res.0
    247 }
    248 
    249 !0 = !{!3, !3, i64 0}
    250 !1 = !{!"omnipotent char", !2}
    251 !2 = !{!"Simple C/C++ TBAA", null}
    252 !3 = !{!"int", !1}
    253