Skip to content

Commit 0cdb310

Browse files
committed
Simplify the checkRebuildingPreservesNUW computation
1 parent bf8391d commit 0cdb310

File tree

1 file changed

+25
-32
lines changed

1 file changed

+25
-32
lines changed

Diff for: llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp

+25-32
Original file line numberDiff line numberDiff line change
@@ -269,13 +269,6 @@ class ConstantOffsetExtractor {
269269
APInt findInEitherOperand(BinaryOperator *BO, bool SignExtended,
270270
bool ZeroExtended);
271271

272-
/// A helper function to check if a subsequent call to rebuildWithoutConst
273-
/// will allow preserving the GEP's nuw flag. That is the case if all
274-
/// reassociated binary operations are add nuw and no non-nuw trunc is
275-
/// distributed through an add.
276-
/// Can only be called after find has populated the UserChain.
277-
bool checkRebuildingPreservesNUW() const;
278-
279272
/// After finding the constant offset C from the GEP index I, we build a new
280273
/// index I' s.t. I' + C = I. This function builds and returns the new
281274
/// index I' according to UserChain produced by function "find".
@@ -685,30 +678,6 @@ Value *ConstantOffsetExtractor::applyExts(Value *V) {
685678
return Current;
686679
}
687680

688-
bool ConstantOffsetExtractor::checkRebuildingPreservesNUW() const {
689-
auto AllowsPreservingNUW = [](User *U) {
690-
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(U)) {
691-
auto Opcode = BO->getOpcode();
692-
if (Opcode == BinaryOperator::Or) {
693-
// Ors are only considered here if they are disjoint. The addition that
694-
// they represent in this case is NUW.
695-
assert(cast<PossiblyDisjointInst>(BO)->isDisjoint());
696-
return true;
697-
}
698-
return Opcode == BinaryOperator::Add && BO->hasNoUnsignedWrap();
699-
}
700-
// UserChain can only contain ConstantInt, CastInst, or BinaryOperator.
701-
// Among the possible CastInsts, only trunc without nuw is a problem: If it
702-
// is distributed through an add nuw, wrapping may occur:
703-
// "add nuw trunc(a), trunc(b)" is more poisonous than "trunc(add nuw a, b)"
704-
if (TruncInst *TI = dyn_cast<TruncInst>(U))
705-
return TI->hasNoUnsignedWrap();
706-
return true;
707-
};
708-
709-
return all_of(UserChain, AllowsPreservingNUW);
710-
}
711-
712681
Value *ConstantOffsetExtractor::rebuildWithoutConstOffset() {
713682
distributeExtsAndCloneChain(UserChain.size() - 1);
714683
// Remove all nullptrs (used to be s/zext) from UserChain.
@@ -811,6 +780,30 @@ Value *ConstantOffsetExtractor::removeConstOffset(unsigned ChainIndex) {
811780
return NewBO;
812781
}
813782

783+
/// A helper function to check if reassociating through an entry in the user
784+
/// chain would invalidate the GEP's nuw flag.
785+
static bool allowsPreservingNUW(User *U) {
786+
assert(isa<BinaryOperator>(U) || isa<CastInst>(U) || isa<ConstantInt>(U));
787+
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(U)) {
788+
// Binary operations needd to be effectively add nuw.
789+
auto Opcode = BO->getOpcode();
790+
if (Opcode == BinaryOperator::Or) {
791+
// Ors are only considered here if they are disjoint. The addition that
792+
// they represent in this case is NUW.
793+
assert(cast<PossiblyDisjointInst>(BO)->isDisjoint());
794+
return true;
795+
}
796+
return Opcode == BinaryOperator::Add && BO->hasNoUnsignedWrap();
797+
}
798+
// UserChain can only contain ConstantInt, CastInst, or BinaryOperator.
799+
// Among the possible CastInsts, only trunc without nuw is a problem: If it
800+
// is distributed through an add nuw, wrapping may occur:
801+
// "add nuw trunc(a), trunc(b)" is more poisonous than "trunc(add nuw a, b)"
802+
if (TruncInst *TI = dyn_cast<TruncInst>(U))
803+
return TI->hasNoUnsignedWrap();
804+
return true;
805+
}
806+
814807
Value *ConstantOffsetExtractor::Extract(Value *Idx, GetElementPtrInst *GEP,
815808
User *&UserChainTail,
816809
bool &PreservesNUW) {
@@ -825,7 +818,7 @@ Value *ConstantOffsetExtractor::Extract(Value *Idx, GetElementPtrInst *GEP,
825818
return nullptr;
826819
}
827820

828-
PreservesNUW = Extractor.checkRebuildingPreservesNUW();
821+
PreservesNUW = all_of(Extractor.UserChain, allowsPreservingNUW);
829822

830823
// Separates the constant offset from the GEP index.
831824
Value *IdxWithoutConstOffset = Extractor.rebuildWithoutConstOffset();

0 commit comments

Comments
 (0)