@@ -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-
712681Value *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+
814807Value *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