Skip to content

Commit 6eb47bb

Browse files
authored
[InstCombine] Migrate undef -> poison only for certain cast-related optimizations (#201631)
Further deprecate UndefValue by restricting several related optimizations in InstCombineCasts to PoisonValue only. Update regression tests to reflect these changes.
1 parent 2853284 commit 6eb47bb

5 files changed

Lines changed: 67 additions & 68 deletions

File tree

llvm/include/llvm/IR/PatternMatch.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,6 +1978,10 @@ struct m_SpecificMask {
19781978
bool match(ArrayRef<int> Mask) const { return Val == Mask; }
19791979
};
19801980

1981+
struct m_SplatMask {
1982+
bool match(ArrayRef<int> Mask) const { return all_equal(Mask); }
1983+
};
1984+
19811985
struct m_SplatOrPoisonMask {
19821986
int &SplatIndex;
19831987
m_SplatOrPoisonMask(int &SplatIndex) : SplatIndex(SplatIndex) {}

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ Instruction *InstCombinerImpl::commonCastTransforms(CastInst &CI) {
269269
// cast (shuffle X, Mask) --> shuffle (cast X), Mask
270270
Value *X;
271271
ArrayRef<int> Mask;
272-
if (match(Src, m_OneUse(m_Shuffle(m_Value(X), m_Undef(), m_Mask(Mask))))) {
272+
if (match(Src, m_OneUse(m_Shuffle(m_Value(X), m_Poison(), m_Mask(Mask))))) {
273273
// TODO: Allow scalable vectors?
274274
auto *SrcTy = dyn_cast<FixedVectorType>(X->getType());
275275
auto *DestTy = dyn_cast<FixedVectorType>(Ty);
@@ -977,25 +977,26 @@ Instruction *InstCombinerImpl::narrowBinOp(TruncInst &Trunc) {
977977
/// creating a shuffle type that targets may not be able to lower effectively.
978978
static Instruction *shrinkSplatShuffle(TruncInst &Trunc,
979979
InstCombiner::BuilderTy &Builder) {
980-
auto *Shuf = dyn_cast<ShuffleVectorInst>(Trunc.getOperand(0));
981-
if (Shuf && Shuf->hasOneUse() && match(Shuf->getOperand(1), m_Undef()) &&
982-
all_equal(Shuf->getShuffleMask()) &&
983-
ElementCount::isKnownGE(Shuf->getType()->getElementCount(),
984-
cast<VectorType>(Shuf->getOperand(0)->getType())
985-
->getElementCount())) {
986-
// trunc (shuf X, Undef, SplatMask) --> shuf (trunc X), Poison, SplatMask
987-
// trunc (shuf X, Poison, SplatMask) --> shuf (trunc X), Poison, SplatMask
988-
Type *NewTruncTy = Shuf->getOperand(0)->getType()->getWithNewType(
989-
Trunc.getType()->getScalarType());
990-
Value *NarrowOp = Builder.CreateTrunc(Shuf->getOperand(0), NewTruncTy);
991-
return new ShuffleVectorInst(NarrowOp, Shuf->getShuffleMask());
980+
Value *Shuf = Trunc.getOperand(0), *ShufVec;
981+
ArrayRef<int> SplatMask;
982+
if (match(Shuf, m_OneUse(m_Shuffle(m_Value(ShufVec), m_Poison(),
983+
m_Mask(SplatMask)))) &&
984+
match(SplatMask, m_SplatMask()) &&
985+
ElementCount::isKnownGE(
986+
cast<VectorType>(Shuf->getType())->getElementCount(),
987+
cast<VectorType>(ShufVec->getType())->getElementCount())) {
988+
// trunc (shuf X, poison, SplatMask) --> shuf (trunc X), poison, SplatMask
989+
Type *NewTruncTy =
990+
ShufVec->getType()->getWithNewType(Trunc.getType()->getScalarType());
991+
Value *NarrowOp = Builder.CreateTrunc(ShufVec, NewTruncTy);
992+
return new ShuffleVectorInst(NarrowOp, SplatMask);
992993
}
993994

994995
return nullptr;
995996
}
996997

997998
/// Try to narrow the width of an insert element. This could be generalized for
998-
/// any vector constant, but we limit the transform to insertion into undef to
999+
/// any vector constant, but we limit the transform to insertion into poison to
9991000
/// avoid potential backend problems from unsupported insertion widths. This
10001001
/// could also be extended to handle the case of inserting a scalar constant
10011002
/// into a vector variable.
@@ -1005,22 +1006,15 @@ static Instruction *shrinkInsertElt(CastInst &Trunc,
10051006
assert((Opcode == Instruction::Trunc || Opcode == Instruction::FPTrunc) &&
10061007
"Unexpected instruction for shrinking");
10071008

1008-
auto *InsElt = dyn_cast<InsertElementInst>(Trunc.getOperand(0));
1009-
if (!InsElt || !InsElt->hasOneUse())
1010-
return nullptr;
1011-
1012-
Type *DestTy = Trunc.getType();
1013-
Type *DestScalarTy = DestTy->getScalarType();
1014-
Value *VecOp = InsElt->getOperand(0);
1015-
Value *ScalarOp = InsElt->getOperand(1);
1016-
Value *Index = InsElt->getOperand(2);
1017-
1018-
if (match(VecOp, m_Undef())) {
1019-
// trunc (inselt undef, X, Index) --> inselt undef, (trunc X), Index
1020-
// fptrunc (inselt undef, X, Index) --> inselt undef, (fptrunc X), Index
1021-
UndefValue *NarrowUndef = UndefValue::get(DestTy);
1022-
Value *NarrowOp = Builder.CreateCast(Opcode, ScalarOp, DestScalarTy);
1023-
return InsertElementInst::Create(NarrowUndef, NarrowOp, Index);
1009+
Value *Elt, *Index;
1010+
if (match(Trunc.getOperand(0),
1011+
m_OneUse(m_InsertElt(m_Poison(), m_Value(Elt), m_Value(Index))))) {
1012+
// trunc (inselt poison, X, Index) --> inselt poison, (trunc X), Index
1013+
// fptrunc (inselt poison, X, Index) --> inselt poison, (fptrunc X), Index
1014+
auto *NarrowPoison = PoisonValue::get(Trunc.getType());
1015+
Value *NarrowOp =
1016+
Builder.CreateCast(Opcode, Elt, Trunc.getType()->getScalarType());
1017+
return InsertElementInst::Create(NarrowPoison, NarrowOp, Index);
10241018
}
10251019

10261020
return nullptr;
@@ -2069,11 +2063,11 @@ static Type *shrinkFPConstantVector(Value *V, bool PreferBFloat) {
20692063

20702064
// For fixed-width vectors we find the minimal type by looking
20712065
// through the constant values of the vector.
2072-
for (unsigned i = 0; i != NumElts; ++i) {
2073-
if (isa<UndefValue>(CV->getAggregateElement(i)))
2066+
for (unsigned I = 0; I != NumElts; ++I) {
2067+
if (match(CV->getAggregateElement(I), m_Poison()))
20742068
continue;
20752069

2076-
auto *CFP = dyn_cast_or_null<ConstantFP>(CV->getAggregateElement(i));
2070+
auto *CFP = dyn_cast_or_null<ConstantFP>(CV->getAggregateElement(I));
20772071
if (!CFP)
20782072
return nullptr;
20792073

@@ -2763,8 +2757,9 @@ static bool collectInsertionElements(Value *V, unsigned Shift,
27632757
assert(isMultipleOfTypeSize(Shift, VecEltTy) &&
27642758
"Shift should be a multiple of the element type size");
27652759

2766-
// Undef values never contribute useful bits to the result.
2767-
if (isa<UndefValue>(V)) return true;
2760+
// Poison values never contribute useful bits to the result.
2761+
if (match(V, m_Poison()))
2762+
return true;
27682763

27692764
// If we got down to a value of the right type, we win, try inserting into the
27702765
// right element.

llvm/test/Transforms/InstCombine/fpextend.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,14 @@ define <2 x float> @test6(<2 x float> %x) nounwind {
8282
ret <2 x float> %t34
8383
}
8484

85-
; Test with an undef element
86-
define <2 x float> @test6_undef(<2 x float> %x) nounwind {
87-
; CHECK-LABEL: @test6_undef(
88-
; CHECK-NEXT: [[T34:%.*]] = fadd <2 x float> [[X:%.*]], <float 0.000000e+00, float undef>
85+
; Test with a poison element
86+
define <2 x float> @test6_poison(<2 x float> %x) nounwind {
87+
; CHECK-LABEL: @test6_poison(
88+
; CHECK-NEXT: [[T34:%.*]] = fadd <2 x float> [[X:%.*]], <float 0.000000e+00, float poison>
8989
; CHECK-NEXT: ret <2 x float> [[T34]]
9090
;
9191
%t1 = fpext <2 x float> %x to <2 x double>
92-
%t3 = fadd <2 x double> %t1, <double 0.000000e+00, double undef>
92+
%t3 = fadd <2 x double> %t1, <double 0.000000e+00, double poison>
9393
%t34 = fptrunc <2 x double> %t3 to <2 x float>
9494
ret <2 x float> %t34
9595
}

llvm/test/Transforms/InstCombine/vector-casts-inseltpoison.ll

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -288,30 +288,30 @@ define <8 x i32> @pr24458(<8 x float> %n) {
288288
ret <8 x i32> %wrong
289289
}
290290

291-
; Hoist a trunc to a scalar if we're inserting into an undef vector.
292-
; trunc (inselt undef, X, Index) --> inselt undef, (trunc X), Index
291+
; Hoist a trunc to a scalar if we're inserting into a poison vector.
292+
; trunc (inselt poison, X, Index) --> inselt poison, (trunc X), Index
293293

294-
define <3 x i16> @trunc_inselt_undef(i32 %x) {
295-
; CHECK-LABEL: @trunc_inselt_undef(
294+
define <3 x i16> @trunc_inselt_poison(i32 %x, i32 %index) {
295+
; CHECK-LABEL: @trunc_inselt_poison(
296296
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
297-
; CHECK-NEXT: [[TRUNC:%.*]] = insertelement <3 x i16> <i16 undef, i16 poison, i16 undef>, i16 [[TMP1]], i64 1
297+
; CHECK-NEXT: [[TRUNC:%.*]] = insertelement <3 x i16> poison, i16 [[TMP1]], i32 [[INDEX:%.*]]
298298
; CHECK-NEXT: ret <3 x i16> [[TRUNC]]
299299
;
300-
%vec = insertelement <3 x i32> poison, i32 %x, i32 1
300+
%vec = insertelement <3 x i32> poison, i32 %x, i32 %index
301301
%trunc = trunc <3 x i32> %vec to <3 x i16>
302302
ret <3 x i16> %trunc
303303
}
304304

305-
; Hoist a trunc to a scalar if we're inserting into an undef vector.
306-
; trunc (inselt undef, X, Index) --> inselt undef, (trunc X), Index
305+
; Hoist a trunc to a scalar if we're inserting into a poison vector.
306+
; trunc (inselt poison, X, Index) --> inselt poison, (trunc X), Index
307307

308-
define <2 x float> @fptrunc_inselt_undef(double %x, i32 %index) {
309-
; CHECK-LABEL: @fptrunc_inselt_undef(
308+
define <2 x float> @fptrunc_inselt_poison(double %x, i32 %index) {
309+
; CHECK-LABEL: @fptrunc_inselt_poison(
310310
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[X:%.*]] to float
311-
; CHECK-NEXT: [[TRUNC:%.*]] = insertelement <2 x float> undef, float [[TMP1]], i32 [[INDEX:%.*]]
311+
; CHECK-NEXT: [[TRUNC:%.*]] = insertelement <2 x float> poison, float [[TMP1]], i32 [[INDEX:%.*]]
312312
; CHECK-NEXT: ret <2 x float> [[TRUNC]]
313313
;
314-
%vec = insertelement <2 x double> <double undef, double undef>, double %x, i32 %index
314+
%vec = insertelement <2 x double> poison, double %x, i32 %index
315315
%trunc = fptrunc <2 x double> %vec to <2 x float>
316316
ret <2 x float> %trunc
317317
}
@@ -337,11 +337,11 @@ define <3 x i16> @trunc_inselt1(i32 %x) {
337337

338338
define <2 x float> @fptrunc_inselt1(double %x, i32 %index) {
339339
; CHECK-LABEL: @fptrunc_inselt1(
340-
; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x double> <double undef, double 3.000000e+00>, double [[X:%.*]], i32 [[INDEX:%.*]]
340+
; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x double> <double poison, double 3.000000e+00>, double [[X:%.*]], i32 [[INDEX:%.*]]
341341
; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <2 x double> [[VEC]] to <2 x float>
342342
; CHECK-NEXT: ret <2 x float> [[TRUNC]]
343343
;
344-
%vec = insertelement <2 x double> <double undef, double 3.0>, double %x, i32 %index
344+
%vec = insertelement <2 x double> <double poison, double 3.0>, double %x, i32 %index
345345
%trunc = fptrunc <2 x double> %vec to <2 x float>
346346
ret <2 x float> %trunc
347347
}

llvm/test/Transforms/InstCombine/vector-casts.ll

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -288,30 +288,30 @@ define <8 x i32> @pr24458(<8 x float> %n) {
288288
ret <8 x i32> %wrong
289289
}
290290

291-
; Hoist a trunc to a scalar if we're inserting into an undef vector.
292-
; trunc (inselt undef, X, Index) --> inselt undef, (trunc X), Index
291+
; Hoist a trunc to a scalar if we're inserting into a poison vector.
292+
; trunc (inselt poison, X, Index) --> inselt poison, (trunc X), Index
293293

294-
define <3 x i16> @trunc_inselt_undef(i32 %x) {
295-
; CHECK-LABEL: @trunc_inselt_undef(
294+
define <3 x i16> @trunc_inselt_poison(i32 %x, i32 %index) {
295+
; CHECK-LABEL: @trunc_inselt_poison(
296296
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
297-
; CHECK-NEXT: [[TRUNC:%.*]] = insertelement <3 x i16> <i16 undef, i16 poison, i16 undef>, i16 [[TMP1]], i64 1
297+
; CHECK-NEXT: [[TRUNC:%.*]] = insertelement <3 x i16> poison, i16 [[TMP1]], i32 [[INDEX:%.*]]
298298
; CHECK-NEXT: ret <3 x i16> [[TRUNC]]
299299
;
300-
%vec = insertelement <3 x i32> undef, i32 %x, i32 1
300+
%vec = insertelement <3 x i32> poison, i32 %x, i32 %index
301301
%trunc = trunc <3 x i32> %vec to <3 x i16>
302302
ret <3 x i16> %trunc
303303
}
304304

305-
; Hoist a trunc to a scalar if we're inserting into an undef vector.
306-
; trunc (inselt undef, X, Index) --> inselt undef, (trunc X), Index
305+
; Hoist a trunc to a scalar if we're inserting into a poison vector.
306+
; trunc (inselt poison, X, Index) --> inselt poison, (trunc X), Index
307307

308-
define <2 x float> @fptrunc_inselt_undef(double %x, i32 %index) {
309-
; CHECK-LABEL: @fptrunc_inselt_undef(
308+
define <2 x float> @fptrunc_inselt_poison(double %x, i32 %index) {
309+
; CHECK-LABEL: @fptrunc_inselt_poison(
310310
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[X:%.*]] to float
311-
; CHECK-NEXT: [[TRUNC:%.*]] = insertelement <2 x float> undef, float [[TMP1]], i32 [[INDEX:%.*]]
311+
; CHECK-NEXT: [[TRUNC:%.*]] = insertelement <2 x float> poison, float [[TMP1]], i32 [[INDEX:%.*]]
312312
; CHECK-NEXT: ret <2 x float> [[TRUNC]]
313313
;
314-
%vec = insertelement <2 x double> <double undef, double undef>, double %x, i32 %index
314+
%vec = insertelement <2 x double> poison, double %x, i32 %index
315315
%trunc = fptrunc <2 x double> %vec to <2 x float>
316316
ret <2 x float> %trunc
317317
}
@@ -337,11 +337,11 @@ define <3 x i16> @trunc_inselt1(i32 %x) {
337337

338338
define <2 x float> @fptrunc_inselt1(double %x, i32 %index) {
339339
; CHECK-LABEL: @fptrunc_inselt1(
340-
; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x double> <double undef, double 3.000000e+00>, double [[X:%.*]], i32 [[INDEX:%.*]]
340+
; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x double> <double poison, double 3.000000e+00>, double [[X:%.*]], i32 [[INDEX:%.*]]
341341
; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <2 x double> [[VEC]] to <2 x float>
342342
; CHECK-NEXT: ret <2 x float> [[TRUNC]]
343343
;
344-
%vec = insertelement <2 x double> <double undef, double 3.0>, double %x, i32 %index
344+
%vec = insertelement <2 x double> <double poison, double 3.0>, double %x, i32 %index
345345
%trunc = fptrunc <2 x double> %vec to <2 x float>
346346
ret <2 x float> %trunc
347347
}

0 commit comments

Comments
 (0)