[llvm] 648544f - [Constant] ConstantStruct/Array should not lower poison to undef
Juneyoung Lee via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 7 23:23:42 PDT 2021
Author: Juneyoung Lee
Date: 2021-04-08T15:23:12+09:00
New Revision: 648544f998cd0811670a625f4f2964125cf833b3
URL: https://github.com/llvm/llvm-project/commit/648544f998cd0811670a625f4f2964125cf833b3
DIFF: https://github.com/llvm/llvm-project/commit/648544f998cd0811670a625f4f2964125cf833b3.diff
LOG: [Constant] ConstantStruct/Array should not lower poison to undef
This is a (late) follow-up patch of 8871a4b4cab8a56fd6ff12fd024002c3c79128b3 and
c95f39891a282ebf36199c73b705d4a2c78a46ce 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)
Added:
Modified:
llvm/lib/IR/Constants.cpp
llvm/unittests/IR/ConstantsTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 48ccb18fee08..c0b8af8b2437 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -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);
diff --git a/llvm/unittests/IR/ConstantsTest.cpp b/llvm/unittests/IR/ConstantsTest.cpp
index 50eb3e0df1f5..54ef98cb5917 100644
--- a/llvm/unittests/IR/ConstantsTest.cpp
+++ b/llvm/unittests/IR/ConstantsTest.cpp
@@ -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;
More information about the llvm-commits
mailing list