Index: llvm/include/llvm/Transforms/IPO/Attributor.h =================================================================== --- llvm/include/llvm/Transforms/IPO/Attributor.h +++ llvm/include/llvm/Transforms/IPO/Attributor.h @@ -3362,9 +3362,10 @@ struct PotentialValuesState : BooleanState { using SetTy = DenseSet; - PotentialValuesState() : BooleanState(true) {} + PotentialValuesState() : BooleanState(true), UndefIsContained(false) {} - PotentialValuesState(bool IsValid) : BooleanState(IsValid) {} + PotentialValuesState(bool IsValid) + : BooleanState(IsValid), UndefIsContained(false) {} /// Return this set. We should check whether this set is valid or not by /// isValidState() before calling this function. @@ -3373,6 +3374,12 @@ return Set; } + /// Returns whether this state contains an undef value or not. + bool undefIsContained() const { + assert(isValidState() && "This flag shoud not be used when it is invalid!"); + return UndefIsContained; + } + bool operator==(const PotentialValuesState &RHS) const { if (isValidState() != RHS.isValidState()) return false; @@ -3405,6 +3412,9 @@ /// Union assumed set with assumed set of the passed state \p PVS. void unionAssumed(const PotentialValuesState &PVS) { unionWith(PVS); } + /// Union assumed set with an undef value. + void unionAssumedWithUndef() { unionWithUndef(); } + /// "Clamp" this state with \p PVS. PotentialValuesState operator^=(const PotentialValuesState &PVS) { unionAssumed(PVS); @@ -3424,6 +3434,14 @@ indicatePessimisticFixpoint(); } + /// If this state contains both undef and not undef, we can reduce + /// undef to the not undef value. + void reduceUndefValue() { + if (UndefIsContained && Set.size() > 0) { + UndefIsContained = false; + } + } + /// Insert an element into this set. void insert(const MemberTy &C) { if (!isValidState()) @@ -3444,9 +3462,17 @@ } for (const MemberTy &C : R.Set) Set.insert(C); + UndefIsContained |= R.undefIsContained(); + reduceUndefValue(); checkAndInvalidate(); } + /// Take union with an undef value. + void unionWithUndef() { + UndefIsContained = true; + reduceUndefValue(); + } + /// Take intersection with R. void intersectWith(const PotentialValuesState &R) { /// If R is a full set, do nothing. @@ -3463,10 +3489,15 @@ IntersectSet.insert(C); } Set = IntersectSet; + UndefIsContained &= R.undefIsContained(); + reduceUndefValue(); } /// Container for potential values SetTy Set; + + /// Flag for undef value + bool UndefIsContained; }; using PotentialConstantIntValuesState = PotentialValuesState; @@ -3513,8 +3544,12 @@ if (getAssumedSet().size() == 1) return cast(ConstantInt::get(getAssociatedValue().getType(), *(getAssumedSet().begin()))); - if (getAssumedSet().size() == 0) + if (getAssumedSet().size() == 0) { + if (undefIsContained()) + return cast( + ConstantInt::get(getAssociatedValue().getType(), 0)); return llvm::None; + } return nullptr; } Index: llvm/lib/Transforms/IPO/AttributorAttributes.cpp =================================================================== --- llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -7255,10 +7255,7 @@ } if (isa(&V)) { - // Collapse the undef state to 0. - unionAssumed( - APInt(/* numBits */ getAssociatedType()->getIntegerBitWidth(), - /* val */ 0)); + unionAssumedWithUndef(); indicateOptimisticFixpoint(); return; }