• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4define void @idom_sign_bit_check_edge_dominates(i64 %a) {
5; CHECK-LABEL: @idom_sign_bit_check_edge_dominates(
6; CHECK-NEXT:  entry:
7; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0
8; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
9; CHECK:       land.lhs.true:
10; CHECK-NEXT:    br label [[LOR_END:%.*]]
11; CHECK:       lor.rhs:
12; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i64 [[A]], 0
13; CHECK-NEXT:    br i1 [[CMP2]], label [[LOR_END]], label [[LAND_RHS:%.*]]
14; CHECK:       land.rhs:
15; CHECK-NEXT:    br label [[LOR_END]]
16; CHECK:       lor.end:
17; CHECK-NEXT:    ret void
18;
19entry:
20  %cmp = icmp slt i64 %a, 0
21  br i1 %cmp, label %land.lhs.true, label %lor.rhs
22
23land.lhs.true:
24  br label %lor.end
25
26lor.rhs:
27  %cmp2 = icmp sgt i64 %a, 0
28  br i1 %cmp2, label %land.rhs, label %lor.end
29
30land.rhs:
31  br label %lor.end
32
33lor.end:
34  ret void
35}
36
37define void @idom_sign_bit_check_edge_not_dominates(i64 %a) {
38; CHECK-LABEL: @idom_sign_bit_check_edge_not_dominates(
39; CHECK-NEXT:  entry:
40; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0
41; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
42; CHECK:       land.lhs.true:
43; CHECK-NEXT:    br i1 undef, label [[LOR_END:%.*]], label [[LOR_RHS]]
44; CHECK:       lor.rhs:
45; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i64 [[A]], 0
46; CHECK-NEXT:    br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]
47; CHECK:       land.rhs:
48; CHECK-NEXT:    br label [[LOR_END]]
49; CHECK:       lor.end:
50; CHECK-NEXT:    ret void
51;
52entry:
53  %cmp = icmp slt i64 %a, 0
54  br i1 %cmp, label %land.lhs.true, label %lor.rhs
55
56land.lhs.true:
57  br i1 undef, label %lor.end, label %lor.rhs
58
59lor.rhs:
60  %cmp2 = icmp sgt i64 %a, 0
61  br i1 %cmp2, label %land.rhs, label %lor.end
62
63land.rhs:
64  br label %lor.end
65
66lor.end:
67  ret void
68}
69
70define void @idom_sign_bit_check_edge_dominates_select(i64 %a, i64 %b) {
71; CHECK-LABEL: @idom_sign_bit_check_edge_dominates_select(
72; CHECK-NEXT:  entry:
73; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 5
74; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
75; CHECK:       land.lhs.true:
76; CHECK-NEXT:    br label [[LOR_END:%.*]]
77; CHECK:       lor.rhs:
78; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i64 [[A]], [[B:%.*]]
79; CHECK-NEXT:    br i1 [[CMP3]], label [[LOR_END]], label [[LAND_RHS:%.*]]
80; CHECK:       land.rhs:
81; CHECK-NEXT:    br label [[LOR_END]]
82; CHECK:       lor.end:
83; CHECK-NEXT:    ret void
84;
85entry:
86  %cmp = icmp slt i64 %a, 5
87  br i1 %cmp, label %land.lhs.true, label %lor.rhs
88
89land.lhs.true:
90  br label %lor.end
91
92lor.rhs:
93  %cmp2 = icmp sgt i64 %a, 5
94  %select = select i1 %cmp2, i64 %a, i64 5
95  %cmp3 = icmp ne i64 %select, %b
96  br i1 %cmp3, label %land.rhs, label %lor.end
97
98land.rhs:
99  br label %lor.end
100
101lor.end:
102  ret void
103}
104
105define void @idom_zbranch(i64 %a) {
106; CHECK-LABEL: @idom_zbranch(
107; CHECK-NEXT:  entry:
108; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[A:%.*]], 0
109; CHECK-NEXT:    br i1 [[CMP]], label [[LOR_END:%.*]], label [[LOR_RHS:%.*]]
110; CHECK:       lor.rhs:
111; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i64 [[A]], 0
112; CHECK-NEXT:    br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]
113; CHECK:       land.rhs:
114; CHECK-NEXT:    br label [[LOR_END]]
115; CHECK:       lor.end:
116; CHECK-NEXT:    ret void
117;
118entry:
119  %cmp = icmp sgt i64 %a, 0
120  br i1 %cmp, label %lor.end, label %lor.rhs
121
122lor.rhs:
123  %cmp2 = icmp slt i64 %a, 0
124  br i1 %cmp2, label %land.rhs, label %lor.end
125
126land.rhs:
127  br label %lor.end
128
129lor.end:
130  ret void
131}
132
133define void @idom_not_zbranch(i32 %a, i32 %b) {
134; CHECK-LABEL: @idom_not_zbranch(
135; CHECK-NEXT:  entry:
136; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
137; CHECK-NEXT:    br i1 [[CMP]], label [[RETURN:%.*]], label [[IF_END:%.*]]
138; CHECK:       if.end:
139; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[A]], [[B:%.*]]
140; CHECK-NEXT:    br i1 [[CMP2]], label [[RETURN]], label [[IF_THEN3:%.*]]
141; CHECK:       if.then3:
142; CHECK-NEXT:    br label [[RETURN]]
143; CHECK:       return:
144; CHECK-NEXT:    ret void
145;
146entry:
147  %cmp = icmp sgt i32 %a, 0
148  br i1 %cmp, label %return, label %if.end
149
150if.end:
151  %cmp1 = icmp slt i32 %a, 0
152  %a. = select i1 %cmp1, i32 %a, i32 0
153  %cmp2 = icmp ne i32 %a., %b
154  br i1 %cmp2, label %if.then3, label %return
155
156if.then3:
157  br label %return
158
159return:
160  ret void
161}
162
163define void @trueblock_cmp_eq(i32 %a, i32 %b) {
164; CHECK-LABEL: @trueblock_cmp_eq(
165; CHECK-NEXT:  entry:
166; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
167; CHECK-NEXT:    br i1 [[CMP]], label [[IF_END:%.*]], label [[RETURN:%.*]]
168; CHECK:       if.end:
169; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A]], 1
170; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN3:%.*]], label [[RETURN]]
171; CHECK:       if.then3:
172; CHECK-NEXT:    br label [[RETURN]]
173; CHECK:       return:
174; CHECK-NEXT:    ret void
175;
176entry:
177  %cmp = icmp sgt i32 %a, 0
178  br i1 %cmp, label %if.end, label %return
179
180if.end:
181  %cmp1 = icmp slt i32 %a, 2
182  br i1 %cmp1, label %if.then3, label %return
183
184if.then3:
185  br label %return
186
187return:
188  ret void
189}
190
191define i1 @trueblock_cmp_is_false(i32 %x, i32 %y) {
192; CHECK-LABEL: @trueblock_cmp_is_false(
193; CHECK-NEXT:  entry:
194; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
195; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
196; CHECK:       t:
197; CHECK-NEXT:    ret i1 false
198; CHECK:       f:
199; CHECK-NEXT:    ret i1 [[CMP]]
200;
201entry:
202  %cmp = icmp sgt i32 %x, %y
203  br i1 %cmp, label %t, label %f
204t:
205  %cmp2 = icmp slt i32 %x, %y
206  ret i1 %cmp2
207f:
208  ret i1 %cmp
209}
210
211define i1 @trueblock_cmp_is_false_commute(i32 %x, i32 %y) {
212; CHECK-LABEL: @trueblock_cmp_is_false_commute(
213; CHECK-NEXT:  entry:
214; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
215; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
216; CHECK:       t:
217; CHECK-NEXT:    ret i1 false
218; CHECK:       f:
219; CHECK-NEXT:    ret i1 [[CMP]]
220;
221entry:
222  %cmp = icmp eq i32 %x, %y
223  br i1 %cmp, label %t, label %f
224t:
225  %cmp2 = icmp sgt i32 %y, %x
226  ret i1 %cmp2
227f:
228  ret i1 %cmp
229}
230
231define i1 @trueblock_cmp_is_true(i32 %x, i32 %y) {
232; CHECK-LABEL: @trueblock_cmp_is_true(
233; CHECK-NEXT:  entry:
234; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
235; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
236; CHECK:       t:
237; CHECK-NEXT:    ret i1 true
238; CHECK:       f:
239; CHECK-NEXT:    ret i1 [[CMP]]
240;
241entry:
242  %cmp = icmp ult i32 %x, %y
243  br i1 %cmp, label %t, label %f
244t:
245  %cmp2 = icmp ne i32 %x, %y
246  ret i1 %cmp2
247f:
248  ret i1 %cmp
249}
250
251define i1 @trueblock_cmp_is_true_commute(i32 %x, i32 %y) {
252; CHECK-LABEL: @trueblock_cmp_is_true_commute(
253; CHECK-NEXT:  entry:
254; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
255; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
256; CHECK:       t:
257; CHECK-NEXT:    ret i1 true
258; CHECK:       f:
259; CHECK-NEXT:    ret i1 [[CMP]]
260;
261entry:
262  %cmp = icmp ugt i32 %x, %y
263  br i1 %cmp, label %t, label %f
264t:
265  %cmp2 = icmp ne i32 %y, %x
266  ret i1 %cmp2
267f:
268  ret i1 %cmp
269}
270
271define i1 @falseblock_cmp_is_false(i32 %x, i32 %y) {
272; CHECK-LABEL: @falseblock_cmp_is_false(
273; CHECK-NEXT:  entry:
274; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
275; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
276; CHECK:       t:
277; CHECK-NEXT:    ret i1 [[CMP]]
278; CHECK:       f:
279; CHECK-NEXT:    ret i1 false
280;
281entry:
282  %cmp = icmp sle i32 %x, %y
283  br i1 %cmp, label %t, label %f
284t:
285  ret i1 %cmp
286f:
287  %cmp2 = icmp slt i32 %x, %y
288  ret i1 %cmp2
289}
290
291define i1 @falseblock_cmp_is_false_commute(i32 %x, i32 %y) {
292; CHECK-LABEL: @falseblock_cmp_is_false_commute(
293; CHECK-NEXT:  entry:
294; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
295; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
296; CHECK:       t:
297; CHECK-NEXT:    ret i1 [[CMP]]
298; CHECK:       f:
299; CHECK-NEXT:    ret i1 false
300;
301entry:
302  %cmp = icmp eq i32 %x, %y
303  br i1 %cmp, label %t, label %f
304t:
305  ret i1 %cmp
306f:
307  %cmp2 = icmp eq i32 %y, %x
308  ret i1 %cmp2
309}
310
311define i1 @falseblock_cmp_is_true(i32 %x, i32 %y) {
312; CHECK-LABEL: @falseblock_cmp_is_true(
313; CHECK-NEXT:  entry:
314; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
315; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
316; CHECK:       t:
317; CHECK-NEXT:    ret i1 [[CMP]]
318; CHECK:       f:
319; CHECK-NEXT:    ret i1 true
320;
321entry:
322  %cmp = icmp ult i32 %x, %y
323  br i1 %cmp, label %t, label %f
324t:
325  ret i1 %cmp
326f:
327  %cmp2 = icmp uge i32 %x, %y
328  ret i1 %cmp2
329}
330
331define i1 @falseblock_cmp_is_true_commute(i32 %x, i32 %y) {
332; CHECK-LABEL: @falseblock_cmp_is_true_commute(
333; CHECK-NEXT:  entry:
334; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
335; CHECK-NEXT:    br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
336; CHECK:       t:
337; CHECK-NEXT:    ret i1 [[CMP]]
338; CHECK:       f:
339; CHECK-NEXT:    ret i1 true
340;
341entry:
342  %cmp = icmp sgt i32 %x, %y
343  br i1 %cmp, label %t, label %f
344t:
345  ret i1 %cmp
346f:
347  %cmp2 = icmp sge i32 %y, %x
348  ret i1 %cmp2
349}
350
351