xref: /llvm-project/llvm/test/Transforms/InstSimplify/select-icmp.ll (revision 2bd568feccff9760938849e79289af67c3e6c231)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3
4; TODO: https://alive2.llvm.org/ce/z/3ybZRl
5define i32 @pr54735_slt(i32 %x, i32 %y) {
6; CHECK-LABEL: @pr54735_slt(
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
9; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
10; CHECK:       cond.true:
11; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
12; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], 1
13; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[SUB]], -1
14; CHECK-NEXT:    [[ABSCOND:%.*]] = icmp sle i32 [[SUB]], -1
15; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[ADD]]
16; CHECK-NEXT:    ret i32 [[ABS]]
17; CHECK:       cond.end:
18; CHECK-NEXT:    ret i32 0
19;
20entry:
21  %cmp = icmp slt i32 %x, %y                      ; x<y ? abs (x-y+1): 0
22  br i1 %cmp, label %cond.true, label %cond.end
23
24cond.true:                                        ; preds = %entry
25  %sub = sub nsw i32 %x, %y
26  %add = add nsw i32 %sub, 1
27  %neg = xor i32 %sub, -1                         ; sub nsw i32 0, %add
28  %abscond = icmp sle i32 %sub, -1
29  %abs = select i1 %abscond, i32 %neg, i32 %add
30  ret i32 %abs
31
32cond.end:                                         ; preds = %entry, %cond.true
33  ret i32 0
34}
35
36; https://alive2.llvm.org/ce/z/fTTsdT
37define i32 @pr54735_sgt(i32 %x, i32 %y) {
38; CHECK-LABEL: @pr54735_sgt(
39; CHECK-NEXT:  entry:
40; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
41; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
42; CHECK:       cond.true:
43; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
44; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], 1
45; CHECK-NEXT:    ret i32 [[ADD]]
46; CHECK:       cond.end:
47; CHECK-NEXT:    ret i32 0
48;
49entry:
50  %cmp = icmp sgt i32 %x, %y                      ; x>y ? abs (x-y+1): 0
51  br i1 %cmp, label %cond.true, label %cond.end
52
53cond.true:                                        ; preds = %entry
54  %sub = sub nsw i32 %x, %y
55  %add = add nsw i32 %sub, 1
56  %neg = xor i32 %sub, -1                         ; sub nsw i32 0, %add
57  %abscond = icmp slt i32 %sub, -1
58  %abs = select i1 %abscond, i32 %neg, i32 %add
59  ret i32 %abs
60
61cond.end:                                         ; preds = %entry, %cond.true
62  ret i32 0
63}
64
65; https://alive2.llvm.org/ce/z/k9v75c
66define i32 @pr54735_sge(i32 %x, i32 %y) {
67; CHECK-LABEL: @pr54735_sge(
68; CHECK-NEXT:  entry:
69; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]
70; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
71; CHECK:       cond.true:
72; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
73; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], 1
74; CHECK-NEXT:    ret i32 [[ADD]]
75; CHECK:       cond.end:
76; CHECK-NEXT:    ret i32 0
77;
78entry:
79  %cmp = icmp sge i32 %x, %y                      ; x>y ? abs (x-y+1): 0
80  br i1 %cmp, label %cond.true, label %cond.end
81
82cond.true:                                        ; preds = %entry
83  %sub = sub nsw i32 %x, %y
84  %add = add nsw i32 %sub, 1
85  %neg = xor i32 %sub, -1                         ; sub nsw i32 0, %add
86  %abscond = icmp slt i32 %sub, -1
87  %abs = select i1 %abscond, i32 %neg, i32 %add
88  ret i32 %abs
89
90cond.end:                                         ; preds = %entry, %cond.true
91  ret i32 0
92}
93
94; Negative test: https://alive2.llvm.org/ce/z/oZyu4M
95define i8 @pr54735_without_nsw (i8 %x, i8 %y) {
96; CHECK-LABEL: @pr54735_without_nsw(
97; CHECK-NEXT:  entry:
98; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
99; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
100; CHECK:       cond.true:
101; CHECK-NEXT:    [[SUB:%.*]] = sub i8 [[X]], [[Y]]
102; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SUB]], 1
103; CHECK-NEXT:    [[NEG:%.*]] = xor i8 [[SUB]], -1
104; CHECK-NEXT:    [[ABSCOND:%.*]] = icmp slt i8 [[SUB]], -1
105; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[ABSCOND]], i8 [[NEG]], i8 [[ADD]]
106; CHECK-NEXT:    ret i8 [[ABS]]
107; CHECK:       cond.end:
108; CHECK-NEXT:    ret i8 0
109;
110entry:
111  %cmp = icmp sgt i8 %x, %y
112  br i1 %cmp, label %cond.true, label %cond.end
113
114cond.true:                                        ; preds = %entry
115  %sub = sub i8 %x, %y
116  %add = add i8 %sub, 1
117  %neg = xor i8 %sub, -1
118  %abscond = icmp slt i8 %sub, -1
119  %abs = select i1 %abscond, i8 %neg, i8 %add
120  ret i8 %abs
121
122cond.end:                                         ; preds = %entry, %cond.true
123  ret i8 0
124}
125
126define i32 @pr54735_sle(i32 %x, i32 %y) {
127; CHECK-LABEL: @pr54735_sle(
128; CHECK-NEXT:  entry:
129; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
130; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
131; CHECK:       cond.true:
132; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
133; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], 1
134; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[SUB]], -1
135; CHECK-NEXT:    [[ABSCOND:%.*]] = icmp slt i32 [[SUB]], -1
136; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[ADD]]
137; CHECK-NEXT:    ret i32 [[ABS]]
138; CHECK:       cond.end:
139; CHECK-NEXT:    ret i32 0
140;
141entry:
142  %cmp = icmp sle i32 %x, %y                      ; x<=y ? abs (x-y+1): 0
143  br i1 %cmp, label %cond.true, label %cond.end
144
145cond.true:                                        ; preds = %entry
146  %sub = sub nsw i32 %x, %y
147  %add = add nsw i32 %sub, 1
148  %neg = xor i32 %sub, -1                         ; sub nsw i32 0, %add
149  %abscond = icmp slt i32 %sub, -1
150  %abs = select i1 %abscond, i32 %neg, i32 %add
151  ret i32 %abs
152
153cond.end:                                         ; preds = %entry, %cond.true
154  ret i32 0
155}
156
157; https://alive2.llvm.org/ce/z/pp9zJi
158define i32 @pr54735_slt_neg(i32 %x, i32 %y) {
159; CHECK-LABEL: @pr54735_slt_neg(
160; CHECK-NEXT:  entry:
161; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
162; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
163; CHECK:       cond.true:
164; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
165; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[SUB]], 12
166; CHECK-NEXT:    ret i32 [[NEG]]
167; CHECK:       cond.end:
168; CHECK-NEXT:    ret i32 0
169;
170entry:
171  %cmp = icmp slt i32 %x, %y                      ; x<y ? abs (x-y-12): 0
172  br i1 %cmp, label %cond.true, label %cond.end
173
174cond.true:                                        ; preds = %entry
175  %sub = sub nsw i32 %x, %y
176  %add = add nsw i32 %sub, -12                    ; %sub - 12
177  %neg = xor i32 %sub, 12                         ; 12 - %sub
178  %abscond = icmp sle i32 %sub, 12
179  %abs = select i1 %abscond, i32 %neg, i32 %add
180  ret i32 %abs
181
182cond.end:                                         ; preds = %entry, %cond.true
183  ret i32 0
184}
185
186; https://alive2.llvm.org/ce/z/9P6grR
187define i32 @pr54735_sle_neg(i32 %x, i32 %y) {
188; CHECK-LABEL: @pr54735_sle_neg(
189; CHECK-NEXT:  entry:
190; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
191; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
192; CHECK:       cond.true:
193; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
194; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[SUB]], 12
195; CHECK-NEXT:    ret i32 [[NEG]]
196; CHECK:       cond.end:
197; CHECK-NEXT:    ret i32 0
198;
199entry:
200  %cmp = icmp sle i32 %x, %y                      ; x<=y ? abs (x-y-12): 0
201  br i1 %cmp, label %cond.true, label %cond.end
202
203cond.true:                                        ; preds = %entry
204  %sub = sub nsw i32 %x, %y
205  %add = add nsw i32 %sub, -12
206  %neg = xor i32 %sub, 12                         ; %sub - 12
207  %abscond = icmp sle i32 %sub, 12
208  %abs = select i1 %abscond, i32 %neg, i32 %add
209  ret i32 %abs
210
211cond.end:                                         ; preds = %entry, %cond.true
212  ret i32 0
213}
214
215; Negative test: https://alive2.llvm.org/ce/z/Yqv4x2
216define i8 @pr54735_unexpect_const (i8 %x, i8 %y) {
217; CHECK-LABEL: @pr54735_unexpect_const(
218; CHECK-NEXT:  entry:
219; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
220; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
221; CHECK:       cond.true:
222; CHECK-NEXT:    [[SUB:%.*]] = sub i8 [[X]], [[Y]]
223; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SUB]], 2
224; CHECK-NEXT:    [[NEG:%.*]] = xor i8 [[SUB]], -1
225; CHECK-NEXT:    [[ABSCOND:%.*]] = icmp slt i8 [[SUB]], -2
226; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[ABSCOND]], i8 [[NEG]], i8 [[ADD]]
227; CHECK-NEXT:    ret i8 [[ABS]]
228; CHECK:       cond.end:
229; CHECK-NEXT:    ret i8 0
230;
231entry:
232  %cmp = icmp sgt i8 %x, %y                       ; x>y ? abs (x-y+2): 0
233  br i1 %cmp, label %cond.true, label %cond.end
234
235cond.true:                                        ; preds = %entry
236  %sub = sub i8 %x, %y
237  %add = add i8 %sub, 2                           ; x-y+2
238  %neg = xor i8 %sub, -1                          ; y-x-1
239  %neg1 = sub i8 %neg, 1                          ; y-x-2
240  %abscond = icmp slt i8 %sub, -2
241  %abs = select i1 %abscond, i8 %neg, i8 %add
242  ret i8 %abs
243
244cond.end:                                         ; preds = %entry, %cond.true
245  ret i8 0
246}
247