[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / CorrelatedValuePropagation / icmp.ll
blob7f28dadeaeedb18a19e862c3a40bfb3ccafa8212
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -correlated-propagation -S %s | FileCheck %s
3 ; RUN: opt -passes=correlated-propagation -S %s | FileCheck %s
5 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
6 target triple = "x86_64-apple-macosx10.10.0"
8 declare void @check1(i1) #1
9 declare void @check2(i1) #1
11 ; Make sure we propagate the value of %tmp35 to the true/false cases
13 define void @test1(i64 %tmp35) {
14 ; CHECK-LABEL: @test1(
15 ; CHECK-NEXT:  bb:
16 ; CHECK-NEXT:    [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0
17 ; CHECK-NEXT:    br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]]
18 ; CHECK:       bb_true:
19 ; CHECK-NEXT:    tail call void @check1(i1 false) #0
20 ; CHECK-NEXT:    unreachable
21 ; CHECK:       bb_false:
22 ; CHECK-NEXT:    tail call void @check2(i1 true) #0
23 ; CHECK-NEXT:    unreachable
25 bb:
26   %tmp36 = icmp sgt i64 %tmp35, 0
27   br i1 %tmp36, label %bb_true, label %bb_false
29 bb_true:
30   %tmp47 = icmp slt i64 %tmp35, 0
31   tail call void @check1(i1 %tmp47) #4
32   unreachable
34 bb_false:
35   %tmp48 = icmp sle i64 %tmp35, 0
36   tail call void @check2(i1 %tmp48) #4
37   unreachable
40 ; This is the same as test1 but with a diamond to ensure we
41 ; get %tmp36 from both true and false BBs.
43 define void @test2(i64 %tmp35, i1 %inner_cmp) {
44 ; CHECK-LABEL: @test2(
45 ; CHECK-NEXT:  bb:
46 ; CHECK-NEXT:    [[TMP36:%.*]] = icmp sgt i64 [[TMP35:%.*]], 0
47 ; CHECK-NEXT:    br i1 [[TMP36]], label [[BB_TRUE:%.*]], label [[BB_FALSE:%.*]]
48 ; CHECK:       bb_true:
49 ; CHECK-NEXT:    br i1 [[INNER_CMP:%.*]], label [[INNER_TRUE:%.*]], label [[INNER_FALSE:%.*]]
50 ; CHECK:       inner_true:
51 ; CHECK-NEXT:    br label [[MERGE:%.*]]
52 ; CHECK:       inner_false:
53 ; CHECK-NEXT:    br label [[MERGE]]
54 ; CHECK:       merge:
55 ; CHECK-NEXT:    tail call void @check1(i1 false)
56 ; CHECK-NEXT:    unreachable
57 ; CHECK:       bb_false:
58 ; CHECK-NEXT:    tail call void @check2(i1 true) #0
59 ; CHECK-NEXT:    unreachable
61 bb:
62   %tmp36 = icmp sgt i64 %tmp35, 0
63   br i1 %tmp36, label %bb_true, label %bb_false
65 bb_true:
66   br i1 %inner_cmp, label %inner_true, label %inner_false
68 inner_true:
69   br label %merge
71 inner_false:
72   br label %merge
74 merge:
75   %tmp47 = icmp slt i64 %tmp35, 0
76   tail call void @check1(i1 %tmp47) #0
77   unreachable
79 bb_false:
80   %tmp48 = icmp sle i64 %tmp35, 0
81   tail call void @check2(i1 %tmp48) #4
82   unreachable
85 ; Make sure binary operator transfer functions are run when RHS is non-constant
87 define i1 @test3(i32 %x, i32 %y) #0 {
88 ; CHECK-LABEL: @test3(
89 ; CHECK-NEXT:  entry:
90 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
91 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
92 ; CHECK:       cont1:
93 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
94 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
95 ; CHECK:       cont2:
96 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]]
97 ; CHECK-NEXT:    br label [[CONT3:%.*]]
98 ; CHECK:       cont3:
99 ; CHECK-NEXT:    br label [[OUT]]
100 ; CHECK:       out:
101 ; CHECK-NEXT:    ret i1 true
103 entry:
104   %cmp1 = icmp ult i32 %x, 10
105   br i1 %cmp1, label %cont1, label %out
107 cont1:
108   %cmp2 = icmp ult i32 %y, 10
109   br i1 %cmp2, label %cont2, label %out
111 cont2:
112   %add = add i32 %x, %y
113   br label %cont3
115 cont3:
116   %cmp3 = icmp ult i32 %add, 25
117   br label %out
119 out:
120   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont3 ]
121   ret i1 %ret
124 ; Same as previous but make sure nobody gets over-zealous
126 define i1 @test4(i32 %x, i32 %y) #0 {
127 ; CHECK-LABEL: @test4(
128 ; CHECK-NEXT:  entry:
129 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 10
130 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
131 ; CHECK:       cont1:
132 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 10
133 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
134 ; CHECK:       cont2:
135 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[X]], [[Y]]
136 ; CHECK-NEXT:    br label [[CONT3:%.*]]
137 ; CHECK:       cont3:
138 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i32 [[ADD]], 15
139 ; CHECK-NEXT:    br label [[OUT]]
140 ; CHECK:       out:
141 ; CHECK-NEXT:    [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT3]] ]
142 ; CHECK-NEXT:    ret i1 [[RET]]
144 entry:
145   %cmp1 = icmp ult i32 %x, 10
146   br i1 %cmp1, label %cont1, label %out
148 cont1:
149   %cmp2 = icmp ult i32 %y, 10
150   br i1 %cmp2, label %cont2, label %out
152 cont2:
153   %add = add i32 %x, %y
154   br label %cont3
156 cont3:
157   %cmp3 = icmp ult i32 %add, 15
158   br label %out
160 out:
161   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont3 ]
162   ret i1 %ret
165 ; Make sure binary operator transfer functions are run when RHS is non-constant
167 define i1 @test5(i32 %x, i32 %y) #0 {
168 ; CHECK-LABEL: @test5(
169 ; CHECK-NEXT:  entry:
170 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5
171 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
172 ; CHECK:       cont1:
173 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 5
174 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
175 ; CHECK:       cont2:
176 ; CHECK-NEXT:    [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]]
177 ; CHECK-NEXT:    br label [[CONT3:%.*]]
178 ; CHECK:       cont3:
179 ; CHECK-NEXT:    br label [[OUT]]
180 ; CHECK:       out:
181 ; CHECK-NEXT:    ret i1 true
183 entry:
184   %cmp1 = icmp ult i32 %x, 5
185   br i1 %cmp1, label %cont1, label %out
187 cont1:
188   %cmp2 = icmp ult i32 %y, 5
189   br i1 %cmp2, label %cont2, label %out
191 cont2:
192   %shifted = shl i32 %x, %y
193   br label %cont3
195 cont3:
196   %cmp3 = icmp ult i32 %shifted, 65536
197   br label %out
199 out:
200   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont3 ]
201   ret i1 %ret
204 ; Same as previous but make sure nobody gets over-zealous
206 define i1 @test6(i32 %x, i32 %y) #0 {
207 ; CHECK-LABEL: @test6(
208 ; CHECK-NEXT:  entry:
209 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], 5
210 ; CHECK-NEXT:    br i1 [[CMP1]], label [[CONT1:%.*]], label [[OUT:%.*]]
211 ; CHECK:       cont1:
212 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], 15
213 ; CHECK-NEXT:    br i1 [[CMP2]], label [[CONT2:%.*]], label [[OUT]]
214 ; CHECK:       cont2:
215 ; CHECK-NEXT:    [[SHIFTED:%.*]] = shl nuw nsw i32 [[X]], [[Y]]
216 ; CHECK-NEXT:    br label [[CONT3:%.*]]
217 ; CHECK:       cont3:
218 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i32 [[SHIFTED]], 65536
219 ; CHECK-NEXT:    br label [[OUT]]
220 ; CHECK:       out:
221 ; CHECK-NEXT:    [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT3]] ]
222 ; CHECK-NEXT:    ret i1 [[RET]]
224 entry:
225   %cmp1 = icmp ult i32 %x, 5
226   br i1 %cmp1, label %cont1, label %out
228 cont1:
229   %cmp2 = icmp ult i32 %y, 15
230   br i1 %cmp2, label %cont2, label %out
232 cont2:
233   %shifted = shl i32 %x, %y
234   br label %cont3
236 cont3:
237   %cmp3 = icmp ult i32 %shifted, 65536
238   br label %out
240 out:
241   %ret = phi i1 [ true, %entry], [ true, %cont1 ], [ %cmp3, %cont3 ]
242   ret i1 %ret
245 attributes #4 = { noreturn }