• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4; Should fold
5;   (%x + %y) u< %x
6; or
7;   (%x + %y) u< %y
8; to
9;   @llvm.uadd.with.overflow(%x, %y) + extractvalue
10;
11; All tests here have extra uses, to ensure that the pattern isn't perturbed.
12
13declare void @use8(i8)
14declare void @use2x8(<2 x i8>)
15
16define 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 ult i8 [[T0]], [[Y]]
21; CHECK-NEXT:    ret i1 [[R]]
22;
23  %t0 = add i8 %x, %y
24  call void @use8(i8 %t0)
25  %r = icmp ult i8 %t0, %y
26  ret i1 %r
27}
28
29define <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 ult <2 x i8> [[T0]], [[Y]]
34; CHECK-NEXT:    ret <2 x i1> [[R]]
35;
36  %t0 = add <2 x i8> %x, %y
37  call void @use2x8(<2 x i8> %t0)
38  %r = icmp ult <2 x i8> %t0, %y
39  ret <2 x i1> %r
40}
41
42; Commutativity
43
44define 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 ult i8 [[T0]], [[X]]
49; CHECK-NEXT:    ret i1 [[R]]
50;
51  %t0 = add i8 %x, %y
52  call void @use8(i8 %t0)
53  %r = icmp ult i8 %t0, %x ; can check against either of `add` arguments
54  ret i1 %r
55}
56
57declare i8 @gen8()
58
59define 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 ult i8 [[T0]], [[Y]]
65; CHECK-NEXT:    ret i1 [[R]]
66;
67  %y = call i8 @gen8()
68  %t0 = add i8 %y, %x ; swapped
69  call void @use8(i8 %t0)
70  %r = icmp ult i8 %t0, %y
71  ret i1 %r
72}
73
74define i1 @t4_commutative(i8 %x, i8 %y) {
75; CHECK-LABEL: @t4_commutative(
76; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
77; CHECK-NEXT:    call void @use8(i8 [[T0]])
78; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[T0]], [[Y]]
79; CHECK-NEXT:    ret i1 [[R]]
80;
81  %t0 = add i8 %x, %y
82  call void @use8(i8 %t0)
83  %r = icmp ugt i8 %y, %t0 ; swapped
84  ret i1 %r
85}
86
87define i1 @t5_commutative(i8 %x) {
88; CHECK-LABEL: @t5_commutative(
89; CHECK-NEXT:    [[Y:%.*]] = call i8 @gen8()
90; CHECK-NEXT:    [[T0:%.*]] = add i8 [[Y]], [[X:%.*]]
91; CHECK-NEXT:    call void @use8(i8 [[T0]])
92; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[Y]], [[T0]]
93; CHECK-NEXT:    ret i1 [[R]]
94;
95  %y = call i8 @gen8()
96  %t0 = add i8 %y, %x ; swapped
97  call void @use8(i8 %t0)
98  %r = icmp ugt i8 %y, %t0 ; swapped
99  ret i1 %r
100}
101
102; Extra-use tests
103
104define i1 @t6_no_extrause(i8 %x, i8 %y) {
105; CHECK-LABEL: @t6_no_extrause(
106; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1
107; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[TMP1]], [[X:%.*]]
108; CHECK-NEXT:    ret i1 [[R]]
109;
110  %t0 = add i8 %x, %y
111  %r = icmp ult i8 %t0, %y
112  ret i1 %r
113}
114
115; Negative tests
116
117define i1 @n7_different_y(i8 %x, i8 %y0, i8 %y1) {
118; CHECK-LABEL: @n7_different_y(
119; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], [[Y0:%.*]]
120; CHECK-NEXT:    call void @use8(i8 [[T0]])
121; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[T0]], [[Y1:%.*]]
122; CHECK-NEXT:    ret i1 [[R]]
123;
124  %t0 = add i8 %x, %y0
125  call void @use8(i8 %t0)
126  %r = icmp ult i8 %t0, %y1
127  ret i1 %r
128}
129
130define i1 @n8_wrong_pred0(i8 %x, i8 %y) {
131; CHECK-LABEL: @n8_wrong_pred0(
132; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
133; CHECK-NEXT:    call void @use8(i8 [[T0]])
134; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[T0]], [[Y]]
135; CHECK-NEXT:    ret i1 [[R]]
136;
137  %t0 = add i8 %x, %y
138  call void @use8(i8 %t0)
139  %r = icmp ule i8 %t0, %y
140  ret i1 %r
141}
142
143define i1 @n9_wrong_pred1(i8 %x, i8 %y) {
144; CHECK-LABEL: @n9_wrong_pred1(
145; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
146; CHECK-NEXT:    call void @use8(i8 [[T0]])
147; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[T0]], [[Y]]
148; CHECK-NEXT:    ret i1 [[R]]
149;
150  %t0 = add i8 %x, %y
151  call void @use8(i8 %t0)
152  %r = icmp ugt i8 %t0, %y
153  ret i1 %r
154}
155
156define i1 @n10_wrong_pred2(i8 %x, i8 %y) {
157; CHECK-LABEL: @n10_wrong_pred2(
158; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
159; CHECK-NEXT:    call void @use8(i8 [[T0]])
160; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X]], 0
161; CHECK-NEXT:    ret i1 [[R]]
162;
163  %t0 = add i8 %x, %y
164  call void @use8(i8 %t0)
165  %r = icmp eq i8 %t0, %y
166  ret i1 %r
167}
168
169define i1 @n11_wrong_pred3(i8 %x, i8 %y) {
170; CHECK-LABEL: @n11_wrong_pred3(
171; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
172; CHECK-NEXT:    call void @use8(i8 [[T0]])
173; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X]], 0
174; CHECK-NEXT:    ret i1 [[R]]
175;
176  %t0 = add i8 %x, %y
177  call void @use8(i8 %t0)
178  %r = icmp ne i8 %t0, %y
179  ret i1 %r
180}
181
182define i1 @n12_wrong_pred4(i8 %x, i8 %y) {
183; CHECK-LABEL: @n12_wrong_pred4(
184; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
185; CHECK-NEXT:    call void @use8(i8 [[T0]])
186; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[T0]], [[Y]]
187; CHECK-NEXT:    ret i1 [[R]]
188;
189  %t0 = add i8 %x, %y
190  call void @use8(i8 %t0)
191  %r = icmp slt i8 %t0, %y
192  ret i1 %r
193}
194
195define i1 @n13_wrong_pred5(i8 %x, i8 %y) {
196; CHECK-LABEL: @n13_wrong_pred5(
197; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
198; CHECK-NEXT:    call void @use8(i8 [[T0]])
199; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[T0]], [[Y]]
200; CHECK-NEXT:    ret i1 [[R]]
201;
202  %t0 = add i8 %x, %y
203  call void @use8(i8 %t0)
204  %r = icmp sle i8 %t0, %y
205  ret i1 %r
206}
207
208define i1 @n14_wrong_pred6(i8 %x, i8 %y) {
209; CHECK-LABEL: @n14_wrong_pred6(
210; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
211; CHECK-NEXT:    call void @use8(i8 [[T0]])
212; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[T0]], [[Y]]
213; CHECK-NEXT:    ret i1 [[R]]
214;
215  %t0 = add i8 %x, %y
216  call void @use8(i8 %t0)
217  %r = icmp sgt i8 %t0, %y
218  ret i1 %r
219}
220
221define i1 @n15_wrong_pred7(i8 %x, i8 %y) {
222; CHECK-LABEL: @n15_wrong_pred7(
223; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
224; CHECK-NEXT:    call void @use8(i8 [[T0]])
225; CHECK-NEXT:    [[R:%.*]] = icmp sge i8 [[T0]], [[Y]]
226; CHECK-NEXT:    ret i1 [[R]]
227;
228  %t0 = add i8 %x, %y
229  call void @use8(i8 %t0)
230  %r = icmp sge i8 %t0, %y
231  ret i1 %r
232}
233