1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; Simplify 'shl' inequality test into 'and' equality test.
5 ; (X l<< C2) u</u>= C1 iff C1 is power of 2 -> X & (-C1 l>> C2) ==/!= 0
9 ; C2 Shift amount smaller than C1 trailing zeros.
10 define i1 @scalar_i8_shl_ult_const_1(i8 %x) {
11 ; CHECK-LABEL: @scalar_i8_shl_ult_const_1(
12 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 6
13 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
14 ; CHECK-NEXT: ret i1 [[CMP]]
17 %cmp = icmp ult i8 %shl, 64
21 ; C2 Shift amount equal to C1 trailing zeros.
22 define i1 @scalar_i8_shl_ult_const_2(i8 %x) {
23 ; CHECK-LABEL: @scalar_i8_shl_ult_const_2(
24 ; CHECK-NEXT: [[SHL_MASK:%.*]] = and i8 [[X:%.*]], 3
25 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SHL_MASK]], 0
26 ; CHECK-NEXT: ret i1 [[CMP]]
29 %cmp = icmp ult i8 %shl, 64
33 ; C2 Shift amount greater than C1 trailing zeros.
34 define i1 @scalar_i8_shl_ult_const_3(i8 %x) {
35 ; CHECK-LABEL: @scalar_i8_shl_ult_const_3(
36 ; CHECK-NEXT: [[SHL_MASK:%.*]] = and i8 [[X:%.*]], 1
37 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SHL_MASK]], 0
38 ; CHECK-NEXT: ret i1 [[CMP]]
41 %cmp = icmp ult i8 %shl, 64
45 ; C2 Shift amount smaller than C1 trailing zeros.
46 define i1 @scalar_i16_shl_ult_const(i16 %x) {
47 ; CHECK-LABEL: @scalar_i16_shl_ult_const(
48 ; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], 252
49 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
50 ; CHECK-NEXT: ret i1 [[CMP]]
53 %cmp = icmp ult i16 %shl, 1024
57 define i1 @scalar_i32_shl_ult_const(i32 %x) {
58 ; CHECK-LABEL: @scalar_i32_shl_ult_const(
59 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 2097088
60 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
61 ; CHECK-NEXT: ret i1 [[CMP]]
64 %cmp = icmp ult i32 %shl, 131072
68 define i1 @scalar_i64_shl_ult_const(i64 %x) {
69 ; CHECK-LABEL: @scalar_i64_shl_ult_const(
70 ; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 549755813632
71 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], 0
72 ; CHECK-NEXT: ret i1 [[CMP]]
75 %cmp = icmp ult i64 %shl, 8589934592
79 ; Check 'uge' predicate
80 define i1 @scalar_i8_shl_uge_const(i8 %x) {
81 ; CHECK-LABEL: @scalar_i8_shl_uge_const(
82 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 6
83 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 0
84 ; CHECK-NEXT: ret i1 [[CMP]]
87 %cmp = icmp uge i8 %shl, 64
91 ; Check 'ule' predicate
92 define i1 @scalar_i8_shl_ule_const(i8 %x) {
93 ; CHECK-LABEL: @scalar_i8_shl_ule_const(
94 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 6
95 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
96 ; CHECK-NEXT: ret i1 [[CMP]]
99 %cmp = icmp ule i8 %shl, 63
103 ; Check 'ugt' predicate
104 define i1 @scalar_i8_shl_ugt_const(i8 %x) {
105 ; CHECK-LABEL: @scalar_i8_shl_ugt_const(
106 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 6
107 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 0
108 ; CHECK-NEXT: ret i1 [[CMP]]
111 %cmp = icmp ugt i8 %shl, 63
117 define <4 x i1> @vector_4xi32_shl_ult_const(<4 x i32> %x) {
118 ; CHECK-LABEL: @vector_4xi32_shl_ult_const(
119 ; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[X:%.*]], <i32 2097088, i32 2097088, i32 2097088, i32 2097088>
120 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[TMP1]], zeroinitializer
121 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
123 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 11, i32 11>
124 %cmp = icmp ult <4 x i32> %shl, <i32 131072, i32 131072, i32 131072, i32 131072>
128 define <4 x i1> @vector_4xi32_shl_ult_const_undef1(<4 x i32> %x) {
129 ; CHECK-LABEL: @vector_4xi32_shl_ult_const_undef1(
130 ; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], <i32 11, i32 11, i32 undef, i32 11>
131 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <4 x i32> [[SHL]], <i32 131072, i32 131072, i32 131072, i32 131072>
132 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
134 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 undef, i32 11>
135 %cmp = icmp ult <4 x i32> %shl, <i32 131072, i32 131072, i32 131072, i32 131072>
139 define <4 x i1> @vector_4xi32_shl_ult_const_undef2(<4 x i32> %x) {
140 ; CHECK-LABEL: @vector_4xi32_shl_ult_const_undef2(
141 ; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], <i32 11, i32 11, i32 11, i32 11>
142 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <4 x i32> [[SHL]], <i32 131072, i32 131072, i32 131072, i32 undef>
143 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
145 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 11, i32 11>
146 %cmp = icmp ult <4 x i32> %shl, <i32 131072, i32 131072, i32 131072, i32 undef>
150 define <4 x i1> @vector_4xi32_shl_ult_const_undef3(<4 x i32> %x) {
151 ; CHECK-LABEL: @vector_4xi32_shl_ult_const_undef3(
152 ; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], <i32 11, i32 11, i32 undef, i32 11>
153 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <4 x i32> [[SHL]], <i32 undef, i32 131072, i32 131072, i32 131072>
154 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
156 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 undef, i32 11>
157 %cmp = icmp ult <4 x i32> %shl, <i32 undef, i32 131072, i32 131072, i32 131072>
161 ; Check 'uge' predicate
162 define <4 x i1> @vector_4xi32_shl_uge_const(<4 x i32> %x) {
163 ; CHECK-LABEL: @vector_4xi32_shl_uge_const(
164 ; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[X:%.*]], <i32 2097088, i32 2097088, i32 2097088, i32 2097088>
165 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <4 x i32> [[TMP1]], zeroinitializer
166 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
168 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 11, i32 11>
169 %cmp = icmp uge <4 x i32> %shl, <i32 131072, i32 131072, i32 131072, i32 131072>
173 ; Check 'ule' predicate
174 define <4 x i1> @vector_4xi32_shl_ule_const(<4 x i32> %x) {
175 ; CHECK-LABEL: @vector_4xi32_shl_ule_const(
176 ; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[X:%.*]], <i32 2097088, i32 2097088, i32 2097088, i32 2097088>
177 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[TMP1]], zeroinitializer
178 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
180 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 11, i32 11>
181 %cmp = icmp ule <4 x i32> %shl, <i32 131071, i32 131071, i32 131071, i32 131071>
185 ; Check 'ugt' predicate
186 define <4 x i1> @vector_4xi32_shl_ugt_const(<4 x i32> %x) {
187 ; CHECK-LABEL: @vector_4xi32_shl_ugt_const(
188 ; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[X:%.*]], <i32 2097088, i32 2097088, i32 2097088, i32 2097088>
189 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <4 x i32> [[TMP1]], zeroinitializer
190 ; CHECK-NEXT: ret <4 x i1> [[CMP]]
192 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 11, i32 11>
193 %cmp = icmp ugt <4 x i32> %shl, <i32 131071, i32 131071, i32 131071, i32 131071>
200 define i1 @scalar_i8_shl_ult_const_extra_use_shl(i8 %x, i8* %p) {
201 ; CHECK-LABEL: @scalar_i8_shl_ult_const_extra_use_shl(
202 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 5
203 ; CHECK-NEXT: store i8 [[SHL]], i8* [[P:%.*]], align 1
204 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[SHL]], 64
205 ; CHECK-NEXT: ret i1 [[CMP]]
208 store i8 %shl, i8* %p
209 %cmp = icmp ult i8 %shl, 64
215 ; Check 'slt' predicate
216 define i1 @scalar_i8_shl_slt_const(i8 %x) {
217 ; CHECK-LABEL: @scalar_i8_shl_slt_const(
218 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 5
219 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[SHL]], 64
220 ; CHECK-NEXT: ret i1 [[CMP]]
223 %cmp = icmp slt i8 %shl, 64
227 define i1 @scalar_i8_shl_ugt_const_not_power_of_2(i8 %x) {
228 ; CHECK-LABEL: @scalar_i8_shl_ugt_const_not_power_of_2(
229 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 5
230 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[SHL]], 66
231 ; CHECK-NEXT: ret i1 [[CMP]]
234 %cmp = icmp ugt i8 %shl, 66