1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; This test case tests the InstructionCombining optimization that
4 ; %Y = sext i8 %X to i32
5 ; %C = icmp ult i32 %Y, 1024
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.
13 ; RUN: opt < %s -instcombine -S | FileCheck %s
15 define 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]]
20 %Y = sext i8 %SB to i32
21 %C = icmp ult i32 %Y, 1024
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.
28 @a = common global i32** null
29 @b = common global [1 x i32] zeroinitializer
31 define 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]]
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)
42 define <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]]
48 %Y = sext <2 x i8> %SB to <2 x i32>
49 %C = icmp ult <2 x i32> %Y, <i32 1024, i32 2>
53 define i1 @lt_signed_to_large_signed(i8 %SB) {
54 ; CHECK-LABEL: @lt_signed_to_large_signed(
55 ; CHECK-NEXT: ret i1 true
57 %Y = sext i8 %SB to i32
58 %C = icmp slt i32 %Y, 1024
62 define i1 @lt_signed_to_large_negative(i8 %SB) {
63 ; CHECK-LABEL: @lt_signed_to_large_negative(
64 ; CHECK-NEXT: ret i1 false
66 %Y = sext i8 %SB to i32
67 %C = icmp slt i32 %Y, -1024
71 define 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]]
76 %Y = sext i8 %SB to i32
77 %C = icmp ult i32 %Y, 17
81 define 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]]
86 %Y = sext i8 %SB to i32
87 %C = icmp slt i32 %Y, 17
90 define 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]]
95 %Y = sext i8 %SB to i32
96 %C = icmp slt i32 %Y, -17
100 define i1 @lt_unsigned_to_large_unsigned(i8 %SB) {
101 ; CHECK-LABEL: @lt_unsigned_to_large_unsigned(
102 ; CHECK-NEXT: ret i1 true
104 %Y = zext i8 %SB to i32
105 %C = icmp ult i32 %Y, 1024
109 define i1 @lt_unsigned_to_large_signed(i8 %SB) {
110 ; CHECK-LABEL: @lt_unsigned_to_large_signed(
111 ; CHECK-NEXT: ret i1 true
113 %Y = zext i8 %SB to i32
114 %C = icmp slt i32 %Y, 1024
118 define i1 @lt_unsigned_to_large_negative(i8 %SB) {
119 ; CHECK-LABEL: @lt_unsigned_to_large_negative(
120 ; CHECK-NEXT: ret i1 false
122 %Y = zext i8 %SB to i32
123 %C = icmp slt i32 %Y, -1024
127 define 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]]
132 %Y = zext i8 %SB to i32
133 %C = icmp ult i32 %Y, 17
137 define 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]]
142 %Y = zext i8 %SB to i32
143 %C = icmp slt i32 %Y, 17
147 define i1 @lt_unsigned_to_small_negative(i8 %SB) {
148 ; CHECK-LABEL: @lt_unsigned_to_small_negative(
149 ; CHECK-NEXT: ret i1 false
151 %Y = zext i8 %SB to i32
152 %C = icmp slt i32 %Y, -17
156 define 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]]
161 %Y = sext i8 %SB to i32
162 %C = icmp ugt i32 %Y, 1024
166 define i1 @gt_signed_to_large_signed(i8 %SB) {
167 ; CHECK-LABEL: @gt_signed_to_large_signed(
168 ; CHECK-NEXT: ret i1 false
170 %Y = sext i8 %SB to i32
171 %C = icmp sgt i32 %Y, 1024
175 define i1 @gt_signed_to_large_negative(i8 %SB) {
176 ; CHECK-LABEL: @gt_signed_to_large_negative(
177 ; CHECK-NEXT: ret i1 true
179 %Y = sext i8 %SB to i32
180 %C = icmp sgt i32 %Y, -1024
184 define 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]]
189 %Y = sext i8 %SB to i32
190 %C = icmp ugt i32 %Y, 17
194 define 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]]
199 %Y = sext i8 %SB to i32
200 %C = icmp sgt i32 %Y, 17
204 define 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]]
209 %Y = sext i8 %SB to i32
210 %C = icmp sgt i32 %Y, -17
214 define i1 @gt_unsigned_to_large_unsigned(i8 %SB) {
215 ; CHECK-LABEL: @gt_unsigned_to_large_unsigned(
216 ; CHECK-NEXT: ret i1 false
218 %Y = zext i8 %SB to i32
219 %C = icmp ugt i32 %Y, 1024
223 define i1 @gt_unsigned_to_large_signed(i8 %SB) {
224 ; CHECK-LABEL: @gt_unsigned_to_large_signed(
225 ; CHECK-NEXT: ret i1 false
227 %Y = zext i8 %SB to i32
228 %C = icmp sgt i32 %Y, 1024
232 define i1 @gt_unsigned_to_large_negative(i8 %SB) {
233 ; CHECK-LABEL: @gt_unsigned_to_large_negative(
234 ; CHECK-NEXT: ret i1 true
236 %Y = zext i8 %SB to i32
237 %C = icmp sgt i32 %Y, -1024
241 define 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]]
246 %Y = zext i8 %SB to i32
247 %C = icmp ugt i32 %Y, 17
251 define 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]]
256 %Y = zext i8 %SB to i32
257 %C = icmp sgt i32 %Y, 17
261 define i1 @gt_unsigned_to_small_negative(i8 %SB) {
262 ; CHECK-LABEL: @gt_unsigned_to_small_negative(
263 ; CHECK-NEXT: ret i1 true
265 %Y = zext i8 %SB to i32
266 %C = icmp sgt i32 %Y, -17