1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; This test case tests the InstructionCombining optimization that
3; reduces things like:
4;   %Y = sext i8 %X to i32
5;   %C = icmp ult i32 %Y, 1024
6; to
7;   %C = i1 true
8; It includes test cases for different constant values, signedness of the
9; cast operands, and types of setCC operators. In all cases, the cast should
10; be eliminated. In many cases the setCC is also eliminated based on the
11; constant value and the range of the casted value.
12;
13; RUN: opt < %s -instcombine -S | FileCheck %s
14
15define i1 @lt_signed_to_large_unsigned(i8 %SB) {
16; CHECK-LABEL: @lt_signed_to_large_unsigned(
17; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i8 %SB, -1
18; CHECK-NEXT:    ret i1 [[C1]]
19;
20  %Y = sext i8 %SB to i32
21  %C = icmp ult i32 %Y, 1024
22  ret i1 %C
23}
24
25; PR28011 - https://llvm.org/bugs/show_bug.cgi?id=28011
26; The above transform only applies to scalar integers; it shouldn't be attempted for constant expressions or vectors.
27
28@a = common global i32** null
29@b = common global [1 x i32] zeroinitializer
30
31define i1 @PR28011(i16 %a) {
32; CHECK-LABEL: @PR28011(
33; CHECK-NEXT:    [[CONV:%.*]] = sext i16 %a to i32
34; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[CONV]], or (i32 zext (i1 icmp ne (i32*** bitcast ([1 x i32]* @b to i32***), i32*** @a) to i32), i32 1)
35; CHECK-NEXT:    ret i1 [[CMP]]
36;
37  %conv = sext i16 %a to i32
38  %cmp = icmp ne i32 %conv, or (i32 zext (i1 icmp ne (i32*** bitcast ([1 x i32]* @b to i32***), i32*** @a) to i32), i32 1)
39  ret i1 %cmp
40}
41
42define <2 x i1> @lt_signed_to_large_unsigned_vec(<2 x i8> %SB) {
43; CHECK-LABEL: @lt_signed_to_large_unsigned_vec(
44; CHECK-NEXT:    [[Y:%.*]] = sext <2 x i8> %SB to <2 x i32>
45; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> [[Y]], <i32 1024, i32 2>
46; CHECK-NEXT:    ret <2 x i1> [[C]]
47;
48  %Y = sext <2 x i8> %SB to <2 x i32>
49  %C = icmp ult <2 x i32> %Y, <i32 1024, i32 2>
50  ret <2 x i1> %C
51}
52
53define i1 @lt_signed_to_large_signed(i8 %SB) {
54; CHECK-LABEL: @lt_signed_to_large_signed(
55; CHECK-NEXT:    ret i1 true
56;
57  %Y = sext i8 %SB to i32
58  %C = icmp slt i32 %Y, 1024
59  ret i1 %C
60}
61
62define i1 @lt_signed_to_large_negative(i8 %SB) {
63; CHECK-LABEL: @lt_signed_to_large_negative(
64; CHECK-NEXT:    ret i1 false
65;
66  %Y = sext i8 %SB to i32
67  %C = icmp slt i32 %Y, -1024
68  ret i1 %C
69}
70
71define i1 @lt_signed_to_small_unsigned(i8 %SB) {
72; CHECK-LABEL: @lt_signed_to_small_unsigned(
73; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 %SB, 17
74; CHECK-NEXT:    ret i1 [[C]]
75;
76  %Y = sext i8 %SB to i32
77  %C = icmp ult i32 %Y, 17
78  ret i1 %C
79}
80
81define i1 @lt_signed_to_small_signed(i8 %SB) {
82; CHECK-LABEL: @lt_signed_to_small_signed(
83; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 %SB, 17
84; CHECK-NEXT:    ret i1 [[C]]
85;
86  %Y = sext i8 %SB to i32
87  %C = icmp slt i32 %Y, 17
88  ret i1 %C
89}
90define i1 @lt_signed_to_small_negative(i8 %SB) {
91; CHECK-LABEL: @lt_signed_to_small_negative(
92; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 %SB, -17
93; CHECK-NEXT:    ret i1 [[C]]
94;
95  %Y = sext i8 %SB to i32
96  %C = icmp slt i32 %Y, -17
97  ret i1 %C
98}
99
100define i1 @lt_unsigned_to_large_unsigned(i8 %SB) {
101; CHECK-LABEL: @lt_unsigned_to_large_unsigned(
102; CHECK-NEXT:    ret i1 true
103;
104  %Y = zext i8 %SB to i32
105  %C = icmp ult i32 %Y, 1024
106  ret i1 %C
107}
108
109define i1 @lt_unsigned_to_large_signed(i8 %SB) {
110; CHECK-LABEL: @lt_unsigned_to_large_signed(
111; CHECK-NEXT:    ret i1 true
112;
113  %Y = zext i8 %SB to i32
114  %C = icmp slt i32 %Y, 1024
115  ret i1 %C
116}
117
118define i1 @lt_unsigned_to_large_negative(i8 %SB) {
119; CHECK-LABEL: @lt_unsigned_to_large_negative(
120; CHECK-NEXT:    ret i1 false
121;
122  %Y = zext i8 %SB to i32
123  %C = icmp slt i32 %Y, -1024
124  ret i1 %C
125}
126
127define i1 @lt_unsigned_to_small_unsigned(i8 %SB) {
128; CHECK-LABEL: @lt_unsigned_to_small_unsigned(
129; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 %SB, 17
130; CHECK-NEXT:    ret i1 [[C]]
131;
132  %Y = zext i8 %SB to i32
133  %C = icmp ult i32 %Y, 17
134  ret i1 %C
135}
136
137define i1 @lt_unsigned_to_small_signed(i8 %SB) {
138; CHECK-LABEL: @lt_unsigned_to_small_signed(
139; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 %SB, 17
140; CHECK-NEXT:    ret i1 [[C]]
141;
142  %Y = zext i8 %SB to i32
143  %C = icmp slt i32 %Y, 17
144  ret i1 %C
145}
146
147define i1 @lt_unsigned_to_small_negative(i8 %SB) {
148; CHECK-LABEL: @lt_unsigned_to_small_negative(
149; CHECK-NEXT:    ret i1 false
150;
151  %Y = zext i8 %SB to i32
152  %C = icmp slt i32 %Y, -17
153  ret i1 %C
154}
155
156define i1 @gt_signed_to_large_unsigned(i8 %SB) {
157; CHECK-LABEL: @gt_signed_to_large_unsigned(
158; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 %SB, 0
159; CHECK-NEXT:    ret i1 [[C]]
160;
161  %Y = sext i8 %SB to i32
162  %C = icmp ugt i32 %Y, 1024
163  ret i1 %C
164}
165
166define i1 @gt_signed_to_large_signed(i8 %SB) {
167; CHECK-LABEL: @gt_signed_to_large_signed(
168; CHECK-NEXT:    ret i1 false
169;
170  %Y = sext i8 %SB to i32
171  %C = icmp sgt i32 %Y, 1024
172  ret i1 %C
173}
174
175define i1 @gt_signed_to_large_negative(i8 %SB) {
176; CHECK-LABEL: @gt_signed_to_large_negative(
177; CHECK-NEXT:    ret i1 true
178;
179  %Y = sext i8 %SB to i32
180  %C = icmp sgt i32 %Y, -1024
181  ret i1 %C
182}
183
184define i1 @gt_signed_to_small_unsigned(i8 %SB) {
185; CHECK-LABEL: @gt_signed_to_small_unsigned(
186; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 %SB, 17
187; CHECK-NEXT:    ret i1 [[C]]
188;
189  %Y = sext i8 %SB to i32
190  %C = icmp ugt i32 %Y, 17
191  ret i1 %C
192}
193
194define i1 @gt_signed_to_small_signed(i8 %SB) {
195; CHECK-LABEL: @gt_signed_to_small_signed(
196; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 %SB, 17
197; CHECK-NEXT:    ret i1 [[C]]
198;
199  %Y = sext i8 %SB to i32
200  %C = icmp sgt i32 %Y, 17
201  ret i1 %C
202}
203
204define i1 @gt_signed_to_small_negative(i8 %SB) {
205; CHECK-LABEL: @gt_signed_to_small_negative(
206; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 %SB, -17
207; CHECK-NEXT:    ret i1 [[C]]
208;
209  %Y = sext i8 %SB to i32
210  %C = icmp sgt i32 %Y, -17
211  ret i1 %C
212}
213
214define i1 @gt_unsigned_to_large_unsigned(i8 %SB) {
215; CHECK-LABEL: @gt_unsigned_to_large_unsigned(
216; CHECK-NEXT:    ret i1 false
217;
218  %Y = zext i8 %SB to i32
219  %C = icmp ugt i32 %Y, 1024
220  ret i1 %C
221}
222
223define i1 @gt_unsigned_to_large_signed(i8 %SB) {
224; CHECK-LABEL: @gt_unsigned_to_large_signed(
225; CHECK-NEXT:    ret i1 false
226;
227  %Y = zext i8 %SB to i32
228  %C = icmp sgt i32 %Y, 1024
229  ret i1 %C
230}
231
232define i1 @gt_unsigned_to_large_negative(i8 %SB) {
233; CHECK-LABEL: @gt_unsigned_to_large_negative(
234; CHECK-NEXT:    ret i1 true
235;
236  %Y = zext i8 %SB to i32
237  %C = icmp sgt i32 %Y, -1024
238  ret i1 %C
239}
240
241define i1 @gt_unsigned_to_small_unsigned(i8 %SB) {
242; CHECK-LABEL: @gt_unsigned_to_small_unsigned(
243; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 %SB, 17
244; CHECK-NEXT:    ret i1 [[C]]
245;
246  %Y = zext i8 %SB to i32
247  %C = icmp ugt i32 %Y, 17
248  ret i1 %C
249}
250
251define i1 @gt_unsigned_to_small_signed(i8 %SB) {
252; CHECK-LABEL: @gt_unsigned_to_small_signed(
253; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 %SB, 17
254; CHECK-NEXT:    ret i1 [[C]]
255;
256  %Y = zext i8 %SB to i32
257  %C = icmp sgt i32 %Y, 17
258  ret i1 %C
259}
260
261define i1 @gt_unsigned_to_small_negative(i8 %SB) {
262; CHECK-LABEL: @gt_unsigned_to_small_negative(
263; CHECK-NEXT:    ret i1 true
264;
265  %Y = zext i8 %SB to i32
266  %C = icmp sgt i32 %Y, -17
267  ret i1 %C
268}
269
270