1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt %s -instcombine -S | FileCheck %s
9 ; @llvm.uadd.with.overflow(%x, %y) + extractvalue + not
11 ; All tests here have extra uses, to ensure that the pattern isn't perturbed.
13 declare void @use8(i8)
14 declare void @use2x8(<2 x i8>)
16 define i1 @t0_basic(i8 %x, i8 %y) {
17 ; CHECK-LABEL: @t0_basic(
18 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
19 ; CHECK-NEXT: call void @use8(i8 [[T0]])
20 ; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[T0]], [[Y]]
21 ; CHECK-NEXT: ret i1 [[R]]
24 call void @use8(i8 %t0)
25 %r = icmp uge i8 %t0, %y
29 define <2 x i1> @t1_vec(<2 x i8> %x, <2 x i8> %y) {
30 ; CHECK-LABEL: @t1_vec(
31 ; CHECK-NEXT: [[T0:%.*]] = add <2 x i8> [[X:%.*]], [[Y:%.*]]
32 ; CHECK-NEXT: call void @use2x8(<2 x i8> [[T0]])
33 ; CHECK-NEXT: [[R:%.*]] = icmp uge <2 x i8> [[T0]], [[Y]]
34 ; CHECK-NEXT: ret <2 x i1> [[R]]
36 %t0 = add <2 x i8> %x, %y
37 call void @use2x8(<2 x i8> %t0)
38 %r = icmp uge <2 x i8> %t0, %y
44 define i1 @t2_symmetry(i8 %x, i8 %y) {
45 ; CHECK-LABEL: @t2_symmetry(
46 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
47 ; CHECK-NEXT: call void @use8(i8 [[T0]])
48 ; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[T0]], [[X]]
49 ; CHECK-NEXT: ret i1 [[R]]
52 call void @use8(i8 %t0)
53 %r = icmp uge i8 %t0, %x ; can check against either of `add` arguments
59 define i1 @t3_commutative(i8 %x) {
60 ; CHECK-LABEL: @t3_commutative(
61 ; CHECK-NEXT: [[Y:%.*]] = call i8 @gen8()
62 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[Y]], [[X:%.*]]
63 ; CHECK-NEXT: call void @use8(i8 [[T0]])
64 ; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[T0]], [[Y]]
65 ; CHECK-NEXT: ret i1 [[R]]
68 %t0 = add i8 %y, %x ; swapped
69 call void @use8(i8 %t0)
70 %r = icmp uge i8 %t0, %y
74 define i1 @t4_commutative() {
75 ; CHECK-LABEL: @t4_commutative(
76 ; CHECK-NEXT: [[X:%.*]] = call i8 @gen8()
77 ; CHECK-NEXT: [[Y:%.*]] = call i8 @gen8()
78 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X]], [[Y]]
79 ; CHECK-NEXT: call void @use8(i8 [[T0]])
80 ; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[Y]], [[T0]]
81 ; CHECK-NEXT: ret i1 [[R]]
86 call void @use8(i8 %t0)
87 %r = icmp ule i8 %y, %t0 ; swapped
91 define i1 @t5_commutative(i8 %x) {
92 ; CHECK-LABEL: @t5_commutative(
93 ; CHECK-NEXT: [[Y:%.*]] = call i8 @gen8()
94 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[Y]], [[X:%.*]]
95 ; CHECK-NEXT: call void @use8(i8 [[T0]])
96 ; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[Y]], [[T0]]
97 ; CHECK-NEXT: ret i1 [[R]]
100 %t0 = add i8 %y, %x ; swapped
101 call void @use8(i8 %t0)
102 %r = icmp ule i8 %y, %t0 ; swapped
108 define i1 @t6_no_extrause(i8 %x, i8 %y) {
109 ; CHECK-LABEL: @t6_no_extrause(
110 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1
111 ; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[TMP1]], [[X:%.*]]
112 ; CHECK-NEXT: ret i1 [[R]]
115 %r = icmp uge i8 %t0, %y
121 define i1 @n7_different_y(i8 %x, i8 %y0, i8 %y1) {
122 ; CHECK-LABEL: @n7_different_y(
123 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], [[Y0:%.*]]
124 ; CHECK-NEXT: call void @use8(i8 [[T0]])
125 ; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[T0]], [[Y1:%.*]]
126 ; CHECK-NEXT: ret i1 [[R]]
129 call void @use8(i8 %t0)
130 %r = icmp uge i8 %t0, %y1
134 define i1 @n8_wrong_pred0(i8 %x, i8 %y) {
135 ; CHECK-LABEL: @n8_wrong_pred0(
136 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
137 ; CHECK-NEXT: call void @use8(i8 [[T0]])
138 ; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[T0]], [[Y]]
139 ; CHECK-NEXT: ret i1 [[R]]
142 call void @use8(i8 %t0)
143 %r = icmp ule i8 %t0, %y
147 define i1 @n9_wrong_pred1(i8 %x, i8 %y) {
148 ; CHECK-LABEL: @n9_wrong_pred1(
149 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
150 ; CHECK-NEXT: call void @use8(i8 [[T0]])
151 ; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[T0]], [[Y]]
152 ; CHECK-NEXT: ret i1 [[R]]
155 call void @use8(i8 %t0)
156 %r = icmp ugt i8 %t0, %y
160 define i1 @n10_wrong_pred2(i8 %x, i8 %y) {
161 ; CHECK-LABEL: @n10_wrong_pred2(
162 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
163 ; CHECK-NEXT: call void @use8(i8 [[T0]])
164 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], 0
165 ; CHECK-NEXT: ret i1 [[R]]
168 call void @use8(i8 %t0)
169 %r = icmp eq i8 %t0, %y
173 define i1 @n11_wrong_pred3(i8 %x, i8 %y) {
174 ; CHECK-LABEL: @n11_wrong_pred3(
175 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
176 ; CHECK-NEXT: call void @use8(i8 [[T0]])
177 ; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X]], 0
178 ; CHECK-NEXT: ret i1 [[R]]
181 call void @use8(i8 %t0)
182 %r = icmp ne i8 %t0, %y
186 define i1 @n12_wrong_pred4(i8 %x, i8 %y) {
187 ; CHECK-LABEL: @n12_wrong_pred4(
188 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
189 ; CHECK-NEXT: call void @use8(i8 [[T0]])
190 ; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[T0]], [[Y]]
191 ; CHECK-NEXT: ret i1 [[R]]
194 call void @use8(i8 %t0)
195 %r = icmp slt i8 %t0, %y
199 define i1 @n13_wrong_pred5(i8 %x, i8 %y) {
200 ; CHECK-LABEL: @n13_wrong_pred5(
201 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
202 ; CHECK-NEXT: call void @use8(i8 [[T0]])
203 ; CHECK-NEXT: [[R:%.*]] = icmp sle i8 [[T0]], [[Y]]
204 ; CHECK-NEXT: ret i1 [[R]]
207 call void @use8(i8 %t0)
208 %r = icmp sle i8 %t0, %y
212 define i1 @n14_wrong_pred6(i8 %x, i8 %y) {
213 ; CHECK-LABEL: @n14_wrong_pred6(
214 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
215 ; CHECK-NEXT: call void @use8(i8 [[T0]])
216 ; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[T0]], [[Y]]
217 ; CHECK-NEXT: ret i1 [[R]]
220 call void @use8(i8 %t0)
221 %r = icmp sgt i8 %t0, %y
225 define i1 @n15_wrong_pred7(i8 %x, i8 %y) {
226 ; CHECK-LABEL: @n15_wrong_pred7(
227 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
228 ; CHECK-NEXT: call void @use8(i8 [[T0]])
229 ; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[T0]], [[Y]]
230 ; CHECK-NEXT: ret i1 [[R]]
233 call void @use8(i8 %t0)
234 %r = icmp sge i8 %t0, %y