blob: eabd41ceb62a54a1cf67dfc105c66dce24929bfe [file] [log] [blame]
Sanjay Patel73d8bd92016-12-08 23:36:57 +00001; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -instcombine < %s | FileCheck %s
3
4; If we have a umax feeding an unsigned or equality icmp that shares an
5; operand with the umax, the compare should always be folded.
6; Test all 4 foldable predicates (eq,ne,ugt,ule) * 4 commutation
7; possibilities for each predicate. Note that folds to true/false
8; (predicate = uge/ult) or folds to an existing instruction should be
9; handled by InstSimplify.
10
11; umax(X, Y) == X --> X >= Y
12
13define i1 @eq_umax1(i32 %x, i32 %y) {
14; CHECK-LABEL: @eq_umax1(
Sanjay Pateldd46b522016-12-19 17:32:37 +000015; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 %x, %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +000016; CHECK-NEXT: ret i1 [[CMP2]]
17;
18 %cmp1 = icmp ugt i32 %x, %y
19 %sel = select i1 %cmp1, i32 %x, i32 %y
20 %cmp2 = icmp eq i32 %sel, %x
21 ret i1 %cmp2
22}
23
24; Commute max operands.
25
26define i1 @eq_umax2(i32 %x, i32 %y) {
27; CHECK-LABEL: @eq_umax2(
Sanjay Pateldd46b522016-12-19 17:32:37 +000028; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 %x, %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +000029; CHECK-NEXT: ret i1 [[CMP2]]
30;
31 %cmp1 = icmp ugt i32 %y, %x
32 %sel = select i1 %cmp1, i32 %y, i32 %x
33 %cmp2 = icmp eq i32 %sel, %x
34 ret i1 %cmp2
35}
36
37; Disguise the icmp predicate by commuting the max op to the RHS.
38
39define i1 @eq_umax3(i32 %a, i32 %y) {
40; CHECK-LABEL: @eq_umax3(
41; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +000042; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +000043; CHECK-NEXT: ret i1 [[CMP2]]
44;
45 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
46 %cmp1 = icmp ugt i32 %x, %y
47 %sel = select i1 %cmp1, i32 %x, i32 %y
48 %cmp2 = icmp eq i32 %x, %sel
49 ret i1 %cmp2
50}
51
52; Commute max operands.
53
54define i1 @eq_umax4(i32 %a, i32 %y) {
55; CHECK-LABEL: @eq_umax4(
56; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +000057; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +000058; CHECK-NEXT: ret i1 [[CMP2]]
59;
60 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
61 %cmp1 = icmp ugt i32 %y, %x
62 %sel = select i1 %cmp1, i32 %y, i32 %x
63 %cmp2 = icmp eq i32 %x, %sel
64 ret i1 %cmp2
65}
66
67; umax(X, Y) <= X --> X >= Y
68
69define i1 @ule_umax1(i32 %x, i32 %y) {
70; CHECK-LABEL: @ule_umax1(
Sanjay Pateldd46b522016-12-19 17:32:37 +000071; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 %x, %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +000072; CHECK-NEXT: ret i1 [[CMP2]]
73;
74 %cmp1 = icmp ugt i32 %x, %y
75 %sel = select i1 %cmp1, i32 %x, i32 %y
76 %cmp2 = icmp ule i32 %sel, %x
77 ret i1 %cmp2
78}
79
80; Commute max operands.
81
82define i1 @ule_umax2(i32 %x, i32 %y) {
83; CHECK-LABEL: @ule_umax2(
Sanjay Pateldd46b522016-12-19 17:32:37 +000084; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 %x, %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +000085; CHECK-NEXT: ret i1 [[CMP2]]
86;
87 %cmp1 = icmp ugt i32 %y, %x
88 %sel = select i1 %cmp1, i32 %y, i32 %x
89 %cmp2 = icmp ule i32 %sel, %x
90 ret i1 %cmp2
91}
92
93; Disguise the icmp predicate by commuting the max op to the RHS.
94
95define i1 @ule_umax3(i32 %a, i32 %y) {
96; CHECK-LABEL: @ule_umax3(
97; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +000098; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +000099; CHECK-NEXT: ret i1 [[CMP2]]
100;
101 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
102 %cmp1 = icmp ugt i32 %x, %y
103 %sel = select i1 %cmp1, i32 %x, i32 %y
104 %cmp2 = icmp uge i32 %x, %sel
105 ret i1 %cmp2
106}
107
108; Commute max operands.
109
110define i1 @ule_umax4(i32 %a, i32 %y) {
111; CHECK-LABEL: @ule_umax4(
112; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +0000113; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +0000114; CHECK-NEXT: ret i1 [[CMP2]]
115;
116 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
117 %cmp1 = icmp ugt i32 %y, %x
118 %sel = select i1 %cmp1, i32 %y, i32 %x
119 %cmp2 = icmp uge i32 %x, %sel
120 ret i1 %cmp2
121}
122
123; umax(X, Y) != X --> X < Y
124
125define i1 @ne_umax1(i32 %x, i32 %y) {
126; CHECK-LABEL: @ne_umax1(
Sanjay Pateldd46b522016-12-19 17:32:37 +0000127; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 %x, %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +0000128; CHECK-NEXT: ret i1 [[CMP2]]
129;
130 %cmp1 = icmp ugt i32 %x, %y
131 %sel = select i1 %cmp1, i32 %x, i32 %y
132 %cmp2 = icmp ne i32 %sel, %x
133 ret i1 %cmp2
134}
135
136; Commute max operands.
137
138define i1 @ne_umax2(i32 %x, i32 %y) {
139; CHECK-LABEL: @ne_umax2(
140; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 %y, %x
141; CHECK-NEXT: ret i1 [[CMP1]]
142;
143 %cmp1 = icmp ugt i32 %y, %x
144 %sel = select i1 %cmp1, i32 %y, i32 %x
145 %cmp2 = icmp ne i32 %sel, %x
146 ret i1 %cmp2
147}
148
149; Disguise the icmp predicate by commuting the max op to the RHS.
150
151define i1 @ne_umax3(i32 %a, i32 %y) {
152; CHECK-LABEL: @ne_umax3(
153; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +0000154; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +0000155; CHECK-NEXT: ret i1 [[CMP2]]
156;
157 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
158 %cmp1 = icmp ugt i32 %x, %y
159 %sel = select i1 %cmp1, i32 %x, i32 %y
160 %cmp2 = icmp ne i32 %x, %sel
161 ret i1 %cmp2
162}
163
164; Commute max operands.
165
166define i1 @ne_umax4(i32 %a, i32 %y) {
167; CHECK-LABEL: @ne_umax4(
168; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
169; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y
170; CHECK-NEXT: ret i1 [[CMP1]]
171;
172 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
173 %cmp1 = icmp ugt i32 %y, %x
174 %sel = select i1 %cmp1, i32 %y, i32 %x
175 %cmp2 = icmp ne i32 %x, %sel
176 ret i1 %cmp2
177}
178
179; umax(X, Y) > X --> X < Y
180
181define i1 @ugt_umax1(i32 %x, i32 %y) {
182; CHECK-LABEL: @ugt_umax1(
Sanjay Pateldd46b522016-12-19 17:32:37 +0000183; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 %x, %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +0000184; CHECK-NEXT: ret i1 [[CMP2]]
185;
186 %cmp1 = icmp ugt i32 %x, %y
187 %sel = select i1 %cmp1, i32 %x, i32 %y
188 %cmp2 = icmp ugt i32 %sel, %x
189 ret i1 %cmp2
190}
191
192; Commute max operands.
193
194define i1 @ugt_umax2(i32 %x, i32 %y) {
195; CHECK-LABEL: @ugt_umax2(
196; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 %y, %x
197; CHECK-NEXT: ret i1 [[CMP1]]
198;
199 %cmp1 = icmp ugt i32 %y, %x
200 %sel = select i1 %cmp1, i32 %y, i32 %x
201 %cmp2 = icmp ugt i32 %sel, %x
202 ret i1 %cmp2
203}
204
205; Disguise the icmp predicate by commuting the max op to the RHS.
206
207define i1 @ugt_umax3(i32 %a, i32 %y) {
208; CHECK-LABEL: @ugt_umax3(
209; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +0000210; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], %y
Sanjay Patel73d8bd92016-12-08 23:36:57 +0000211; CHECK-NEXT: ret i1 [[CMP2]]
212;
213 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
214 %cmp1 = icmp ugt i32 %x, %y
215 %sel = select i1 %cmp1, i32 %x, i32 %y
216 %cmp2 = icmp ult i32 %x, %sel
217 ret i1 %cmp2
218}
219
220; Commute max operands.
221
222define i1 @ugt_umax4(i32 %a, i32 %y) {
223; CHECK-LABEL: @ugt_umax4(
224; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
225; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y
226; CHECK-NEXT: ret i1 [[CMP1]]
227;
228 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
229 %cmp1 = icmp ugt i32 %y, %x
230 %sel = select i1 %cmp1, i32 %y, i32 %x
231 %cmp2 = icmp ult i32 %x, %sel
232 ret i1 %cmp2
233}
234