1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
4 ; If we have a umin feeding an unsigned or equality icmp that shares an
5 ; operand with the umin, the compare should always be folded.
6 ; Test all 4 foldable predicates (eq,ne,uge,ult) * 4 commutation
7 ; possibilities for each predicate. Note that folds to true/false
8 ; (predicate is ule/ugt) or folds to an existing instruction should be
9 ; handled by InstSimplify.
11 ; umin(X, Y) == X --> X <= Y
13 define i1 @eq_umin1(i32 %x, i32 %y) {
14 ; CHECK-LABEL: @eq_umin1(
15 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]]
16 ; CHECK-NEXT: ret i1 [[CMP2]]
18 %cmp1 = icmp ult i32 %x, %y
19 %sel = select i1 %cmp1, i32 %x, i32 %y
20 %cmp2 = icmp eq i32 %sel, %x
24 ; Commute min operands.
26 define i1 @eq_umin2(i32 %x, i32 %y) {
27 ; CHECK-LABEL: @eq_umin2(
28 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]]
29 ; CHECK-NEXT: ret i1 [[CMP2]]
31 %cmp1 = icmp ult i32 %y, %x
32 %sel = select i1 %cmp1, i32 %y, i32 %x
33 %cmp2 = icmp eq i32 %sel, %x
37 ; Disguise the icmp predicate by commuting the min op to the RHS.
39 define i1 @eq_umin3(i32 %a, i32 %y) {
40 ; CHECK-LABEL: @eq_umin3(
41 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
42 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], [[Y:%.*]]
43 ; CHECK-NEXT: ret i1 [[CMP2]]
45 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
46 %cmp1 = icmp ult i32 %x, %y
47 %sel = select i1 %cmp1, i32 %x, i32 %y
48 %cmp2 = icmp eq i32 %x, %sel
52 ; Commute min operands.
54 define i1 @eq_umin4(i32 %a, i32 %y) {
55 ; CHECK-LABEL: @eq_umin4(
56 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
57 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], [[Y:%.*]]
58 ; CHECK-NEXT: ret i1 [[CMP2]]
60 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
61 %cmp1 = icmp ult i32 %y, %x
62 %sel = select i1 %cmp1, i32 %y, i32 %x
63 %cmp2 = icmp eq i32 %x, %sel
67 ; umin(X, Y) >= X --> X <= Y
69 define i1 @uge_umin1(i32 %x, i32 %y) {
70 ; CHECK-LABEL: @uge_umin1(
71 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]]
72 ; CHECK-NEXT: ret i1 [[CMP2]]
74 %cmp1 = icmp ult i32 %x, %y
75 %sel = select i1 %cmp1, i32 %x, i32 %y
76 %cmp2 = icmp uge i32 %sel, %x
80 ; Commute min operands.
82 define i1 @uge_umin2(i32 %x, i32 %y) {
83 ; CHECK-LABEL: @uge_umin2(
84 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]]
85 ; CHECK-NEXT: ret i1 [[CMP2]]
87 %cmp1 = icmp ult i32 %y, %x
88 %sel = select i1 %cmp1, i32 %y, i32 %x
89 %cmp2 = icmp uge i32 %sel, %x
93 ; Disguise the icmp predicate by commuting the min op to the RHS.
95 define i1 @uge_umin3(i32 %a, i32 %y) {
96 ; CHECK-LABEL: @uge_umin3(
97 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
98 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], [[Y:%.*]]
99 ; CHECK-NEXT: ret i1 [[CMP2]]
101 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
102 %cmp1 = icmp ult i32 %x, %y
103 %sel = select i1 %cmp1, i32 %x, i32 %y
104 %cmp2 = icmp ule i32 %x, %sel
108 ; Commute min operands.
110 define i1 @uge_umin4(i32 %a, i32 %y) {
111 ; CHECK-LABEL: @uge_umin4(
112 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
113 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], [[Y:%.*]]
114 ; CHECK-NEXT: ret i1 [[CMP2]]
116 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
117 %cmp1 = icmp ult i32 %y, %x
118 %sel = select i1 %cmp1, i32 %y, i32 %x
119 %cmp2 = icmp ule i32 %x, %sel
123 ; umin(X, Y) != X --> X > Y
125 define i1 @ne_umin1(i32 %x, i32 %y) {
126 ; CHECK-LABEL: @ne_umin1(
127 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
128 ; CHECK-NEXT: ret i1 [[CMP2]]
130 %cmp1 = icmp ult i32 %x, %y
131 %sel = select i1 %cmp1, i32 %x, i32 %y
132 %cmp2 = icmp ne i32 %sel, %x
136 ; Commute min operands.
138 define i1 @ne_umin2(i32 %x, i32 %y) {
139 ; CHECK-LABEL: @ne_umin2(
140 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[Y:%.*]], [[X:%.*]]
141 ; CHECK-NEXT: ret i1 [[CMP1]]
143 %cmp1 = icmp ult i32 %y, %x
144 %sel = select i1 %cmp1, i32 %y, i32 %x
145 %cmp2 = icmp ne i32 %sel, %x
149 ; Disguise the icmp predicate by commuting the min op to the RHS.
151 define i1 @ne_umin3(i32 %a, i32 %y) {
152 ; CHECK-LABEL: @ne_umin3(
153 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
154 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], [[Y:%.*]]
155 ; CHECK-NEXT: ret i1 [[CMP2]]
157 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
158 %cmp1 = icmp ult i32 %x, %y
159 %sel = select i1 %cmp1, i32 %x, i32 %y
160 %cmp2 = icmp ne i32 %x, %sel
164 ; Commute min operands.
166 define i1 @ne_umin4(i32 %a, i32 %y) {
167 ; CHECK-LABEL: @ne_umin4(
168 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
169 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], [[Y:%.*]]
170 ; CHECK-NEXT: ret i1 [[CMP1]]
172 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
173 %cmp1 = icmp ult i32 %y, %x
174 %sel = select i1 %cmp1, i32 %y, i32 %x
175 %cmp2 = icmp ne i32 %x, %sel
179 ; umin(X, Y) < X --> X > Y
181 define i1 @ult_umin1(i32 %x, i32 %y) {
182 ; CHECK-LABEL: @ult_umin1(
183 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
184 ; CHECK-NEXT: ret i1 [[CMP2]]
186 %cmp1 = icmp ult i32 %x, %y
187 %sel = select i1 %cmp1, i32 %x, i32 %y
188 %cmp2 = icmp ult i32 %sel, %x
192 ; Commute min operands.
194 define i1 @ult_umin2(i32 %x, i32 %y) {
195 ; CHECK-LABEL: @ult_umin2(
196 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[Y:%.*]], [[X:%.*]]
197 ; CHECK-NEXT: ret i1 [[CMP1]]
199 %cmp1 = icmp ult i32 %y, %x
200 %sel = select i1 %cmp1, i32 %y, i32 %x
201 %cmp2 = icmp ult i32 %sel, %x
205 ; Disguise the icmp predicate by commuting the min op to the RHS.
207 define i1 @ult_umin3(i32 %a, i32 %y) {
208 ; CHECK-LABEL: @ult_umin3(
209 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
210 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], [[Y:%.*]]
211 ; CHECK-NEXT: ret i1 [[CMP2]]
213 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
214 %cmp1 = icmp ult i32 %x, %y
215 %sel = select i1 %cmp1, i32 %x, i32 %y
216 %cmp2 = icmp ugt i32 %x, %sel
220 ; Commute min operands.
222 define i1 @ult_umin4(i32 %a, i32 %y) {
223 ; CHECK-LABEL: @ult_umin4(
224 ; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3
225 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], [[Y:%.*]]
226 ; CHECK-NEXT: ret i1 [[CMP1]]
228 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
229 %cmp1 = icmp ult i32 %y, %x
230 %sel = select i1 %cmp1, i32 %y, i32 %x
231 %cmp2 = icmp ugt i32 %x, %sel