1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=ipsccp -S | FileCheck %s
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(
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:%.*]]
15 ; CHECK-NEXT: call void @use(i1 false)
16 ; CHECK-NEXT: call void @use(i1 true)
17 ; CHECK-NEXT: ret void
19 ; CHECK-NEXT: ret void
23 %bc.1 = icmp eq i32 %a, 10
24 br i1 %bc.1, label %true, label %false
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)
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(
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:%.*]]
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
53 ; CHECK-NEXT: ret void
57 %bc.1 = icmp ult i32 %a, 127
58 br i1 %bc.1, label %true, label %false
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)
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(
76 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[INC1:%.*]], label [[INC2:%.*]]
78 ; CHECK-NEXT: br label [[IF:%.*]]
80 ; CHECK-NEXT: br label [[IF]]
82 ; CHECK-NEXT: br label [[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
91 br i1 %cond, label %inc1, label %inc2
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
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)
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(
122 ; CHECK-NEXT: [[A_127:%.*]] = and i32 [[A:%.*]], 127
123 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[INC1:%.*]], label [[INC2:%.*]]
125 ; CHECK-NEXT: br label [[IF:%.*]]
127 ; CHECK-NEXT: br label [[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:%.*]]
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
138 ; CHECK-NEXT: ret void
141 %a.127 = and i32 %a, 127
142 br i1 %cond, label %inc1, label %inc2
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
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)
167 ; All uses of %p can be replaced by a constant (10), we are allowed to use it
169 define void @bound_singlecrfromundef(i32 %a, i1 %cond) {
170 ; CHECK-LABEL: @bound_singlecrfromundef(
172 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
174 ; CHECK-NEXT: br label [[PRED:%.*]]
176 ; CHECK-NEXT: br label [[PRED]]
178 ; CHECK-NEXT: [[BC_1:%.*]] = icmp ugt i32 [[A:%.*]], 10
179 ; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
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
187 ; CHECK-NEXT: ret void
190 br i1 %cond, label %bb1, label %bb2
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
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)
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(
224 ; CHECK-NEXT: [[A_10:%.*]] = and i32 [[A:%.*]], 127
225 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
227 ; CHECK-NEXT: br label [[PRED:%.*]]
229 ; CHECK-NEXT: br label [[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:%.*]]
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
241 ; CHECK-NEXT: ret void
244 %a.10 = and i32 %a, 127
245 br i1 %cond, label %bb1, label %bb2
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
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)