diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2023-06-13 10:15:02 +0100 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2023-06-13 10:40:24 +0100 |
commit | e61bb1e541ffe3622712e3475c765f51ba88adfb (patch) | |
tree | 4a1e60368a66404c2c09c161427fca93771cf886 /llvm/lib/CodeGen/MachineFunction.cpp | |
parent | 7fcc35b7a389058149b92be3de26548c76bed752 (diff) | |
download | llvm-e61bb1e541ffe3622712e3475c765f51ba88adfb.zip llvm-e61bb1e541ffe3622712e3475c765f51ba88adfb.tar.gz llvm-e61bb1e541ffe3622712e3475c765f51ba88adfb.tar.bz2 |
MachineConstantPool::getConstantPoolIndex - don't reuse mismatched constants contained undef/poison (Issue #63108)
This patch fixes an issue where we were reusing constant pool entries that contained undef elements, despite the additional uses of the 'equivalent constant' requiring some/all of the elements to be zero.
The CanShareConstantPoolEntry helper function uses ConstantFoldCastOperand to bitcast the type mismatching constants to integer representations to allow comparison, but unfortunately this treats undef elements as zero (which they will be written out as in the final asm). This caused an issue where the original constant pool entry contained undef elements, which was shared with a later constant that required the elements to be zero. This then caused a later analysis pass to incorrectly discard these undef elements.
Ideally we need a more thorough analysis/merging of the constant pool entries so the elements are forced to real zero elements, but for now we just prevent reuse of the constant pool entry entirely if the constants don't have matching undef/poison elements.
Fixes #63108
Differential Revision: https://reviews.llvm.org/D152357
Diffstat (limited to 'llvm/lib/CodeGen/MachineFunction.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineFunction.cpp | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index e1cf417..0f72e4b 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -1392,7 +1392,7 @@ MachineConstantPool::~MachineConstantPool() { } /// Test whether the given two constants can be allocated the same constant pool -/// entry. +/// entry referenced by \param A. static bool CanShareConstantPoolEntry(const Constant *A, const Constant *B, const DataLayout &DL) { // Handle the trivial case quickly. @@ -1412,6 +1412,8 @@ static bool CanShareConstantPoolEntry(const Constant *A, const Constant *B, if (StoreSize != DL.getTypeStoreSize(B->getType()) || StoreSize > 128) return false; + bool ContainsUndefOrPoisonA = A->containsUndefOrPoisonElement(); + Type *IntTy = IntegerType::get(A->getContext(), StoreSize*8); // Try constant folding a bitcast of both instructions to an integer. If we @@ -1431,7 +1433,14 @@ static bool CanShareConstantPoolEntry(const Constant *A, const Constant *B, B = ConstantFoldCastOperand(Instruction::BitCast, const_cast<Constant *>(B), IntTy, DL); - return A == B; + if (A != B) + return false; + + // Constants only safely match if A doesn't contain undef/poison. + // As we'll be reusing A, it doesn't matter if B contain undef/poison. + // TODO: Handle cases where A and B have the same undef/poison elements. + // TODO: Merge A and B with mismatching undef/poison elements. + return !ContainsUndefOrPoisonA; } /// Create a new entry in the constant pool or return an existing one. |