forked from OSchip/llvm-project
[Constant] ConstantStruct/Array should not lower poison to undef
This is a (late) follow-up patch of8871a4b4ca
andc95f39891a
to make ConstantStruct::get/ConstantArray::getImpl correctly return PoisonValue if all elements are poison. This was found while discussing about the elements of a vector-typed UndefValue (D99853)
This commit is contained in:
parent
2a2720a2de
commit
648544f998
|
@ -1265,6 +1265,9 @@ Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {
|
|||
// all undef, return an UndefValue, if "all simple", then return a
|
||||
// ConstantDataArray.
|
||||
Constant *C = V[0];
|
||||
if (isa<PoisonValue>(C) && rangeOnlyContains(V.begin(), V.end(), C))
|
||||
return PoisonValue::get(Ty);
|
||||
|
||||
if (isa<UndefValue>(C) && rangeOnlyContains(V.begin(), V.end(), C))
|
||||
return UndefValue::get(Ty);
|
||||
|
||||
|
@ -1313,21 +1316,28 @@ Constant *ConstantStruct::get(StructType *ST, ArrayRef<Constant*> V) {
|
|||
// Create a ConstantAggregateZero value if all elements are zeros.
|
||||
bool isZero = true;
|
||||
bool isUndef = false;
|
||||
bool isPoison = false;
|
||||
|
||||
if (!V.empty()) {
|
||||
isUndef = isa<UndefValue>(V[0]);
|
||||
isPoison = isa<PoisonValue>(V[0]);
|
||||
isZero = V[0]->isNullValue();
|
||||
// PoisonValue inherits UndefValue, so its check is not necessary.
|
||||
if (isUndef || isZero) {
|
||||
for (unsigned i = 0, e = V.size(); i != e; ++i) {
|
||||
if (!V[i]->isNullValue())
|
||||
isZero = false;
|
||||
if (!isa<UndefValue>(V[i]))
|
||||
if (!isa<PoisonValue>(V[i]))
|
||||
isPoison = false;
|
||||
if (isa<PoisonValue>(V[i]) || !isa<UndefValue>(V[i]))
|
||||
isUndef = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isZero)
|
||||
return ConstantAggregateZero::get(ST);
|
||||
if (isPoison)
|
||||
return PoisonValue::get(ST);
|
||||
if (isUndef)
|
||||
return UndefValue::get(ST);
|
||||
|
||||
|
|
|
@ -644,13 +644,6 @@ TEST(ConstantsTest, isElementWiseEqual) {
|
|||
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});
|
||||
|
@ -692,6 +685,52 @@ TEST(ConstantsTest, isElementWiseEqual) {
|
|||
EXPECT_FALSE(CP00U->isElementWiseEqual(CP00U0));
|
||||
}
|
||||
|
||||
// Check that vector/aggregate constants correctly store undef and poison
|
||||
// elements.
|
||||
|
||||
TEST(ConstantsTest, CheckElementWiseUndefPoison) {
|
||||
LLVMContext Context;
|
||||
|
||||
Type *Int32Ty = Type::getInt32Ty(Context);
|
||||
StructType *STy = StructType::get(Int32Ty, Int32Ty);
|
||||
ArrayType *ATy = ArrayType::get(Int32Ty, 2);
|
||||
Constant *CU = UndefValue::get(Int32Ty);
|
||||
Constant *CP = PoisonValue::get(Int32Ty);
|
||||
|
||||
{
|
||||
Constant *CUU = ConstantVector::get({CU, CU});
|
||||
Constant *CPP = ConstantVector::get({CP, CP});
|
||||
Constant *CUP = ConstantVector::get({CU, CP});
|
||||
Constant *CPU = ConstantVector::get({CP, CU});
|
||||
EXPECT_EQ(CUU, UndefValue::get(CUU->getType()));
|
||||
EXPECT_EQ(CPP, PoisonValue::get(CPP->getType()));
|
||||
EXPECT_NE(CUP, UndefValue::get(CUP->getType()));
|
||||
EXPECT_NE(CPU, UndefValue::get(CPU->getType()));
|
||||
}
|
||||
|
||||
{
|
||||
Constant *CUU = ConstantStruct::get(STy, {CU, CU});
|
||||
Constant *CPP = ConstantStruct::get(STy, {CP, CP});
|
||||
Constant *CUP = ConstantStruct::get(STy, {CU, CP});
|
||||
Constant *CPU = ConstantStruct::get(STy, {CP, CU});
|
||||
EXPECT_EQ(CUU, UndefValue::get(CUU->getType()));
|
||||
EXPECT_EQ(CPP, PoisonValue::get(CPP->getType()));
|
||||
EXPECT_NE(CUP, UndefValue::get(CUP->getType()));
|
||||
EXPECT_NE(CPU, UndefValue::get(CPU->getType()));
|
||||
}
|
||||
|
||||
{
|
||||
Constant *CUU = ConstantArray::get(ATy, {CU, CU});
|
||||
Constant *CPP = ConstantArray::get(ATy, {CP, CP});
|
||||
Constant *CUP = ConstantArray::get(ATy, {CU, CP});
|
||||
Constant *CPU = ConstantArray::get(ATy, {CP, CU});
|
||||
EXPECT_EQ(CUU, UndefValue::get(CUU->getType()));
|
||||
EXPECT_EQ(CPP, PoisonValue::get(CPP->getType()));
|
||||
EXPECT_NE(CUP, UndefValue::get(CUP->getType()));
|
||||
EXPECT_NE(CPU, UndefValue::get(CPU->getType()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ConstantsTest, GetSplatValueRoundTrip) {
|
||||
LLVMContext Context;
|
||||
|
||||
|
|
Loading…
Reference in New Issue