Skip to content

Commit 44977a1

Browse files
committed
Add tests for binops with conditions/assume constraints
Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D140849
1 parent 03d136c commit 44977a1

File tree

1 file changed

+264
-0
lines changed

1 file changed

+264
-0
lines changed
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
4+
declare void @use64(i64)
5+
declare void @llvm.assume(i1)
6+
7+
define i1 @mul_unkV_oddC_eq(i32 %v) {
8+
; CHECK-LABEL: @mul_unkV_oddC_eq(
9+
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[V:%.*]], 3
10+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MUL]], 0
11+
; CHECK-NEXT: ret i1 [[CMP]]
12+
;
13+
%mul = mul i32 %v, 3
14+
%cmp = icmp eq i32 %mul, 0
15+
ret i1 %cmp
16+
}
17+
18+
define i1 @mul_unkV_oddC_eq_nonzero(i32 %v) {
19+
; CHECK-LABEL: @mul_unkV_oddC_eq_nonzero(
20+
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[V:%.*]], 3
21+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MUL]], 4
22+
; CHECK-NEXT: ret i1 [[CMP]]
23+
;
24+
%mul = mul i32 %v, 3
25+
%cmp = icmp eq i32 %mul, 4
26+
ret i1 %cmp
27+
}
28+
29+
define <2 x i1> @mul_unkV_oddC_ne_vec(<2 x i64> %v) {
30+
; CHECK-LABEL: @mul_unkV_oddC_ne_vec(
31+
; CHECK-NEXT: [[MUL:%.*]] = mul <2 x i64> [[V:%.*]], <i64 3, i64 3>
32+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i64> [[MUL]], zeroinitializer
33+
; CHECK-NEXT: ret <2 x i1> [[CMP]]
34+
;
35+
%mul = mul <2 x i64> %v, <i64 3, i64 3>
36+
%cmp = icmp ne <2 x i64> %mul, <i64 0, i64 0>
37+
ret <2 x i1> %cmp
38+
}
39+
40+
define i1 @mul_assumeoddV_asumeoddV_eq(i16 %v, i16 %v2) {
41+
; CHECK-LABEL: @mul_assumeoddV_asumeoddV_eq(
42+
; CHECK-NEXT: [[LB:%.*]] = and i16 [[V:%.*]], 1
43+
; CHECK-NEXT: [[ODD:%.*]] = icmp ne i16 [[LB]], 0
44+
; CHECK-NEXT: call void @llvm.assume(i1 [[ODD]])
45+
; CHECK-NEXT: [[LB2:%.*]] = and i16 [[V2:%.*]], 1
46+
; CHECK-NEXT: [[ODD2:%.*]] = icmp ne i16 [[LB2]], 0
47+
; CHECK-NEXT: call void @llvm.assume(i1 [[ODD2]])
48+
; CHECK-NEXT: ret i1 true
49+
;
50+
%lb = and i16 %v, 1
51+
%odd = icmp ne i16 %lb, 0
52+
call void @llvm.assume(i1 %odd)
53+
%lb2 = and i16 %v2, 1
54+
%odd2 = icmp ne i16 %lb2, 0
55+
call void @llvm.assume(i1 %odd2)
56+
%mul = mul i16 %v, %v2
57+
%cmp = icmp ne i16 %mul, 0
58+
ret i1 %cmp
59+
}
60+
61+
define i1 @mul_unkV_oddC_sge(i8 %v) {
62+
; CHECK-LABEL: @mul_unkV_oddC_sge(
63+
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[V:%.*]], 3
64+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[MUL]], -1
65+
; CHECK-NEXT: ret i1 [[CMP]]
66+
;
67+
%mul = mul i8 %v, 3
68+
%cmp = icmp sge i8 %mul, 0
69+
ret i1 %cmp
70+
}
71+
72+
define i1 @mul_reused_unkV_oddC_ne(i64 %v) {
73+
; CHECK-LABEL: @mul_reused_unkV_oddC_ne(
74+
; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[V:%.*]], 3
75+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[MUL]], 0
76+
; CHECK-NEXT: call void @use64(i64 [[MUL]])
77+
; CHECK-NEXT: ret i1 [[CMP]]
78+
;
79+
%mul = mul i64 %v, 3
80+
%cmp = icmp ne i64 %mul, 0
81+
call void @use64(i64 %mul)
82+
ret i1 %cmp
83+
}
84+
85+
define i1 @mul_assumeoddV_unkV_eq(i16 %v, i16 %v2) {
86+
; CHECK-LABEL: @mul_assumeoddV_unkV_eq(
87+
; CHECK-NEXT: [[LB:%.*]] = and i16 [[V2:%.*]], 1
88+
; CHECK-NEXT: [[ODD:%.*]] = icmp ne i16 [[LB]], 0
89+
; CHECK-NEXT: call void @llvm.assume(i1 [[ODD]])
90+
; CHECK-NEXT: [[MUL:%.*]] = mul i16 [[V:%.*]], [[V2]]
91+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[MUL]], 0
92+
; CHECK-NEXT: ret i1 [[CMP]]
93+
;
94+
%lb = and i16 %v2, 1
95+
%odd = icmp eq i16 %lb, 1
96+
call void @llvm.assume(i1 %odd)
97+
%mul = mul i16 %v, %v2
98+
%cmp = icmp eq i16 %mul, 0
99+
ret i1 %cmp
100+
}
101+
102+
define i1 @mul_reusedassumeoddV_unkV_ne(i64 %v, i64 %v2) {
103+
; CHECK-LABEL: @mul_reusedassumeoddV_unkV_ne(
104+
; CHECK-NEXT: [[LB:%.*]] = and i64 [[V:%.*]], 1
105+
; CHECK-NEXT: [[ODD:%.*]] = icmp ne i64 [[LB]], 0
106+
; CHECK-NEXT: call void @llvm.assume(i1 [[ODD]])
107+
; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[V]], [[V2:%.*]]
108+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[MUL]], 0
109+
; CHECK-NEXT: call void @use64(i64 [[MUL]])
110+
; CHECK-NEXT: ret i1 [[CMP]]
111+
;
112+
%lb = and i64 %v, 1
113+
%odd = icmp ne i64 %lb, 0
114+
call void @llvm.assume(i1 %odd)
115+
%mul = mul i64 %v, %v2
116+
%cmp = icmp ne i64 %mul, 0
117+
call void @use64(i64 %mul)
118+
ret i1 %cmp
119+
}
120+
121+
define <2 x i1> @mul_setoddV_unkV_ne(<2 x i32> %v1, <2 x i32> %v2) {
122+
; CHECK-LABEL: @mul_setoddV_unkV_ne(
123+
; CHECK-NEXT: [[V:%.*]] = or <2 x i32> [[V1:%.*]], <i32 1, i32 1>
124+
; CHECK-NEXT: [[MUL:%.*]] = mul <2 x i32> [[V]], [[V2:%.*]]
125+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[MUL]], zeroinitializer
126+
; CHECK-NEXT: ret <2 x i1> [[CMP]]
127+
;
128+
%v = or <2 x i32> %v1, <i32 1, i32 1>
129+
%mul = mul <2 x i32> %v, %v2
130+
%cmp = icmp ne <2 x i32> %mul, <i32 0, i32 0>
131+
ret <2 x i1> %cmp
132+
}
133+
134+
define i1 @mul_broddV_unkV_eq(i16 %v, i16 %v2) {
135+
; CHECK-LABEL: @mul_broddV_unkV_eq(
136+
; CHECK-NEXT: [[LB:%.*]] = and i16 [[V2:%.*]], 1
137+
; CHECK-NEXT: [[ODD_NOT:%.*]] = icmp eq i16 [[LB]], 0
138+
; CHECK-NEXT: br i1 [[ODD_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
139+
; CHECK: true:
140+
; CHECK-NEXT: [[MUL:%.*]] = mul i16 [[V:%.*]], [[V2]]
141+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[MUL]], 0
142+
; CHECK-NEXT: ret i1 [[CMP]]
143+
; CHECK: false:
144+
; CHECK-NEXT: call void @use64(i16 [[V]])
145+
; CHECK-NEXT: ret i1 false
146+
;
147+
%lb = and i16 %v2, 1
148+
%odd = icmp eq i16 %lb, 1
149+
br i1 %odd, label %true, label %false
150+
true:
151+
%mul = mul i16 %v, %v2
152+
%cmp = icmp eq i16 %mul, 0
153+
ret i1 %cmp
154+
false:
155+
call void @use64(i16 %v)
156+
ret i1 false
157+
}
158+
159+
define i1 @mul_unkV_evenC_ne(i64 %v) {
160+
; CHECK-LABEL: @mul_unkV_evenC_ne(
161+
; CHECK-NEXT: [[MUL_MASK:%.*]] = and i64 [[V:%.*]], 4611686018427387903
162+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[MUL_MASK]], 0
163+
; CHECK-NEXT: ret i1 [[CMP]]
164+
;
165+
%mul = mul i64 %v, 4
166+
%cmp = icmp ne i64 %mul, 0
167+
ret i1 %cmp
168+
}
169+
170+
define i1 @mul_assumenzV_asumenzV_eq(i64 %v, i64 %v2) {
171+
; CHECK-LABEL: @mul_assumenzV_asumenzV_eq(
172+
; CHECK-NEXT: [[NZ:%.*]] = icmp ne i64 [[V:%.*]], 0
173+
; CHECK-NEXT: call void @llvm.assume(i1 [[NZ]])
174+
; CHECK-NEXT: [[NZ2:%.*]] = icmp ne i64 [[V2:%.*]], 0
175+
; CHECK-NEXT: call void @llvm.assume(i1 [[NZ2]])
176+
; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[V]], [[V2]]
177+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[MUL]], 0
178+
; CHECK-NEXT: ret i1 [[CMP]]
179+
;
180+
%nz = icmp ne i64 %v, 0
181+
call void @llvm.assume(i1 %nz)
182+
%nz2 = icmp ne i64 %v2, 0
183+
call void @llvm.assume(i1 %nz2)
184+
%mul = mul i64 %v, %v2
185+
%cmp = icmp eq i64 %mul, 0
186+
ret i1 %cmp
187+
}
188+
189+
define i1 @mul_assumenzV_unkV_nsw_ne(i32 %v, i32 %v2) {
190+
; CHECK-LABEL: @mul_assumenzV_unkV_nsw_ne(
191+
; CHECK-NEXT: [[NZ:%.*]] = icmp ne i32 [[V:%.*]], 0
192+
; CHECK-NEXT: call void @llvm.assume(i1 [[NZ]])
193+
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[V]], [[V2:%.*]]
194+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MUL]], 0
195+
; CHECK-NEXT: ret i1 [[CMP]]
196+
;
197+
%nz = icmp ne i32 %v, 0
198+
call void @llvm.assume(i1 %nz)
199+
%mul = mul nsw i32 %v, %v2
200+
%cmp = icmp ne i32 %mul, 0
201+
ret i1 %cmp
202+
}
203+
204+
define i1 @mul_selectnzV_unkV_nsw_ne(i8 %v, i8 %v2) {
205+
; CHECK-LABEL: @mul_selectnzV_unkV_nsw_ne(
206+
; CHECK-NEXT: [[NZ:%.*]] = icmp ne i8 [[V:%.*]], 0
207+
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i8 [[V]], [[V2:%.*]]
208+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[MUL]], 0
209+
; CHECK-NEXT: [[R:%.*]] = select i1 [[NZ]], i1 [[CMP]], i1 false
210+
; CHECK-NEXT: ret i1 [[R]]
211+
;
212+
%nz = icmp ne i8 %v, 0
213+
%mul = mul nsw i8 %v, %v2
214+
%cmp = icmp ne i8 %mul, 0
215+
%r = select i1 %nz, i1 %cmp, i1 false
216+
ret i1 %r
217+
}
218+
219+
define <2 x i1> @mul_unkV_unkV_nsw_nuw_ne(<2 x i16> %v, <2 x i16> %v2) {
220+
; CHECK-LABEL: @mul_unkV_unkV_nsw_nuw_ne(
221+
; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw <2 x i16> [[V:%.*]], [[V2:%.*]]
222+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i16> [[MUL]], zeroinitializer
223+
; CHECK-NEXT: ret <2 x i1> [[CMP]]
224+
;
225+
%mul = mul nuw nsw <2 x i16> %v, %v2
226+
%cmp = icmp ne <2 x i16> %mul, <i16 0, i16 0>
227+
ret <2 x i1> %cmp
228+
}
229+
230+
define i1 @mul_setnzV_unkV_nuw_eq(i8 %v1, i8 %v2) {
231+
; CHECK-LABEL: @mul_setnzV_unkV_nuw_eq(
232+
; CHECK-NEXT: [[V:%.*]] = or i8 [[V1:%.*]], 2
233+
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i8 [[V]], [[V2:%.*]]
234+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[MUL]], 0
235+
; CHECK-NEXT: ret i1 [[CMP]]
236+
;
237+
%v = or i8 %v1, 2
238+
%mul = mul nuw i8 %v, %v2
239+
%cmp = icmp eq i8 %mul, 0
240+
ret i1 %cmp
241+
}
242+
243+
define i1 @mul_brnzV_unkV_nuw_eq(i64 %v, i64 %v2) {
244+
; CHECK-LABEL: @mul_brnzV_unkV_nuw_eq(
245+
; CHECK-NEXT: [[NZ_NOT:%.*]] = icmp eq i64 [[V2:%.*]], 0
246+
; CHECK-NEXT: br i1 [[NZ_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
247+
; CHECK: true:
248+
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[V:%.*]], [[V2]]
249+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[MUL]], 0
250+
; CHECK-NEXT: ret i1 [[CMP]]
251+
; CHECK: false:
252+
; CHECK-NEXT: call void @use64(i64 [[V]])
253+
; CHECK-NEXT: ret i1 false
254+
;
255+
%nz = icmp ne i64 %v2, 0
256+
br i1 %nz, label %true, label %false
257+
true:
258+
%mul = mul nuw i64 %v, %v2
259+
%cmp = icmp eq i64 %mul, 0
260+
ret i1 %cmp
261+
false:
262+
call void @use64(i64 %v)
263+
ret i1 false
264+
}

0 commit comments

Comments
 (0)