diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4401,10 +4401,10 @@ if (Q.isUndefValue(Idx)) return PoisonValue::get(Vec->getType()); - // If the scalar is undef, and there is no risk of propagating poison from the - // vector value, simplify to the vector value. - if (Q.isUndefValue(Val) && - isGuaranteedNotToBeUndefOrPoison(Vec)) + // If the scalar is poison, or it is undef and there is no risk of + // propagating poison from the vector value, simplify to the vector value. + if (isa(Val) || + (Q.isUndefValue(Val) && isGuaranteedNotToBePoison(Vec))) return Vec; // If we are extracting a value from a vector, then inserting it into the same diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -1339,17 +1339,20 @@ Constant *C = V[0]; bool isZero = C->isNullValue(); bool isUndef = isa(C); + bool isPoison = isa(C); if (isZero || isUndef) { for (unsigned i = 1, e = V.size(); i != e; ++i) if (V[i] != C) { - isZero = isUndef = false; + isZero = isUndef = isPoison = false; break; } } if (isZero) return ConstantAggregateZero::get(T); + if (isPoison) + return PoisonValue::get(T); if (isUndef) return UndefValue::get(T); diff --git a/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll b/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll --- a/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll @@ -244,7 +244,7 @@ define <16 x i8> @elts_packuswb_128(<8 x i16> %a0, <8 x i16> %a1) { ; CHECK-LABEL: @elts_packuswb_128( -; CHECK-NEXT: ret <16 x i8> undef +; CHECK-NEXT: ret <16 x i8> poison ; %1 = insertelement <8 x i16> poison, i16 0, i32 0 %2 = insertelement <8 x i16> poison, i16 0, i32 0 @@ -293,7 +293,7 @@ define <32 x i8> @elts_packuswb_256(<16 x i16> %a0, <16 x i16> %a1) { ; CHECK-LABEL: @elts_packuswb_256( -; CHECK-NEXT: ret <32 x i8> undef +; CHECK-NEXT: ret <32 x i8> poison ; %1 = insertelement <16 x i16> poison, i16 0, i32 1 %2 = insertelement <16 x i16> poison, i16 0, i32 0 @@ -344,7 +344,7 @@ define <64 x i8> @elts_packuswb_512(<32 x i16> %a0, <32 x i16> %a1) { ; CHECK-LABEL: @elts_packuswb_512( -; CHECK-NEXT: ret <64 x i8> undef +; CHECK-NEXT: ret <64 x i8> poison ; %1 = insertelement <32 x i16> poison, i16 0, i32 1 %2 = insertelement <32 x i16> poison, i16 0, i32 0 diff --git a/llvm/test/Transforms/InstCombine/extractelement-inseltpoison.ll b/llvm/test/Transforms/InstCombine/extractelement-inseltpoison.ll --- a/llvm/test/Transforms/InstCombine/extractelement-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/extractelement-inseltpoison.ll @@ -319,8 +319,7 @@ ; ANY-NEXT: [[T4:%.*]] = shufflevector <4 x double> [[B:%.*]], <4 x double> [[TMP1]], <4 x i32> ; ANY-NEXT: [[E:%.*]] = extractelement <4 x double> [[B]], i32 1 ; ANY-NEXT: store double [[E]], double* [[P:%.*]], align 8 -; ANY-NEXT: [[R:%.*]] = insertelement <4 x double> [[T4]], double poison, i64 0 -; ANY-NEXT: ret <4 x double> [[R]] +; ANY-NEXT: ret <4 x double> [[T4]] ; %t3 = extractelement <2 x double> %a, i32 0 %t4 = insertelement <4 x double> %b, double %t3, i32 2 diff --git a/llvm/test/Transforms/InstCombine/extractelement.ll b/llvm/test/Transforms/InstCombine/extractelement.ll --- a/llvm/test/Transforms/InstCombine/extractelement.ll +++ b/llvm/test/Transforms/InstCombine/extractelement.ll @@ -319,8 +319,7 @@ ; ANY-NEXT: [[T4:%.*]] = shufflevector <4 x double> [[B:%.*]], <4 x double> [[TMP1]], <4 x i32> ; ANY-NEXT: [[E:%.*]] = extractelement <4 x double> [[B]], i32 1 ; ANY-NEXT: store double [[E]], double* [[P:%.*]], align 8 -; ANY-NEXT: [[R:%.*]] = insertelement <4 x double> [[T4]], double poison, i64 0 -; ANY-NEXT: ret <4 x double> [[R]] +; ANY-NEXT: ret <4 x double> [[T4]] ; %t3 = extractelement <2 x double> %a, i32 0 %t4 = insertelement <4 x double> %b, double %t3, i32 2 diff --git a/llvm/test/Transforms/InstSimplify/insertelement.ll b/llvm/test/Transforms/InstSimplify/insertelement.ll --- a/llvm/test/Transforms/InstSimplify/insertelement.ll +++ b/llvm/test/Transforms/InstSimplify/insertelement.ll @@ -52,8 +52,7 @@ define <4 x i32> @elem_poison(<4 x i32> %A) { ; CHECK-LABEL: @elem_poison( -; CHECK-NEXT: [[B:%.*]] = insertelement <4 x i32> [[A:%.*]], i32 poison, i32 1 -; CHECK-NEXT: ret <4 x i32> [[B]] +; CHECK-NEXT: ret <4 x i32> [[A:%.*]] ; %B = insertelement <4 x i32> %A, i32 poison, i32 1 ret <4 x i32> %B diff --git a/llvm/test/Transforms/PhaseOrdering/X86/scalarization.ll b/llvm/test/Transforms/PhaseOrdering/X86/scalarization.ll --- a/llvm/test/Transforms/PhaseOrdering/X86/scalarization.ll +++ b/llvm/test/Transforms/PhaseOrdering/X86/scalarization.ll @@ -27,7 +27,7 @@ ; CHECK-NEXT: [[DOTSCALAR6:%.*]] = add i32 [[DOTSCALAR5]], [[DIV9]] ; CHECK-NEXT: [[DOTSCALAR7:%.*]] = add i32 [[DOTSCALAR6]], [[MUL21]] ; CHECK-NEXT: [[DOTSCALAR8:%.*]] = add i32 [[DOTSCALAR7]], 317425 -; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i32> undef, i32 [[DOTSCALAR8]], i64 0 +; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i32> poison, i32 [[DOTSCALAR8]], i64 0 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer ; CHECK-NEXT: [[ADD29:%.*]] = add <4 x i32> [[TMP2]], [[NUM:%.*]] ; CHECK-NEXT: ret <4 x i32> [[ADD29]] diff --git a/llvm/test/Transforms/SLPVectorizer/X86/alternate-int-inseltpoison.ll b/llvm/test/Transforms/SLPVectorizer/X86/alternate-int-inseltpoison.ll --- a/llvm/test/Transforms/SLPVectorizer/X86/alternate-int-inseltpoison.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/alternate-int-inseltpoison.ll @@ -425,10 +425,10 @@ ; CHECK-NEXT: [[AB5:%.*]] = sdiv i32 [[A5]], 4 ; CHECK-NEXT: [[AB6:%.*]] = sdiv i32 [[A6]], 8 ; CHECK-NEXT: [[AB7:%.*]] = sdiv i32 [[A7]], 16 -; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i32> , i32 [[AB1]], i32 1 -; CHECK-NEXT: [[TMP2:%.*]] = insertelement <8 x i32> [[TMP1]], i32 [[AB2]], i32 2 -; CHECK-NEXT: [[R4:%.*]] = insertelement <8 x i32> [[TMP2]], i32 [[AB3]], i32 3 -; CHECK-NEXT: [[R5:%.*]] = insertelement <8 x i32> [[R4]], i32 [[AB5]], i32 5 +; CHECK-NEXT: [[R1:%.*]] = insertelement <8 x i32> poison, i32 [[AB1]], i32 1 +; CHECK-NEXT: [[R2:%.*]] = insertelement <8 x i32> [[R1]], i32 [[AB2]], i32 2 +; CHECK-NEXT: [[R3:%.*]] = insertelement <8 x i32> [[R2]], i32 [[AB3]], i32 3 +; CHECK-NEXT: [[R5:%.*]] = insertelement <8 x i32> [[R3]], i32 [[AB5]], i32 5 ; CHECK-NEXT: [[R6:%.*]] = insertelement <8 x i32> [[R5]], i32 [[AB6]], i32 6 ; CHECK-NEXT: [[R7:%.*]] = insertelement <8 x i32> [[R6]], i32 [[AB7]], i32 7 ; CHECK-NEXT: ret <8 x i32> [[R7]] diff --git a/llvm/test/Transforms/SLPVectorizer/X86/alternate-int.ll b/llvm/test/Transforms/SLPVectorizer/X86/alternate-int.ll --- a/llvm/test/Transforms/SLPVectorizer/X86/alternate-int.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/alternate-int.ll @@ -425,10 +425,10 @@ ; CHECK-NEXT: [[AB5:%.*]] = sdiv i32 [[A5]], 4 ; CHECK-NEXT: [[AB6:%.*]] = sdiv i32 [[A6]], 8 ; CHECK-NEXT: [[AB7:%.*]] = sdiv i32 [[A7]], 16 -; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i32> undef, i32 [[AB1]], i32 1 -; CHECK-NEXT: [[TMP2:%.*]] = insertelement <8 x i32> [[TMP1]], i32 [[AB2]], i32 2 -; CHECK-NEXT: [[R4:%.*]] = insertelement <8 x i32> [[TMP2]], i32 [[AB3]], i32 3 -; CHECK-NEXT: [[R5:%.*]] = insertelement <8 x i32> [[R4]], i32 [[AB5]], i32 5 +; CHECK-NEXT: [[R1:%.*]] = insertelement <8 x i32> , i32 [[AB1]], i32 1 +; CHECK-NEXT: [[R2:%.*]] = insertelement <8 x i32> [[R1]], i32 [[AB2]], i32 2 +; CHECK-NEXT: [[R3:%.*]] = insertelement <8 x i32> [[R2]], i32 [[AB3]], i32 3 +; CHECK-NEXT: [[R5:%.*]] = insertelement <8 x i32> [[R3]], i32 [[AB5]], i32 5 ; CHECK-NEXT: [[R6:%.*]] = insertelement <8 x i32> [[R5]], i32 [[AB6]], i32 6 ; CHECK-NEXT: [[R7:%.*]] = insertelement <8 x i32> [[R6]], i32 [[AB7]], i32 7 ; CHECK-NEXT: ret <8 x i32> [[R7]] diff --git a/llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll b/llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll --- a/llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll +++ b/llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll @@ -131,7 +131,7 @@ define <2 x i64> @shl_constant_op0(i64 %x) { ; CHECK-LABEL: @shl_constant_op0( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = shl i64 2, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 1 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 1 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 1 @@ -142,7 +142,7 @@ define <2 x i64> @shl_constant_op0_not_undef_lane(i64 %x) { ; CHECK-LABEL: @shl_constant_op0_not_undef_lane( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = shl i64 2, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 1 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 1 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 1 @@ -224,7 +224,7 @@ define <2 x i64> @ashr_constant_op0(i64 %x) { ; CHECK-LABEL: @ashr_constant_op0( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = ashr exact i64 2, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 1 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 1 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 1 @@ -235,7 +235,7 @@ define <2 x i64> @ashr_constant_op0_not_undef_lane(i64 %x) { ; CHECK-LABEL: @ashr_constant_op0_not_undef_lane( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = ashr exact i64 2, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 1 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 1 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 1 @@ -268,7 +268,7 @@ define <2 x i64> @lshr_constant_op0(i64 %x) { ; CHECK-LABEL: @lshr_constant_op0( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = lshr i64 5, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 0 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 0 @@ -279,7 +279,7 @@ define <2 x i64> @lshr_constant_op0_not_undef_lane(i64 %x) { ; CHECK-LABEL: @lshr_constant_op0_not_undef_lane( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = lshr i64 5, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 0 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 0 @@ -312,7 +312,7 @@ define <2 x i64> @urem_constant_op0(i64 %x) { ; CHECK-LABEL: @urem_constant_op0( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = urem i64 5, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 0 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 0 @@ -323,7 +323,7 @@ define <2 x i64> @urem_constant_op0_not_undef_lane(i64 %x) { ; CHECK-LABEL: @urem_constant_op0_not_undef_lane( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = urem i64 5, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 0 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 0 @@ -356,7 +356,7 @@ define <2 x i64> @srem_constant_op0(i64 %x) { ; CHECK-LABEL: @srem_constant_op0( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = srem i64 5, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 0 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 0 @@ -367,7 +367,7 @@ define <2 x i64> @srem_constant_op0_not_undef_lane(i64 %x) { ; CHECK-LABEL: @srem_constant_op0_not_undef_lane( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = srem i64 5, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 0 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 0 @@ -400,7 +400,7 @@ define <2 x i64> @udiv_constant_op0(i64 %x) { ; CHECK-LABEL: @udiv_constant_op0( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = udiv exact i64 5, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 0 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 0 @@ -411,7 +411,7 @@ define <2 x i64> @udiv_constant_op0_not_undef_lane(i64 %x) { ; CHECK-LABEL: @udiv_constant_op0_not_undef_lane( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = udiv exact i64 5, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 0 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 0 @@ -444,7 +444,7 @@ define <2 x i64> @sdiv_constant_op0(i64 %x) { ; CHECK-LABEL: @sdiv_constant_op0( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = sdiv i64 5, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 0 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 0 @@ -455,7 +455,7 @@ define <2 x i64> @sdiv_constant_op0_not_undef_lane(i64 %x) { ; CHECK-LABEL: @sdiv_constant_op0_not_undef_lane( ; CHECK-NEXT: [[BO_SCALAR:%.*]] = sdiv i64 5, [[X:%.*]] -; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0 +; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 0 ; CHECK-NEXT: ret <2 x i64> [[BO]] ; %ins = insertelement <2 x i64> undef, i64 %x, i32 0 diff --git a/llvm/test/Transforms/VectorCombine/X86/insert-binop.ll b/llvm/test/Transforms/VectorCombine/X86/insert-binop.ll --- a/llvm/test/Transforms/VectorCombine/X86/insert-binop.ll +++ b/llvm/test/Transforms/VectorCombine/X86/insert-binop.ll @@ -53,7 +53,7 @@ ; CHECK-NEXT: [[S0_SCALAR:%.*]] = sub i64 [[W:%.*]], [[X:%.*]] ; CHECK-NEXT: [[S1_SCALAR:%.*]] = or i64 [[S0_SCALAR]], [[Y:%.*]] ; CHECK-NEXT: [[S2_SCALAR:%.*]] = shl i64 [[Z:%.*]], [[S1_SCALAR]] -; CHECK-NEXT: [[S2:%.*]] = insertelement <2 x i64> undef, i64 [[S2_SCALAR]], i64 1 +; CHECK-NEXT: [[S2:%.*]] = insertelement <2 x i64> poison, i64 [[S2_SCALAR]], i64 1 ; CHECK-NEXT: ret <2 x i64> [[S2]] ; %i0 = insertelement <2 x i64> undef, i64 %w, i64 1 diff --git a/llvm/unittests/IR/ConstantsTest.cpp b/llvm/unittests/IR/ConstantsTest.cpp --- a/llvm/unittests/IR/ConstantsTest.cpp +++ b/llvm/unittests/IR/ConstantsTest.cpp @@ -631,9 +631,17 @@ Type *Int32Ty = Type::getInt32Ty(Context); Constant *CU = UndefValue::get(Int32Ty); + Constant *CP = PoisonValue::get(Int32Ty); Constant *C1 = ConstantInt::get(Int32Ty, 1); Constant *C2 = ConstantInt::get(Int32Ty, 2); + Constant *CUU = ConstantVector::get({CU, CU}); + Constant *CPP = ConstantVector::get({CP, CP}); + Constant *CUP = ConstantVector::get({CU, CP}); + EXPECT_EQ(CUU, UndefValue::get(CUU->getType())); + EXPECT_EQ(CPP, PoisonValue::get(CPP->getType())); + EXPECT_NE(CUP, UndefValue::get(CUP->getType())); + Constant *C1211 = ConstantVector::get({C1, C2, C1, C1}); Constant *C12U1 = ConstantVector::get({C1, C2, CU, C1}); Constant *C12U2 = ConstantVector::get({C1, C2, CU, C2});