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