forked from OSchip/llvm-project
[ValueTracking] look through bitcast of vector in computeKnownBits
This borrows as much as possible from the SDAG version of the code (originally added with D27129 and since updated with big endian support). In IR, we can test more easily for correctness than we did in the original patch. I'm using the simplest cases that I could find for InstSimplify: we computeKnownBits on variable shift amounts to see if they are zero or in range. So shuffle constant elements into a vector, cast it, and shift it. The motivating x86 example from https://llvm.org/PR50123 is also here. We computeKnownBits in the caller code, but we only check if the shift amount is in range. That could be enhanced to catch the 2nd x86 test - if the shift amount is known too big, the result is 0. Alive2 understands the datalayout and agrees that the tests here are correct - example: https://alive2.llvm.org/ce/z/KZJFMZ Differential Revision: https://reviews.llvm.org/D104472
This commit is contained in:
parent
8cfc080132
commit
656001e7b2
|
@ -1182,6 +1182,47 @@ static void computeKnownBitsFromOperator(const Operator *I,
|
||||||
computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
|
computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle cast from vector integer type to scalar or vector integer.
|
||||||
|
auto *SrcVecTy = dyn_cast<FixedVectorType>(SrcTy);
|
||||||
|
if (!SrcVecTy || !SrcVecTy->getElementType()->isIntegerTy() ||
|
||||||
|
!I->getType()->isIntOrIntVectorTy())
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Look through a cast from narrow vector elements to wider type.
|
||||||
|
// Examples: v4i32 -> v2i64, v3i8 -> v24
|
||||||
|
unsigned SubBitWidth = SrcVecTy->getScalarSizeInBits();
|
||||||
|
if (BitWidth % SubBitWidth == 0) {
|
||||||
|
// Known bits are automatically intersected across demanded elements of a
|
||||||
|
// vector. So for example, if a bit is computed as known zero, it must be
|
||||||
|
// zero across all demanded elements of the vector.
|
||||||
|
//
|
||||||
|
// For this bitcast, each demanded element of the output is sub-divided
|
||||||
|
// across a set of smaller vector elements in the source vector. To get
|
||||||
|
// the known bits for an entire element of the output, compute the known
|
||||||
|
// bits for each sub-element sequentially. This is done by shifting the
|
||||||
|
// one-set-bit demanded elements parameter across the sub-elements for
|
||||||
|
// consecutive calls to computeKnownBits. We are using the demanded
|
||||||
|
// elements parameter as a mask operator.
|
||||||
|
//
|
||||||
|
// The known bits of each sub-element are then inserted into place
|
||||||
|
// (dependent on endian) to form the full result of known bits.
|
||||||
|
unsigned NumElts = DemandedElts.getBitWidth();
|
||||||
|
unsigned SubScale = BitWidth / SubBitWidth;
|
||||||
|
APInt SubDemandedElts = APInt::getNullValue(NumElts * SubScale);
|
||||||
|
for (unsigned i = 0; i != NumElts; ++i) {
|
||||||
|
if (DemandedElts[i])
|
||||||
|
SubDemandedElts.setBit(i * SubScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
KnownBits KnownSrc(SubBitWidth);
|
||||||
|
for (unsigned i = 0; i != SubScale; ++i) {
|
||||||
|
computeKnownBits(I->getOperand(0), SubDemandedElts.shl(i), KnownSrc,
|
||||||
|
Depth + 1, Q);
|
||||||
|
unsigned ShiftElt = Q.DL.isLittleEndian() ? i : SubScale - 1 - i;
|
||||||
|
Known.insertBits(KnownSrc, ShiftElt * SubBitWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Instruction::SExt: {
|
case Instruction::SExt: {
|
||||||
|
|
|
@ -2762,14 +2762,18 @@ define <2 x i64> @sse2_psll_q_128_masked(<2 x i64> %v, <2 x i64> %a) {
|
||||||
ret <2 x i64> %2
|
ret <2 x i64> %2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; The shift amount is in range (masked with 31 and high 32-bits are zero),
|
||||||
|
; so convert to standard IR - https://llvm.org/PR50123
|
||||||
|
|
||||||
define <2 x i64> @sse2_psll_q_128_masked_bitcast(<2 x i64> %v, <2 x i64> %a) {
|
define <2 x i64> @sse2_psll_q_128_masked_bitcast(<2 x i64> %v, <2 x i64> %a) {
|
||||||
; CHECK-LABEL: @sse2_psll_q_128_masked_bitcast(
|
; CHECK-LABEL: @sse2_psll_q_128_masked_bitcast(
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x i32>
|
; CHECK-NEXT: [[B:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x i32>
|
||||||
; CHECK-NEXT: [[M:%.*]] = and <4 x i32> [[B]], <i32 31, i32 poison, i32 poison, i32 poison>
|
; CHECK-NEXT: [[M:%.*]] = and <4 x i32> [[B]], <i32 31, i32 poison, i32 poison, i32 poison>
|
||||||
; CHECK-NEXT: [[I:%.*]] = insertelement <4 x i32> [[M]], i32 0, i32 1
|
; CHECK-NEXT: [[I:%.*]] = insertelement <4 x i32> [[M]], i32 0, i32 1
|
||||||
; CHECK-NEXT: [[SHAMT:%.*]] = bitcast <4 x i32> [[I]] to <2 x i64>
|
; CHECK-NEXT: [[SHAMT:%.*]] = bitcast <4 x i32> [[I]] to <2 x i64>
|
||||||
; CHECK-NEXT: [[R:%.*]] = tail call <2 x i64> @llvm.x86.sse2.psll.q(<2 x i64> [[V:%.*]], <2 x i64> [[SHAMT]])
|
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i64> [[SHAMT]], <2 x i64> poison, <2 x i32> zeroinitializer
|
||||||
; CHECK-NEXT: ret <2 x i64> [[R]]
|
; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i64> [[V:%.*]], [[TMP1]]
|
||||||
|
; CHECK-NEXT: ret <2 x i64> [[TMP2]]
|
||||||
;
|
;
|
||||||
%b = bitcast <2 x i64> %a to <4 x i32>
|
%b = bitcast <2 x i64> %a to <4 x i32>
|
||||||
%m = and <4 x i32> %b, <i32 31, i32 poison, i32 poison, i32 poison>
|
%m = and <4 x i32> %b, <i32 31, i32 poison, i32 poison, i32 poison>
|
||||||
|
@ -2779,6 +2783,8 @@ define <2 x i64> @sse2_psll_q_128_masked_bitcast(<2 x i64> %v, <2 x i64> %a) {
|
||||||
ret <2 x i64> %r
|
ret <2 x i64> %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; TODO: This could be recognized as an over-shift.
|
||||||
|
|
||||||
define <2 x i64> @sse2_psll_q_128_masked_bitcast_overshift(<2 x i64> %v, <2 x i64> %a) {
|
define <2 x i64> @sse2_psll_q_128_masked_bitcast_overshift(<2 x i64> %v, <2 x i64> %a) {
|
||||||
; CHECK-LABEL: @sse2_psll_q_128_masked_bitcast_overshift(
|
; CHECK-LABEL: @sse2_psll_q_128_masked_bitcast_overshift(
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x i32>
|
; CHECK-NEXT: [[B:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x i32>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
; RUN: opt < %s -instsimplify -S -data-layout="E" | FileCheck %s
|
; RUN: opt < %s -instsimplify -S -data-layout="E" | FileCheck %s --check-prefixes=CHECK,BIGENDIAN
|
||||||
|
; RUN: opt < %s -instsimplify -S -data-layout="e" | FileCheck %s --check-prefixes=CHECK,LITTLEENDIAN
|
||||||
|
|
||||||
; If any bits of the shift amount are known to make it exceed or equal
|
; If any bits of the shift amount are known to make it exceed or equal
|
||||||
; the number of bits in the type, the shift causes undefined behavior.
|
; the number of bits in the type, the shift causes undefined behavior.
|
||||||
|
@ -223,12 +224,11 @@ define i8 @lshr_cttz_zero_is_undef_vec(<2 x i8> %x) {
|
||||||
ret i8 %ex
|
ret i8 %ex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; The shift amount is 0 on either of high/low bytes. The middle byte doesn't matter.
|
||||||
|
|
||||||
define i24 @bitcast_noshift_scalar(<3 x i8> %v1, i24 %v2) {
|
define i24 @bitcast_noshift_scalar(<3 x i8> %v1, i24 %v2) {
|
||||||
; CHECK-LABEL: @bitcast_noshift_scalar(
|
; CHECK-LABEL: @bitcast_noshift_scalar(
|
||||||
; CHECK-NEXT: [[S:%.*]] = shufflevector <3 x i8> [[V1:%.*]], <3 x i8> <i8 0, i8 poison, i8 poison>, <3 x i32> <i32 3, i32 1, i32 3>
|
; CHECK-NEXT: ret i24 [[V2:%.*]]
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <3 x i8> [[S]] to i24
|
|
||||||
; CHECK-NEXT: [[R:%.*]] = shl i24 [[V2:%.*]], [[B]]
|
|
||||||
; CHECK-NEXT: ret i24 [[R]]
|
|
||||||
;
|
;
|
||||||
%c = insertelement <3 x i8> poison, i8 0, i64 0
|
%c = insertelement <3 x i8> poison, i8 0, i64 0
|
||||||
%s = shufflevector <3 x i8> %v1, <3 x i8> %c, <3 x i32> <i32 3, i32 1, i32 3>
|
%s = shufflevector <3 x i8> %v1, <3 x i8> %c, <3 x i32> <i32 3, i32 1, i32 3>
|
||||||
|
@ -237,12 +237,17 @@ define i24 @bitcast_noshift_scalar(<3 x i8> %v1, i24 %v2) {
|
||||||
ret i24 %r
|
ret i24 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; The shift amount is 0 on low byte of big-endian and unknown on little-endian.
|
||||||
|
|
||||||
define i24 @bitcast_noshift_scalar_bigend(<3 x i8> %v1, i24 %v2) {
|
define i24 @bitcast_noshift_scalar_bigend(<3 x i8> %v1, i24 %v2) {
|
||||||
; CHECK-LABEL: @bitcast_noshift_scalar_bigend(
|
; BIGENDIAN-LABEL: @bitcast_noshift_scalar_bigend(
|
||||||
; CHECK-NEXT: [[S:%.*]] = shufflevector <3 x i8> [[V1:%.*]], <3 x i8> <i8 0, i8 poison, i8 poison>, <3 x i32> <i32 0, i32 1, i32 3>
|
; BIGENDIAN-NEXT: ret i24 [[V2:%.*]]
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <3 x i8> [[S]] to i24
|
;
|
||||||
; CHECK-NEXT: [[R:%.*]] = shl i24 [[V2:%.*]], [[B]]
|
; LITTLEENDIAN-LABEL: @bitcast_noshift_scalar_bigend(
|
||||||
; CHECK-NEXT: ret i24 [[R]]
|
; LITTLEENDIAN-NEXT: [[S:%.*]] = shufflevector <3 x i8> [[V1:%.*]], <3 x i8> <i8 0, i8 poison, i8 poison>, <3 x i32> <i32 0, i32 1, i32 3>
|
||||||
|
; LITTLEENDIAN-NEXT: [[B:%.*]] = bitcast <3 x i8> [[S]] to i24
|
||||||
|
; LITTLEENDIAN-NEXT: [[R:%.*]] = shl i24 [[V2:%.*]], [[B]]
|
||||||
|
; LITTLEENDIAN-NEXT: ret i24 [[R]]
|
||||||
;
|
;
|
||||||
%c = insertelement <3 x i8> poison, i8 0, i64 0
|
%c = insertelement <3 x i8> poison, i8 0, i64 0
|
||||||
%s = shufflevector <3 x i8> %v1, <3 x i8> %c, <3 x i32> <i32 0, i32 1, i32 3>
|
%s = shufflevector <3 x i8> %v1, <3 x i8> %c, <3 x i32> <i32 0, i32 1, i32 3>
|
||||||
|
@ -251,12 +256,17 @@ define i24 @bitcast_noshift_scalar_bigend(<3 x i8> %v1, i24 %v2) {
|
||||||
ret i24 %r
|
ret i24 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; The shift amount is 0 on low byte of little-endian and unknown on big-endian.
|
||||||
|
|
||||||
define i24 @bitcast_noshift_scalar_littleend(<3 x i8> %v1, i24 %v2) {
|
define i24 @bitcast_noshift_scalar_littleend(<3 x i8> %v1, i24 %v2) {
|
||||||
; CHECK-LABEL: @bitcast_noshift_scalar_littleend(
|
; BIGENDIAN-LABEL: @bitcast_noshift_scalar_littleend(
|
||||||
; CHECK-NEXT: [[S:%.*]] = shufflevector <3 x i8> [[V1:%.*]], <3 x i8> <i8 0, i8 poison, i8 poison>, <3 x i32> <i32 3, i32 1, i32 2>
|
; BIGENDIAN-NEXT: [[S:%.*]] = shufflevector <3 x i8> [[V1:%.*]], <3 x i8> <i8 0, i8 poison, i8 poison>, <3 x i32> <i32 3, i32 1, i32 2>
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <3 x i8> [[S]] to i24
|
; BIGENDIAN-NEXT: [[B:%.*]] = bitcast <3 x i8> [[S]] to i24
|
||||||
; CHECK-NEXT: [[R:%.*]] = shl i24 [[V2:%.*]], [[B]]
|
; BIGENDIAN-NEXT: [[R:%.*]] = shl i24 [[V2:%.*]], [[B]]
|
||||||
; CHECK-NEXT: ret i24 [[R]]
|
; BIGENDIAN-NEXT: ret i24 [[R]]
|
||||||
|
;
|
||||||
|
; LITTLEENDIAN-LABEL: @bitcast_noshift_scalar_littleend(
|
||||||
|
; LITTLEENDIAN-NEXT: ret i24 [[V2:%.*]]
|
||||||
;
|
;
|
||||||
%c = insertelement <3 x i8> poison, i8 0, i64 0
|
%c = insertelement <3 x i8> poison, i8 0, i64 0
|
||||||
%s = shufflevector <3 x i8> %v1, <3 x i8> %c, <3 x i32> <i32 3, i32 1, i32 2>
|
%s = shufflevector <3 x i8> %v1, <3 x i8> %c, <3 x i32> <i32 3, i32 1, i32 2>
|
||||||
|
@ -265,12 +275,12 @@ define i24 @bitcast_noshift_scalar_littleend(<3 x i8> %v1, i24 %v2) {
|
||||||
ret i24 %r
|
ret i24 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; The shift amount is known 24 on little-endian and known 24<<16 on big-endian
|
||||||
|
; across all vector elements, so it's an overshift either way.
|
||||||
|
|
||||||
define <3 x i24> @bitcast_overshift_vector(<9 x i8> %v1, <3 x i24> %v2) {
|
define <3 x i24> @bitcast_overshift_vector(<9 x i8> %v1, <3 x i24> %v2) {
|
||||||
; CHECK-LABEL: @bitcast_overshift_vector(
|
; CHECK-LABEL: @bitcast_overshift_vector(
|
||||||
; CHECK-NEXT: [[S:%.*]] = shufflevector <9 x i8> [[V1:%.*]], <9 x i8> <i8 24, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison>, <9 x i32> <i32 9, i32 1, i32 2, i32 9, i32 4, i32 5, i32 9, i32 7, i32 8>
|
; CHECK-NEXT: ret <3 x i24> poison
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <9 x i8> [[S]] to <3 x i24>
|
|
||||||
; CHECK-NEXT: [[R:%.*]] = shl <3 x i24> [[V2:%.*]], [[B]]
|
|
||||||
; CHECK-NEXT: ret <3 x i24> [[R]]
|
|
||||||
;
|
;
|
||||||
%c = insertelement <9 x i8> poison, i8 24, i64 0
|
%c = insertelement <9 x i8> poison, i8 24, i64 0
|
||||||
%s = shufflevector <9 x i8> %v1, <9 x i8> %c, <9 x i32> <i32 9, i32 1, i32 2, i32 9, i32 4, i32 5, i32 9, i32 7, i32 8>
|
%s = shufflevector <9 x i8> %v1, <9 x i8> %c, <9 x i32> <i32 9, i32 1, i32 2, i32 9, i32 4, i32 5, i32 9, i32 7, i32 8>
|
||||||
|
@ -279,12 +289,18 @@ define <3 x i24> @bitcast_overshift_vector(<9 x i8> %v1, <3 x i24> %v2) {
|
||||||
ret <3 x i24> %r
|
ret <3 x i24> %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; The shift amount is known 23 on little-endian and known 23<<16 on big-endian
|
||||||
|
; across all vector elements, so it's an overshift for big-endian.
|
||||||
|
|
||||||
define <3 x i24> @bitcast_overshift_vector_bigend(<9 x i8> %v1, <3 x i24> %v2) {
|
define <3 x i24> @bitcast_overshift_vector_bigend(<9 x i8> %v1, <3 x i24> %v2) {
|
||||||
; CHECK-LABEL: @bitcast_overshift_vector_bigend(
|
; BIGENDIAN-LABEL: @bitcast_overshift_vector_bigend(
|
||||||
; CHECK-NEXT: [[S:%.*]] = shufflevector <9 x i8> [[V1:%.*]], <9 x i8> <i8 23, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison>, <9 x i32> <i32 9, i32 1, i32 2, i32 9, i32 4, i32 5, i32 9, i32 7, i32 8>
|
; BIGENDIAN-NEXT: ret <3 x i24> poison
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <9 x i8> [[S]] to <3 x i24>
|
;
|
||||||
; CHECK-NEXT: [[R:%.*]] = shl <3 x i24> [[V2:%.*]], [[B]]
|
; LITTLEENDIAN-LABEL: @bitcast_overshift_vector_bigend(
|
||||||
; CHECK-NEXT: ret <3 x i24> [[R]]
|
; LITTLEENDIAN-NEXT: [[S:%.*]] = shufflevector <9 x i8> [[V1:%.*]], <9 x i8> <i8 23, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison>, <9 x i32> <i32 9, i32 1, i32 2, i32 9, i32 4, i32 5, i32 9, i32 7, i32 8>
|
||||||
|
; LITTLEENDIAN-NEXT: [[B:%.*]] = bitcast <9 x i8> [[S]] to <3 x i24>
|
||||||
|
; LITTLEENDIAN-NEXT: [[R:%.*]] = shl <3 x i24> [[V2:%.*]], [[B]]
|
||||||
|
; LITTLEENDIAN-NEXT: ret <3 x i24> [[R]]
|
||||||
;
|
;
|
||||||
%c = insertelement <9 x i8> poison, i8 23, i64 0
|
%c = insertelement <9 x i8> poison, i8 23, i64 0
|
||||||
%s = shufflevector <9 x i8> %v1, <9 x i8> %c, <9 x i32> <i32 9, i32 1, i32 2, i32 9, i32 4, i32 5, i32 9, i32 7, i32 8>
|
%s = shufflevector <9 x i8> %v1, <9 x i8> %c, <9 x i32> <i32 9, i32 1, i32 2, i32 9, i32 4, i32 5, i32 9, i32 7, i32 8>
|
||||||
|
@ -293,12 +309,18 @@ define <3 x i24> @bitcast_overshift_vector_bigend(<9 x i8> %v1, <3 x i24> %v2) {
|
||||||
ret <3 x i24> %r
|
ret <3 x i24> %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; The shift amount is known 23 on big-endian and known 23<<16 on little-endian
|
||||||
|
; across all vector elements, so it's an overshift for little-endian.
|
||||||
|
|
||||||
define <3 x i24> @bitcast_overshift_vector_littleend(<9 x i8> %v1, <3 x i24> %v2) {
|
define <3 x i24> @bitcast_overshift_vector_littleend(<9 x i8> %v1, <3 x i24> %v2) {
|
||||||
; CHECK-LABEL: @bitcast_overshift_vector_littleend(
|
; BIGENDIAN-LABEL: @bitcast_overshift_vector_littleend(
|
||||||
; CHECK-NEXT: [[S:%.*]] = shufflevector <9 x i8> [[V1:%.*]], <9 x i8> <i8 23, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison>, <9 x i32> <i32 0, i32 1, i32 9, i32 3, i32 4, i32 9, i32 6, i32 7, i32 9>
|
; BIGENDIAN-NEXT: [[S:%.*]] = shufflevector <9 x i8> [[V1:%.*]], <9 x i8> <i8 23, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison>, <9 x i32> <i32 0, i32 1, i32 9, i32 3, i32 4, i32 9, i32 6, i32 7, i32 9>
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <9 x i8> [[S]] to <3 x i24>
|
; BIGENDIAN-NEXT: [[B:%.*]] = bitcast <9 x i8> [[S]] to <3 x i24>
|
||||||
; CHECK-NEXT: [[R:%.*]] = shl <3 x i24> [[V2:%.*]], [[B]]
|
; BIGENDIAN-NEXT: [[R:%.*]] = shl <3 x i24> [[V2:%.*]], [[B]]
|
||||||
; CHECK-NEXT: ret <3 x i24> [[R]]
|
; BIGENDIAN-NEXT: ret <3 x i24> [[R]]
|
||||||
|
;
|
||||||
|
; LITTLEENDIAN-LABEL: @bitcast_overshift_vector_littleend(
|
||||||
|
; LITTLEENDIAN-NEXT: ret <3 x i24> poison
|
||||||
;
|
;
|
||||||
%c = insertelement <9 x i8> poison, i8 23, i64 0
|
%c = insertelement <9 x i8> poison, i8 23, i64 0
|
||||||
%s = shufflevector <9 x i8> %v1, <9 x i8> %c, <9 x i32> <i32 0, i32 1, i32 9, i32 3, i32 4, i32 9, i32 6, i32 7, i32 9>
|
%s = shufflevector <9 x i8> %v1, <9 x i8> %c, <9 x i32> <i32 0, i32 1, i32 9, i32 3, i32 4, i32 9, i32 6, i32 7, i32 9>
|
||||||
|
@ -307,6 +329,8 @@ define <3 x i24> @bitcast_overshift_vector_littleend(<9 x i8> %v1, <3 x i24> %v2
|
||||||
ret <3 x i24> %r
|
ret <3 x i24> %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Negative test - the shift amount is known 24 or 24<<16 on only 2 out of 3 elements.
|
||||||
|
|
||||||
define <3 x i24> @bitcast_partial_overshift_vector(<9 x i8> %v1, <3 x i24> %v2) {
|
define <3 x i24> @bitcast_partial_overshift_vector(<9 x i8> %v1, <3 x i24> %v2) {
|
||||||
; CHECK-LABEL: @bitcast_partial_overshift_vector(
|
; CHECK-LABEL: @bitcast_partial_overshift_vector(
|
||||||
; CHECK-NEXT: [[S:%.*]] = shufflevector <9 x i8> [[V1:%.*]], <9 x i8> <i8 24, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison>, <9 x i32> <i32 9, i32 1, i32 2, i32 9, i32 4, i32 5, i32 6, i32 7, i32 8>
|
; CHECK-NEXT: [[S:%.*]] = shufflevector <9 x i8> [[V1:%.*]], <9 x i8> <i8 24, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison>, <9 x i32> <i32 9, i32 1, i32 2, i32 9, i32 4, i32 5, i32 6, i32 7, i32 8>
|
||||||
|
@ -321,6 +345,8 @@ define <3 x i24> @bitcast_partial_overshift_vector(<9 x i8> %v1, <3 x i24> %v2)
|
||||||
ret <3 x i24> %r
|
ret <3 x i24> %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Negative test - don't know how to look through a cast with non-integer type (but we could handle this...).
|
||||||
|
|
||||||
define <1 x i64> @bitcast_noshift_vector_wrong_type(<2 x float> %v1, <1 x i64> %v2) {
|
define <1 x i64> @bitcast_noshift_vector_wrong_type(<2 x float> %v1, <1 x i64> %v2) {
|
||||||
; CHECK-LABEL: @bitcast_noshift_vector_wrong_type(
|
; CHECK-LABEL: @bitcast_noshift_vector_wrong_type(
|
||||||
; CHECK-NEXT: [[S:%.*]] = shufflevector <2 x float> [[V1:%.*]], <2 x float> <float 0.000000e+00, float poison>, <2 x i32> <i32 2, i32 1>
|
; CHECK-NEXT: [[S:%.*]] = shufflevector <2 x float> [[V1:%.*]], <2 x float> <float 0.000000e+00, float poison>, <2 x i32> <i32 2, i32 1>
|
||||||
|
|
Loading…
Reference in New Issue