@@ -269,13 +269,6 @@ class ConstantOffsetExtractor {
269
269
APInt findInEitherOperand (BinaryOperator *BO, bool SignExtended,
270
270
bool ZeroExtended);
271
271
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
-
279
272
// / After finding the constant offset C from the GEP index I, we build a new
280
273
// / index I' s.t. I' + C = I. This function builds and returns the new
281
274
// / index I' according to UserChain produced by function "find".
@@ -685,30 +678,6 @@ Value *ConstantOffsetExtractor::applyExts(Value *V) {
685
678
return Current;
686
679
}
687
680
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
-
712
681
Value *ConstantOffsetExtractor::rebuildWithoutConstOffset () {
713
682
distributeExtsAndCloneChain (UserChain.size () - 1 );
714
683
// Remove all nullptrs (used to be s/zext) from UserChain.
@@ -811,6 +780,30 @@ Value *ConstantOffsetExtractor::removeConstOffset(unsigned ChainIndex) {
811
780
return NewBO;
812
781
}
813
782
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
+
814
807
Value *ConstantOffsetExtractor::Extract (Value *Idx, GetElementPtrInst *GEP,
815
808
User *&UserChainTail,
816
809
bool &PreservesNUW) {
@@ -825,7 +818,7 @@ Value *ConstantOffsetExtractor::Extract(Value *Idx, GetElementPtrInst *GEP,
825
818
return nullptr ;
826
819
}
827
820
828
- PreservesNUW = Extractor.checkRebuildingPreservesNUW ( );
821
+ PreservesNUW = all_of ( Extractor.UserChain , allowsPreservingNUW );
829
822
830
823
// Separates the constant offset from the GEP index.
831
824
Value *IdxWithoutConstOffset = Extractor.rebuildWithoutConstOffset ();
0 commit comments