aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Constants.cpp
diff options
context:
space:
mode:
authorJuneyoung Lee <aqjune@gmail.com>2021-04-08 15:20:08 +0900
committerJuneyoung Lee <aqjune@gmail.com>2021-04-08 15:23:12 +0900
commit648544f998cd0811670a625f4f2964125cf833b3 (patch)
treec7cefd95eeae8d5815fcc3bb8092f603e51f025e /llvm/lib/IR/Constants.cpp
parent2a2720a2dec4ad4fdc7ae58939448e51824a12c4 (diff)
downloadllvm-648544f998cd0811670a625f4f2964125cf833b3.zip
llvm-648544f998cd0811670a625f4f2964125cf833b3.tar.gz
llvm-648544f998cd0811670a625f4f2964125cf833b3.tar.bz2
[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)
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r--llvm/lib/IR/Constants.cpp12
1 files changed, 11 insertions, 1 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 48ccb18..c0b8af8 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);