diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -26,6 +26,7 @@ #include "llvm/Analysis/MustExecute.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Attributes.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" @@ -167,6 +168,8 @@ Value *AA::getWithType(Value &V, Type &Ty) { if (V.getType() == &Ty) return &V; + if (isa(V)) + return PoisonValue::get(&Ty); if (isa(V)) return UndefValue::get(&Ty); if (auto *C = dyn_cast(&V)) { diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -4631,10 +4631,10 @@ auto *C = SimplifiedAssociatedValue.hasValue() ? dyn_cast(SimplifiedAssociatedValue.getValue()) : UndefValue::get(V.getType()); - if (C && C != &V) { + if (C && C != &V && !V.user_empty()) { Value *NewV = AA::getWithType(*C, *V.getType()); // We can replace the AssociatedValue with the constant. - if (!V.user_empty() && &V != C && NewV) { + if (NewV && NewV != &V) { LLVM_DEBUG(dbgs() << "[ValueSimplify] " << V << " -> " << *NewV << " :: " << *this << "\n"); if (A.changeValueAfterManifest(V, *NewV)) @@ -4773,35 +4773,34 @@ if (SimplifiedAssociatedValue.hasValue() && !SimplifiedAssociatedValue.getValue()) - return Changed; + return Changed | AAValueSimplify::manifest(A); - Value &V = getAssociatedValue(); auto *C = SimplifiedAssociatedValue.hasValue() ? dyn_cast(SimplifiedAssociatedValue.getValue()) - : UndefValue::get(V.getType()); - if (C && C != &V) { - auto PredForReturned = - [&](Value &V, const SmallSetVector &RetInsts) { - // We can replace the AssociatedValue with the constant. - if (&V == C || isa(V)) - return true; - - for (ReturnInst *RI : RetInsts) { - if (RI->getFunction() != getAnchorScope()) - continue; - Value *NewV = - AA::getWithType(*C, *RI->getReturnValue()->getType()); - if (!NewV) - continue; - LLVM_DEBUG(dbgs() << "[ValueSimplify] " << V << " -> " << *NewV - << " in " << *RI << " :: " << *this << "\n"); - if (A.changeUseAfterManifest(RI->getOperandUse(0), *NewV)) - Changed = ChangeStatus::CHANGED; - } + : UndefValue::get(getAssociatedType()); + if (!C || C == &getAssociatedValue()) + return Changed | AAValueSimplify::manifest(A); + + auto PredForReturned = + [&](Value &V, const SmallSetVector &RetInsts) { + // We can replace the AssociatedValue with the constant. + if (&V == C || isa(V)) return true; - }; - A.checkForAllReturnedValuesAndReturnInsts(PredForReturned, *this); - } + + for (ReturnInst *RI : RetInsts) { + if (RI->getFunction() != getAnchorScope()) + continue; + Value *NewV = AA::getWithType(*C, *RI->getReturnValue()->getType()); + if (!NewV) + continue; + LLVM_DEBUG(dbgs() << "[ValueSimplify] " << V << " -> " << *NewV + << " in " << *RI << " :: " << *this << "\n"); + if (A.changeUseAfterManifest(RI->getOperandUse(0), *NewV)) + Changed = ChangeStatus::CHANGED; + } + return true; + }; + A.checkForAllReturnedValuesAndReturnInsts(PredForReturned, *this); return Changed | AAValueSimplify::manifest(A); }