[win/asan] GetInstructionSize: Fix `83 E4 XX` to return 3. (#119644)
[llvm-project.git] / llvm / test / Transforms / SCCP / conditions-ranges-with-undef.ll
blob8b4dea462757e55754f39764a833751b20def38e
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=ipsccp -S | FileCheck %s
4 declare void @use(i1)
6 ; We can simplify the conditions in the true block, because the condition
7 ; allows us to replace all uses of %a in the block with a  constant.
8 define void @val_undef_eq() {
9 ; CHECK-LABEL: @val_undef_eq(
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    [[A:%.*]] = add nuw nsw i32 undef, 0
12 ; CHECK-NEXT:    [[BC_1:%.*]] = icmp eq i32 [[A]], 10
13 ; CHECK-NEXT:    br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
14 ; CHECK:       true:
15 ; CHECK-NEXT:    call void @use(i1 false)
16 ; CHECK-NEXT:    call void @use(i1 true)
17 ; CHECK-NEXT:    ret void
18 ; CHECK:       false:
19 ; CHECK-NEXT:    ret void
21 entry:
22   %a = add i32 undef, 0
23   %bc.1 = icmp eq i32 %a, 10
24   br i1 %bc.1, label %true, label %false
26 true:
27   %f.1 = icmp ne i32 %a, 10
28   call void @use(i1 %f.1)
29   %f.2 = icmp eq i32 %a,  10
30   call void @use(i1 %f.2)
31   ret void
33 false:
34   ret void
37 declare void @use.i32(i32)
39 ; It is not allowed to use the range information from the condition to remove
40 ; %a.127 = and ... in the true block, as %a could be undef.
41 define void @val_undef_range() {
42 ; CHECK-LABEL: @val_undef_range(
43 ; CHECK-NEXT:  entry:
44 ; CHECK-NEXT:    [[A:%.*]] = add nuw nsw i32 undef, 0
45 ; CHECK-NEXT:    [[BC_1:%.*]] = icmp ult i32 [[A]], 127
46 ; CHECK-NEXT:    br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
47 ; CHECK:       true:
48 ; CHECK-NEXT:    call void @use(i1 false)
49 ; CHECK-NEXT:    [[A_127:%.*]] = and i32 [[A]], 127
50 ; CHECK-NEXT:    call void @use.i32(i32 [[A_127]])
51 ; CHECK-NEXT:    ret void
52 ; CHECK:       false:
53 ; CHECK-NEXT:    ret void
55 entry:
56   %a = add i32 undef, 0
57   %bc.1 = icmp ult i32 %a, 127
58   br i1 %bc.1, label %true, label %false
60 true:
61   %f.1 = icmp eq i32 %a, 128
62   call void @use(i1 %f.1)
64   %a.127 = and i32 %a, 127
65   call void @use.i32(i32 %a.127)
66   ret void
68 false:
69   ret void
72 ; All uses of %p can be replaced by a constant (10).
73 define void @val_singlecrfromundef_range(i1 %cond) {
74 ; CHECK-LABEL: @val_singlecrfromundef_range(
75 ; CHECK-NEXT:  entry:
76 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[INC1:%.*]], label [[INC2:%.*]]
77 ; CHECK:       inc1:
78 ; CHECK-NEXT:    br label [[IF:%.*]]
79 ; CHECK:       inc2:
80 ; CHECK-NEXT:    br label [[IF]]
81 ; CHECK:       if:
82 ; CHECK-NEXT:    br label [[TRUE:%.*]]
83 ; CHECK:       true:
84 ; CHECK-NEXT:    call void @use(i1 false)
85 ; CHECK-NEXT:    [[P_127:%.*]] = and i32 10, 127
86 ; CHECK-NEXT:    call void @use.i32(i32 [[P_127]])
87 ; CHECK-NEXT:    ret void
89 entry:
91   br i1 %cond, label %inc1, label %inc2
93 inc1:
94   br label %if
96 inc2:
97   br label %if
99 if:
100   %p = phi i32 [ 10, %inc1 ], [ undef, %inc2 ]
101   %bc.1 = icmp ult i32 %p, 127
102   br i1 %bc.1, label %true, label %false
104 true:
105   %f.1 = icmp eq i32 %p, 128
106   call void @use(i1 %f.1)
108   %p.127 = and i32 %p, 127
109   call void @use.i32(i32 %p.127)
110   ret void
112 false:
113   ret void
117 ; It is not allowed to use the information from the condition ([0, 128))
118 ; to remove a.127.2 = and i32 %p, 127, as %p might be undef.
119 define void @val_undef_to_cr_to_overdef_range(i32 %a, i1 %cond) {
120 ; CHECK-LABEL: @val_undef_to_cr_to_overdef_range(
121 ; CHECK-NEXT:  entry:
122 ; CHECK-NEXT:    [[A_127:%.*]] = and i32 [[A:%.*]], 127
123 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[INC1:%.*]], label [[INC2:%.*]]
124 ; CHECK:       inc1:
125 ; CHECK-NEXT:    br label [[IF:%.*]]
126 ; CHECK:       inc2:
127 ; CHECK-NEXT:    br label [[IF]]
128 ; CHECK:       if:
129 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[A_127]], [[INC1]] ], [ undef, [[INC2]] ]
130 ; CHECK-NEXT:    [[BC_1:%.*]] = icmp ult i32 [[P]], 100
131 ; CHECK-NEXT:    br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
132 ; CHECK:       true:
133 ; CHECK-NEXT:    call void @use(i1 false)
134 ; CHECK-NEXT:    [[P_127:%.*]] = and i32 [[P]], 127
135 ; CHECK-NEXT:    call void @use.i32(i32 [[P_127]])
136 ; CHECK-NEXT:    ret void
137 ; CHECK:       false:
138 ; CHECK-NEXT:    ret void
140 entry:
141   %a.127 = and i32 %a, 127
142   br i1 %cond, label %inc1, label %inc2
144 inc1:
145   br label %if
147 inc2:
148   br label %if
151   %p = phi i32 [ %a.127, %inc1 ], [ undef, %inc2 ]
152   %bc.1 = icmp ult i32 %p, 100
153   br i1 %bc.1, label %true, label %false
155 true:
156   %f.1 = icmp eq i32 %p, 128
157   call void @use(i1 %f.1)
159   %p.127 = and i32 %p, 127
160   call void @use.i32(i32 %p.127)
161   ret void
163 false:
164   ret void
167 ; All uses of %p can be replaced by a constant (10), we are allowed to use it
168 ; as a bound too.
169 define void @bound_singlecrfromundef(i32 %a, i1 %cond) {
170 ; CHECK-LABEL: @bound_singlecrfromundef(
171 ; CHECK-NEXT:  entry:
172 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
173 ; CHECK:       bb1:
174 ; CHECK-NEXT:    br label [[PRED:%.*]]
175 ; CHECK:       bb2:
176 ; CHECK-NEXT:    br label [[PRED]]
177 ; CHECK:       pred:
178 ; CHECK-NEXT:    [[BC_1:%.*]] = icmp ugt i32 [[A:%.*]], 10
179 ; CHECK-NEXT:    br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
180 ; CHECK:       true:
181 ; CHECK-NEXT:    call void @use(i1 false)
182 ; CHECK-NEXT:    call void @use(i1 true)
183 ; CHECK-NEXT:    [[A_127:%.*]] = and i32 [[A]], 127
184 ; CHECK-NEXT:    call void @use.i32(i32 [[A_127]])
185 ; CHECK-NEXT:    ret void
186 ; CHECK:       false:
187 ; CHECK-NEXT:    ret void
189 entry:
190   br i1 %cond, label %bb1, label %bb2
192 bb1:
193   br label %pred
195 bb2:
196   br label %pred
198 pred:
199   %p = phi i32 [ undef, %bb1 ], [ 10, %bb2 ]
200   %bc.1 = icmp ugt i32 %a, %p
201   br i1 %bc.1, label %true, label %false
203 true:
204   %f.1 = icmp eq i32 %a, 5
205   call void @use(i1 %f.1)
207   %t.1 = icmp ne i32 %a,  5
208   call void @use(i1 %t.1)
210   %a.127 = and i32 %a, 127
211   call void @use.i32(i32 %a.127)
213   ret void
215 false:
216   ret void
219 ; It is not allowed to use the information from %p as a bound, because an
220 ; incoming value is undef.
221 define void @bound_range_and_undef(i32 %a, i1 %cond) {
222 ; CHECK-LABEL: @bound_range_and_undef(
223 ; CHECK-NEXT:  entry:
224 ; CHECK-NEXT:    [[A_10:%.*]] = and i32 [[A:%.*]], 127
225 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
226 ; CHECK:       bb1:
227 ; CHECK-NEXT:    br label [[PRED:%.*]]
228 ; CHECK:       bb2:
229 ; CHECK-NEXT:    br label [[PRED]]
230 ; CHECK:       pred:
231 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[A_10]], [[BB1]] ], [ undef, [[BB2]] ]
232 ; CHECK-NEXT:    [[BC_1:%.*]] = icmp ugt i32 [[A]], [[P]]
233 ; CHECK-NEXT:    br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
234 ; CHECK:       true:
235 ; CHECK-NEXT:    [[F_1:%.*]] = icmp eq i32 [[A]], 300
236 ; CHECK-NEXT:    call void @use(i1 [[F_1]])
237 ; CHECK-NEXT:    [[A_127_2:%.*]] = and i32 [[P]], 127
238 ; CHECK-NEXT:    call void @use.i32(i32 [[A_127_2]])
239 ; CHECK-NEXT:    ret void
240 ; CHECK:       false:
241 ; CHECK-NEXT:    ret void
243 entry:
244   %a.10 = and i32 %a, 127
245   br i1 %cond, label %bb1, label %bb2
247 bb1:
248   br label %pred
250 bb2:
251   br label %pred
253 pred:
254   %p = phi i32 [ %a.10, %bb1 ], [ undef, %bb2 ]
255   %bc.1 = icmp ugt i32 %a, %p
256   br i1 %bc.1, label %true, label %false
258 true:
259   %f.1 = icmp eq i32 %a, 300
260   call void @use(i1 %f.1)
262   %a.127.2 = and i32 %p, 127
263   call void @use.i32(i32 %a.127.2)
265   ret void
267 false:
268   ret void