[llvm] cd54c47 - [InstCombine] Match poison instead of undef in foldVectorBinop()
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 18 08:02:07 PST 2023
Author: Nikita Popov
Date: 2023-12-18T17:01:59+01:00
New Revision: cd54c47424456a4dcf8161f3377234cbfa459e88
URL: https://github.com/llvm/llvm-project/commit/cd54c47424456a4dcf8161f3377234cbfa459e88
DIFF: https://github.com/llvm/llvm-project/commit/cd54c47424456a4dcf8161f3377234cbfa459e88.diff
LOG: [InstCombine] Match poison instead of undef in foldVectorBinop()
Some negative tests turn into positive tests, as the differences
between undef and poison propagation allow additional transforms.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll
llvm/test/Transforms/InstCombine/vec_shuffle.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 20ce5e0ede9e5f..4188b5b46e87ed 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1770,9 +1770,9 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
Constant *C;
auto *InstVTy = dyn_cast<FixedVectorType>(Inst.getType());
if (InstVTy &&
- match(&Inst,
- m_c_BinOp(m_OneUse(m_Shuffle(m_Value(V1), m_Undef(), m_Mask(Mask))),
- m_ImmConstant(C))) &&
+ match(&Inst, m_c_BinOp(m_OneUse(m_Shuffle(m_Value(V1), m_Poison(),
+ m_Mask(Mask))),
+ m_ImmConstant(C))) &&
cast<FixedVectorType>(V1->getType())->getNumElements() <=
InstVTy->getNumElements()) {
assert(InstVTy->getScalarType() == V1->getType()->getScalarType() &&
@@ -1787,8 +1787,8 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
ArrayRef<int> ShMask = Mask;
unsigned SrcVecNumElts =
cast<FixedVectorType>(V1->getType())->getNumElements();
- UndefValue *UndefScalar = UndefValue::get(C->getType()->getScalarType());
- SmallVector<Constant *, 16> NewVecC(SrcVecNumElts, UndefScalar);
+ PoisonValue *PoisonScalar = PoisonValue::get(C->getType()->getScalarType());
+ SmallVector<Constant *, 16> NewVecC(SrcVecNumElts, PoisonScalar);
bool MayChange = true;
unsigned NumElts = InstVTy->getNumElements();
for (unsigned I = 0; I < NumElts; ++I) {
@@ -1801,29 +1801,29 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
// 2. The shuffle needs an element of the constant vector that can't
// be mapped to a new constant vector.
// 3. This is a widening shuffle that copies elements of V1 into the
- // extended elements (extending with undef is allowed).
- if (!CElt || (!isa<UndefValue>(NewCElt) && NewCElt != CElt) ||
+ // extended elements (extending with poison is allowed).
+ if (!CElt || (!isa<PoisonValue>(NewCElt) && NewCElt != CElt) ||
I >= SrcVecNumElts) {
MayChange = false;
break;
}
NewVecC[ShMask[I]] = CElt;
}
- // If this is a widening shuffle, we must be able to extend with undef
- // elements. If the original binop does not produce an undef in the high
+ // If this is a widening shuffle, we must be able to extend with poison
+ // elements. If the original binop does not produce a poison in the high
// lanes, then this transform is not safe.
- // Similarly for undef lanes due to the shuffle mask, we can only
- // transform binops that preserve undef.
- // TODO: We could shuffle those non-undef constant values into the
- // result by using a constant vector (rather than an undef vector)
+ // Similarly for poison lanes due to the shuffle mask, we can only
+ // transform binops that preserve poison.
+ // TODO: We could shuffle those non-poison constant values into the
+ // result by using a constant vector (rather than an poison vector)
// as operand 1 of the new binop, but that might be too aggressive
// for target-independent shuffle creation.
if (I >= SrcVecNumElts || ShMask[I] < 0) {
- Constant *MaybeUndef =
+ Constant *MaybePoison =
ConstOp1
- ? ConstantFoldBinaryOpOperands(Opcode, UndefScalar, CElt, DL)
- : ConstantFoldBinaryOpOperands(Opcode, CElt, UndefScalar, DL);
- if (!MaybeUndef || !match(MaybeUndef, m_Undef())) {
+ ? ConstantFoldBinaryOpOperands(Opcode, PoisonScalar, CElt, DL)
+ : ConstantFoldBinaryOpOperands(Opcode, CElt, PoisonScalar, DL);
+ if (!MaybePoison || !isa<PoisonValue>(MaybePoison)) {
MayChange = false;
break;
}
@@ -1831,9 +1831,10 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
}
if (MayChange) {
Constant *NewC = ConstantVector::get(NewVecC);
- // It may not be safe to execute a binop on a vector with undef elements
+ // It may not be safe to execute a binop on a vector with poison elements
// because the entire instruction can be folded to undef or create poison
// that did not exist in the original code.
+ // TODO: The shift case should not be necessary.
if (Inst.isIntDivRem() || (Inst.isShift() && ConstOp1))
NewC = getSafeVectorConstantForBinop(Opcode, NewC, ConstOp1);
diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll b/llvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll
index bedabf4e3456d6..81f0a966dbc968 100644
--- a/llvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll
+++ b/llvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll
@@ -557,7 +557,7 @@ define <4 x i32> @mul_const_splat(<4 x i32> %v) {
define <4 x i32> @lshr_const_half_splat(<4 x i32> %v) {
; CHECK-LABEL: @lshr_const_half_splat(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr <4 x i32> <i32 undef, i32 8, i32 9, i32 undef>, [[V:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = lshr <4 x i32> <i32 poison, i32 8, i32 9, i32 poison>, [[V:%.*]]
; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 2>
; CHECK-NEXT: ret <4 x i32> [[R]]
;
@@ -659,13 +659,12 @@ define <4 x i16> @widening_shuffle_shl_constant_op1(<2 x i16> %v) {
ret <4 x i16> %bo
}
-; A binop that does not produce undef in the high lanes can not be moved before the shuffle.
-; This is not ok because 'shl undef, 1 (or 2)' --> 0' but moving the shuffle results in undef instead.
+; This is valid for poison, but would not be valid for undef.
define <4 x i16> @widening_shuffle_shl_constant_op1_non0(<2 x i16> %v) {
; CHECK-LABEL: @widening_shuffle_shl_constant_op1_non0(
-; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i16> [[V:%.*]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
-; CHECK-NEXT: [[BO:%.*]] = shl <4 x i16> [[SHUF]], <i16 2, i16 4, i16 1, i16 2>
+; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i16> [[V:%.*]], <i16 2, i16 4>
+; CHECK-NEXT: [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
; CHECK-NEXT: ret <4 x i16> [[BO]]
;
%shuf = shufflevector <2 x i16> %v, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
@@ -673,13 +672,10 @@ define <4 x i16> @widening_shuffle_shl_constant_op1_non0(<2 x i16> %v) {
ret <4 x i16> %bo
}
-; A binop that does not produce undef in the high lanes can not be moved before the shuffle.
-; This is not ok because 'or -1, undef --> -1' but moving the shuffle results in undef instead.
-
define <4 x i16> @widening_shuffle_or(<2 x i16> %v) {
; CHECK-LABEL: @widening_shuffle_or(
-; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i16> [[V:%.*]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
-; CHECK-NEXT: [[BO:%.*]] = or <4 x i16> [[SHUF]], <i16 42, i16 -42, i16 -1, i16 -1>
+; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i16> [[V:%.*]], <i16 42, i16 -42>
+; CHECK-NEXT: [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
; CHECK-NEXT: ret <4 x i16> [[BO]]
;
%shuf = shufflevector <2 x i16> %v, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
@@ -856,7 +852,7 @@ define <2 x i32> @mul_splat_constant(<2 x i32> %x) {
define <2 x i32> @shl_splat_constant0(<2 x i32> %x) {
; CHECK-LABEL: @shl_splat_constant0(
-; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> <i32 5, i32 undef>, [[X:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: ret <2 x i32> [[R]]
;
@@ -878,7 +874,7 @@ define <2 x i32> @shl_splat_constant1(<2 x i32> %x) {
define <2 x i32> @ashr_splat_constant0(<2 x i32> %x) {
; CHECK-LABEL: @ashr_splat_constant0(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> <i32 5, i32 undef>, [[X:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: ret <2 x i32> [[R]]
;
@@ -900,7 +896,7 @@ define <2 x i32> @ashr_splat_constant1(<2 x i32> %x) {
define <2 x i32> @lshr_splat_constant0(<2 x i32> %x) {
; CHECK-LABEL: @lshr_splat_constant0(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 undef>, [[X:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: ret <2 x i32> [[R]]
;
@@ -1019,13 +1015,10 @@ define <2 x i32> @and_splat_constant(<2 x i32> %x) {
ret <2 x i32> %r
}
-; AND does not fold to undef for undef operands, we cannot move it
-; across a shuffle with undef masks.
-define <4 x i16> @and_constant_mask_undef(<4 x i16> %add) {
-; CHECK-LABEL: @and_constant_mask_undef(
+define <4 x i16> @and_constant_mask_poison(<4 x i16> %add) {
+; CHECK-LABEL: @and_constant_mask_poison(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
-; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[SHUFFLE]], <i16 0, i16 0, i16 -1, i16 -1>
+; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
; CHECK-NEXT: ret <4 x i16> [[AND]]
;
entry:
@@ -1034,13 +1027,10 @@ entry:
ret <4 x i16> %and
}
-; AND does not fold to undef for undef operands, we cannot move it
-; across a shuffle with undef masks.
-define <4 x i16> @and_constant_mask_undef_2(<4 x i16> %add) {
-; CHECK-LABEL: @and_constant_mask_undef_2(
+define <4 x i16> @and_constant_mask_poison_2(<4 x i16> %add) {
+; CHECK-LABEL: @and_constant_mask_poison_2(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 poison>
-; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[SHUFFLE]], <i16 -1, i16 -1, i16 -1, i16 0>
+; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 poison>
; CHECK-NEXT: ret <4 x i16> [[AND]]
;
entry:
@@ -1050,8 +1040,8 @@ entry:
}
; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.
-define <4 x i16> @and_constant_mask_undef_3(<4 x i16> %add) {
-; CHECK-LABEL: @and_constant_mask_undef_3(
+define <4 x i16> @and_constant_mask_poison_3(<4 x i16> %add) {
+; CHECK-LABEL: @and_constant_mask_poison_3(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret <4 x i16> <i16 0, i16 0, i16 0, i16 undef>
;
@@ -1062,8 +1052,8 @@ entry:
}
; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.
-define <4 x i16> @and_constant_mask_undef_4(<4 x i16> %add) {
-; CHECK-LABEL: @and_constant_mask_undef_4(
+define <4 x i16> @and_constant_mask_poison_4(<4 x i16> %add) {
+; CHECK-LABEL: @and_constant_mask_poison_4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = and <4 x i16> [[ADD:%.*]], <i16 9, i16 20, i16 poison, i16 poison>
; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 poison>
@@ -1088,13 +1078,10 @@ entry:
ret <4 x i16> %and
}
-; OR does not fold to undef for undef operands, we cannot move it
-; across a shuffle with undef masks.
-define <4 x i16> @or_constant_mask_undef(<4 x i16> %in) {
-; CHECK-LABEL: @or_constant_mask_undef(
+define <4 x i16> @or_constant_mask_poison(<4 x i16> %in) {
+; CHECK-LABEL: @or_constant_mask_poison(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
-; CHECK-NEXT: [[OR:%.*]] = or <4 x i16> [[SHUFFLE]], <i16 -1, i16 -1, i16 0, i16 0>
+; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
; CHECK-NEXT: ret <4 x i16> [[OR]]
;
entry:
@@ -1103,13 +1090,10 @@ entry:
ret <4 x i16> %or
}
-; OR does not fold to undef for undef operands, we cannot move it
-; across a shuffle with undef masks.
-define <4 x i16> @or_constant_mask_undef_2(<4 x i16> %in) {
-; CHECK-LABEL: @or_constant_mask_undef_2(
+define <4 x i16> @or_constant_mask_poison_2(<4 x i16> %in) {
+; CHECK-LABEL: @or_constant_mask_poison_2(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>
-; CHECK-NEXT: [[OR:%.*]] = or <4 x i16> [[SHUFFLE]], <i16 -1, i16 0, i16 0, i16 -1>
+; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>
; CHECK-NEXT: ret <4 x i16> [[OR]]
;
entry:
@@ -1119,8 +1103,8 @@ entry:
}
; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.
-define <4 x i16> @or_constant_mask_undef_3(<4 x i16> %in) {
-; CHECK-LABEL: @or_constant_mask_undef_3(
+define <4 x i16> @or_constant_mask_poison_3(<4 x i16> %in) {
+; CHECK-LABEL: @or_constant_mask_poison_3(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret <4 x i16> <i16 undef, i16 -1, i16 -1, i16 undef>
;
@@ -1131,8 +1115,8 @@ entry:
}
; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.
-define <4 x i16> @or_constant_mask_undef_4(<4 x i16> %in) {
-; CHECK-LABEL: @or_constant_mask_undef_4(
+define <4 x i16> @or_constant_mask_poison_4(<4 x i16> %in) {
+; CHECK-LABEL: @or_constant_mask_poison_4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = or <4 x i16> [[IN:%.*]], <i16 poison, i16 99, i16 poison, i16 poison>
; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>
@@ -1160,8 +1144,8 @@ entry:
define <4 x i16> @shl_constant_mask_undef(<4 x i16> %in) {
; CHECK-LABEL: @shl_constant_mask_undef(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 0, i32 poison, i32 1, i32 1>
-; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i16> [[SHUFFLE]], <i16 10, i16 3, i16 0, i16 0>
+; CHECK-NEXT: [[TMP0:%.*]] = shl <4 x i16> [[IN:%.*]], <i16 10, i16 0, i16 0, i16 0>
+; CHECK-NEXT: [[SHL:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 poison, i32 1, i32 1>
; CHECK-NEXT: ret <4 x i16> [[SHL]]
;
entry:
diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle.ll b/llvm/test/Transforms/InstCombine/vec_shuffle.ll
index 0c21dc88f8569e..8eff837d6e1a3f 100644
--- a/llvm/test/Transforms/InstCombine/vec_shuffle.ll
+++ b/llvm/test/Transforms/InstCombine/vec_shuffle.ll
@@ -564,7 +564,7 @@ define <4 x i32> @mul_const_splat(<4 x i32> %v) {
define <4 x i32> @lshr_const_half_splat(<4 x i32> %v) {
; CHECK-LABEL: @lshr_const_half_splat(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr <4 x i32> <i32 undef, i32 8, i32 9, i32 undef>, [[V:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = lshr <4 x i32> <i32 poison, i32 8, i32 9, i32 poison>, [[V:%.*]]
; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 1, i32 1, i32 2, i32 2>
; CHECK-NEXT: ret <4 x i32> [[R]]
;
@@ -666,13 +666,12 @@ define <4 x i16> @widening_shuffle_shl_constant_op1(<2 x i16> %v) {
ret <4 x i16> %bo
}
-; A binop that does not produce undef in the high lanes can not be moved before the shuffle.
-; This is not ok because 'shl undef, 1 (or 2)' --> 0' but moving the shuffle results in undef instead.
+; This is valid for poison, but would not be valid for undef.
define <4 x i16> @widening_shuffle_shl_constant_op1_non0(<2 x i16> %v) {
; CHECK-LABEL: @widening_shuffle_shl_constant_op1_non0(
-; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i16> [[V:%.*]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
-; CHECK-NEXT: [[BO:%.*]] = shl <4 x i16> [[SHUF]], <i16 2, i16 4, i16 1, i16 2>
+; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i16> [[V:%.*]], <i16 2, i16 4>
+; CHECK-NEXT: [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
; CHECK-NEXT: ret <4 x i16> [[BO]]
;
%shuf = shufflevector <2 x i16> %v, <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
@@ -685,8 +684,8 @@ define <4 x i16> @widening_shuffle_shl_constant_op1_non0(<2 x i16> %v) {
define <4 x i16> @widening_shuffle_or(<2 x i16> %v) {
; CHECK-LABEL: @widening_shuffle_or(
-; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i16> [[V:%.*]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
-; CHECK-NEXT: [[BO:%.*]] = or <4 x i16> [[SHUF]], <i16 42, i16 -42, i16 -1, i16 -1>
+; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i16> [[V:%.*]], <i16 42, i16 -42>
+; CHECK-NEXT: [[BO:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
; CHECK-NEXT: ret <4 x i16> [[BO]]
;
%shuf = shufflevector <2 x i16> %v, <2 x i16> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
@@ -863,7 +862,7 @@ define <2 x i32> @mul_splat_constant(<2 x i32> %x) {
define <2 x i32> @shl_splat_constant0(<2 x i32> %x) {
; CHECK-LABEL: @shl_splat_constant0(
-; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> <i32 5, i32 undef>, [[X:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: ret <2 x i32> [[R]]
;
@@ -885,7 +884,7 @@ define <2 x i32> @shl_splat_constant1(<2 x i32> %x) {
define <2 x i32> @ashr_splat_constant0(<2 x i32> %x) {
; CHECK-LABEL: @ashr_splat_constant0(
-; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> <i32 5, i32 undef>, [[X:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: ret <2 x i32> [[R]]
;
@@ -907,7 +906,7 @@ define <2 x i32> @ashr_splat_constant1(<2 x i32> %x) {
define <2 x i32> @lshr_splat_constant0(<2 x i32> %x) {
; CHECK-LABEL: @lshr_splat_constant0(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 undef>, [[X:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> <i32 5, i32 poison>, [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: ret <2 x i32> [[R]]
;
@@ -1026,13 +1025,10 @@ define <2 x i32> @and_splat_constant(<2 x i32> %x) {
ret <2 x i32> %r
}
-; AND does not fold to undef for undef operands, we cannot move it
-; across a shuffle with undef masks.
-define <4 x i16> @and_constant_mask_undef(<4 x i16> %add) {
-; CHECK-LABEL: @and_constant_mask_undef(
+define <4 x i16> @and_constant_mask_poison(<4 x i16> %add) {
+; CHECK-LABEL: @and_constant_mask_poison(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
-; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[SHUFFLE]], <i16 0, i16 0, i16 -1, i16 -1>
+; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
; CHECK-NEXT: ret <4 x i16> [[AND]]
;
entry:
@@ -1041,13 +1037,10 @@ entry:
ret <4 x i16> %and
}
-; AND does not fold to undef for undef operands, we cannot move it
-; across a shuffle with undef masks.
-define <4 x i16> @and_constant_mask_undef_2(<4 x i16> %add) {
-; CHECK-LABEL: @and_constant_mask_undef_2(
+define <4 x i16> @and_constant_mask_poison_2(<4 x i16> %add) {
+; CHECK-LABEL: @and_constant_mask_poison_2(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 poison>
-; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[SHUFFLE]], <i16 -1, i16 -1, i16 -1, i16 0>
+; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[ADD:%.*]], <4 x i16> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 poison>
; CHECK-NEXT: ret <4 x i16> [[AND]]
;
entry:
@@ -1057,8 +1050,8 @@ entry:
}
; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.
-define <4 x i16> @and_constant_mask_undef_3(<4 x i16> %add) {
-; CHECK-LABEL: @and_constant_mask_undef_3(
+define <4 x i16> @and_constant_mask_poison_3(<4 x i16> %add) {
+; CHECK-LABEL: @and_constant_mask_poison_3(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret <4 x i16> <i16 0, i16 0, i16 0, i16 undef>
;
@@ -1069,8 +1062,8 @@ entry:
}
; We can move the AND across the shuffle, as -1 (AND identity value) is used for undef lanes.
-define <4 x i16> @and_constant_mask_undef_4(<4 x i16> %add) {
-; CHECK-LABEL: @and_constant_mask_undef_4(
+define <4 x i16> @and_constant_mask_poison_4(<4 x i16> %add) {
+; CHECK-LABEL: @and_constant_mask_poison_4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = and <4 x i16> [[ADD:%.*]], <i16 9, i16 20, i16 poison, i16 poison>
; CHECK-NEXT: [[AND:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 poison>
@@ -1095,13 +1088,10 @@ entry:
ret <4 x i16> %and
}
-; OR does not fold to undef for undef operands, we cannot move it
-; across a shuffle with undef masks.
-define <4 x i16> @or_constant_mask_undef(<4 x i16> %in) {
-; CHECK-LABEL: @or_constant_mask_undef(
+define <4 x i16> @or_constant_mask_poison(<4 x i16> %in) {
+; CHECK-LABEL: @or_constant_mask_poison(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
-; CHECK-NEXT: [[OR:%.*]] = or <4 x i16> [[SHUFFLE]], <i16 -1, i16 -1, i16 0, i16 0>
+; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 poison, i32 1, i32 1>
; CHECK-NEXT: ret <4 x i16> [[OR]]
;
entry:
@@ -1110,13 +1100,10 @@ entry:
ret <4 x i16> %or
}
-; OR does not fold to undef for undef operands, we cannot move it
-; across a shuffle with undef masks.
-define <4 x i16> @or_constant_mask_undef_2(<4 x i16> %in) {
-; CHECK-LABEL: @or_constant_mask_undef_2(
+define <4 x i16> @or_constant_mask_poison_2(<4 x i16> %in) {
+; CHECK-LABEL: @or_constant_mask_poison_2(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>
-; CHECK-NEXT: [[OR:%.*]] = or <4 x i16> [[SHUFFLE]], <i16 -1, i16 0, i16 0, i16 -1>
+; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>
; CHECK-NEXT: ret <4 x i16> [[OR]]
;
entry:
@@ -1126,8 +1113,8 @@ entry:
}
; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.
-define <4 x i16> @or_constant_mask_undef_3(<4 x i16> %in) {
-; CHECK-LABEL: @or_constant_mask_undef_3(
+define <4 x i16> @or_constant_mask_poison_3(<4 x i16> %in) {
+; CHECK-LABEL: @or_constant_mask_poison_3(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret <4 x i16> <i16 undef, i16 -1, i16 -1, i16 undef>
;
@@ -1138,8 +1125,8 @@ entry:
}
; We can move the OR across the shuffle, as 0 (OR identity value) is used for undef lanes.
-define <4 x i16> @or_constant_mask_undef_4(<4 x i16> %in) {
-; CHECK-LABEL: @or_constant_mask_undef_4(
+define <4 x i16> @or_constant_mask_poison_4(<4 x i16> %in) {
+; CHECK-LABEL: @or_constant_mask_poison_4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = or <4 x i16> [[IN:%.*]], <i16 poison, i16 99, i16 poison, i16 poison>
; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 poison>
@@ -1167,8 +1154,8 @@ entry:
define <4 x i16> @shl_constant_mask_undef(<4 x i16> %in) {
; CHECK-LABEL: @shl_constant_mask_undef(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i16> [[IN:%.*]], <4 x i16> poison, <4 x i32> <i32 0, i32 poison, i32 1, i32 1>
-; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i16> [[SHUFFLE]], <i16 10, i16 3, i16 0, i16 0>
+; CHECK-NEXT: [[TMP0:%.*]] = shl <4 x i16> [[IN:%.*]], <i16 10, i16 0, i16 0, i16 0>
+; CHECK-NEXT: [[SHL:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 poison, i32 1, i32 1>
; CHECK-NEXT: ret <4 x i16> [[SHL]]
;
entry:
More information about the llvm-commits
mailing list