Newer
Older
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -data-layout="n8:16:32" -S | FileCheck %s --check-prefix=ALL --check-prefix=LEGAL8
; RUN: opt < %s -instcombine -data-layout="n16" -S | FileCheck %s --check-prefix=ALL --check-prefix=LEGAL16
; PR35792 - https://bugs.llvm.org/show_bug.cgi?id=35792
define i16 @zext_add(i8 %x) {
; LEGAL8-LABEL: @zext_add(
; LEGAL8-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], 44
; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
; LEGAL8-NEXT: ret i16 [[R]]
;
; LEGAL16-LABEL: @zext_add(
; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16
; LEGAL16-NEXT: [[B:%.*]] = add nuw nsw i16 [[Z]], 44
; LEGAL16-NEXT: [[R:%.*]] = and i16 [[B]], [[Z]]
; LEGAL16-NEXT: ret i16 [[R]]
;
%z = zext i8 %x to i16
%b = add i16 %z, 44
%r = and i16 %b, %z
ret i16 %r
}
define i16 @zext_sub(i8 %x) {
; LEGAL8-LABEL: @zext_sub(
; LEGAL8-NEXT: [[TMP1:%.*]] = sub i8 -5, [[X:%.*]]
; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
; LEGAL8-NEXT: ret i16 [[R]]
;
; LEGAL16-LABEL: @zext_sub(
; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16
; LEGAL16-NEXT: [[B:%.*]] = sub nsw i16 251, [[Z]]
; LEGAL16-NEXT: [[R:%.*]] = and i16 [[B]], [[Z]]
; LEGAL16-NEXT: ret i16 [[R]]
;
%z = zext i8 %x to i16
%b = sub i16 -5, %z
%r = and i16 %b, %z
ret i16 %r
}
define i16 @zext_mul(i8 %x) {
; LEGAL8-LABEL: @zext_mul(
; LEGAL8-NEXT: [[TMP1:%.*]] = mul i8 [[X:%.*]], 3
; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
; LEGAL8-NEXT: ret i16 [[R]]
;
; LEGAL16-LABEL: @zext_mul(
; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16
; LEGAL16-NEXT: [[B:%.*]] = mul nuw nsw i16 [[Z]], 3
; LEGAL16-NEXT: [[R:%.*]] = and i16 [[B]], [[Z]]
; LEGAL16-NEXT: ret i16 [[R]]
;
%z = zext i8 %x to i16
%b = mul i16 %z, 3
%r = and i16 %b, %z
ret i16 %r
}
define i16 @zext_lshr(i8 %x) {
; LEGAL8-LABEL: @zext_lshr(
; LEGAL8-NEXT: [[TMP1:%.*]] = lshr i8 [[X:%.*]], 4
; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
; LEGAL8-NEXT: ret i16 [[R]]
;
; LEGAL16-LABEL: @zext_lshr(
; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16
; LEGAL16-NEXT: [[B:%.*]] = lshr i16 [[Z]], 4
; LEGAL16-NEXT: [[R:%.*]] = and i16 [[B]], [[Z]]
; LEGAL16-NEXT: ret i16 [[R]]
;
%z = zext i8 %x to i16
%b = lshr i16 %z, 4
%r = and i16 %b, %z
ret i16 %r
}
define i16 @zext_ashr(i8 %x) {
; LEGAL8-LABEL: @zext_ashr(
; LEGAL8-NEXT: [[TMP1:%.*]] = lshr i8 [[X:%.*]], 2
; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
; LEGAL8-NEXT: ret i16 [[R]]
;
; LEGAL16-LABEL: @zext_ashr(
; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16
; LEGAL16-NEXT: [[TMP1:%.*]] = lshr i16 [[Z]], 2
; LEGAL16-NEXT: [[R:%.*]] = and i16 [[TMP1]], [[Z]]
; LEGAL16-NEXT: ret i16 [[R]]
;
%z = zext i8 %x to i16
%b = ashr i16 %z, 2
%r = and i16 %b, %z
ret i16 %r
}
define i16 @zext_shl(i8 %x) {
; LEGAL8-LABEL: @zext_shl(
; LEGAL8-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 3
; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
; LEGAL8-NEXT: ret i16 [[R]]
;
; LEGAL16-LABEL: @zext_shl(
; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16
; LEGAL16-NEXT: [[B:%.*]] = shl nuw nsw i16 [[Z]], 3
; LEGAL16-NEXT: [[R:%.*]] = and i16 [[B]], [[Z]]
; LEGAL16-NEXT: ret i16 [[R]]
;
%z = zext i8 %x to i16
%b = shl i16 %z, 3
%r = and i16 %b, %z
ret i16 %r
}
define <2 x i16> @zext_add_vec(<2 x i8> %x) {
; ALL-LABEL: @zext_add_vec(
; ALL-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 44, i8 42>
; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
; ALL-NEXT: ret <2 x i16> [[R]]
;
%z = zext <2 x i8> %x to <2 x i16>
%b = add <2 x i16> %z, <i16 44, i16 42>
%r = and <2 x i16> %b, %z
ret <2 x i16> %r
}
define <2 x i16> @zext_sub_vec(<2 x i8> %x) {
; ALL-LABEL: @zext_sub_vec(
; ALL-NEXT: [[TMP1:%.*]] = sub <2 x i8> <i8 -5, i8 -4>, [[X:%.*]]
; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
; ALL-NEXT: ret <2 x i16> [[R]]
;
%z = zext <2 x i8> %x to <2 x i16>
%b = sub <2 x i16> <i16 -5, i16 -4>, %z
%r = and <2 x i16> %b, %z
ret <2 x i16> %r
}
define <2 x i16> @zext_mul_vec(<2 x i8> %x) {
; ALL-LABEL: @zext_mul_vec(
; ALL-NEXT: [[TMP1:%.*]] = mul <2 x i8> [[X:%.*]], <i8 3, i8 -2>
; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
; ALL-NEXT: ret <2 x i16> [[R]]
;
%z = zext <2 x i8> %x to <2 x i16>
%b = mul <2 x i16> %z, <i16 3, i16 -2>
%r = and <2 x i16> %b, %z
ret <2 x i16> %r
}
define <2 x i16> @zext_lshr_vec(<2 x i8> %x) {
; ALL-LABEL: @zext_lshr_vec(
; ALL-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 4, i8 2>
; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
; ALL-NEXT: ret <2 x i16> [[R]]
;
%z = zext <2 x i8> %x to <2 x i16>
%b = lshr <2 x i16> %z, <i16 4, i16 2>
%r = and <2 x i16> %b, %z
ret <2 x i16> %r
}
define <2 x i16> @zext_ashr_vec(<2 x i8> %x) {
; ALL-LABEL: @zext_ashr_vec(
; ALL-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 2, i8 3>
; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
; ALL-NEXT: ret <2 x i16> [[R]]
;
%z = zext <2 x i8> %x to <2 x i16>
%b = ashr <2 x i16> %z, <i16 2, i16 3>
%r = and <2 x i16> %b, %z
ret <2 x i16> %r
}
define <2 x i16> @zext_shl_vec(<2 x i8> %x) {
; ALL-LABEL: @zext_shl_vec(
; ALL-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 3, i8 2>
; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
; ALL-NEXT: ret <2 x i16> [[R]]
;
%z = zext <2 x i8> %x to <2 x i16>
%b = shl <2 x i16> %z, <i16 3, i16 2>
%r = and <2 x i16> %b, %z
ret <2 x i16> %r
}
; Don't create poison by narrowing a shift below the shift amount.
define <2 x i16> @zext_lshr_vec_overshift(<2 x i8> %x) {
; ALL-LABEL: @zext_lshr_vec_overshift(
; ALL-NEXT: [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16>
; ALL-NEXT: [[B:%.*]] = lshr <2 x i16> [[Z]], <i16 4, i16 8>
; ALL-NEXT: [[R:%.*]] = and <2 x i16> [[B]], [[Z]]
; ALL-NEXT: ret <2 x i16> [[R]]
;
%z = zext <2 x i8> %x to <2 x i16>
%b = lshr <2 x i16> %z, <i16 4, i16 8>
%r = and <2 x i16> %b, %z
ret <2 x i16> %r
}
; Don't create poison by narrowing a shift below the shift amount.
define <2 x i16> @zext_shl_vec_overshift(<2 x i8> %x) {
; ALL-LABEL: @zext_shl_vec_overshift(
; ALL-NEXT: [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16>
; ALL-NEXT: [[B:%.*]] = shl <2 x i16> [[Z]], <i16 8, i16 2>
; ALL-NEXT: [[R:%.*]] = and <2 x i16> [[B]], [[Z]]
; ALL-NEXT: ret <2 x i16> [[R]]
;
%z = zext <2 x i8> %x to <2 x i16>
%b = shl <2 x i16> %z, <i16 8, i16 2>
%r = and <2 x i16> %b, %z
ret <2 x i16> %r
}