@@ -423,7 +423,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
423423// / Returns true if we can rewrite Start as a GEP with pointer Base
424424// / and some integer offset. The nodes that need to be re-written
425425// / for this transformation will be added to Explored.
426- static bool canRewriteGEPAsOffset (Value *Start, Value *Base,
426+ static bool canRewriteGEPAsOffset (Value *Start, Value *Base, GEPNoWrapFlags &NW,
427427 const DataLayout &DL,
428428 SetVector<Value *> &Explored) {
429429 SmallVector<Value *, 16 > WorkList (1 , Start);
@@ -462,6 +462,7 @@ static bool canRewriteGEPAsOffset(Value *Start, Value *Base,
462462 if (!GEP->isInBounds () || count_if (GEP->indices (), IsNonConst) > 1 )
463463 return false ;
464464
465+ NW = NW.intersectForOffsetAdd (GEP->getNoWrapFlags ());
465466 if (!Explored.contains (GEP->getOperand (0 )))
466467 WorkList.push_back (GEP->getOperand (0 ));
467468 }
@@ -536,7 +537,7 @@ static void setInsertionPoint(IRBuilder<> &Builder, Value *V,
536537
537538// / Returns a re-written value of Start as an indexed GEP using Base as a
538539// / pointer.
539- static Value *rewriteGEPAsOffset (Value *Start, Value *Base,
540+ static Value *rewriteGEPAsOffset (Value *Start, Value *Base, GEPNoWrapFlags NW,
540541 const DataLayout &DL,
541542 SetVector<Value *> &Explored,
542543 InstCombiner &IC) {
@@ -578,8 +579,10 @@ static Value *rewriteGEPAsOffset(Value *Start, Value *Base,
578579 if (isa<ConstantInt>(Op) && cast<ConstantInt>(Op)->isZero ())
579580 NewInsts[GEP] = OffsetV;
580581 else
581- NewInsts[GEP] = Builder.CreateNSWAdd (
582- Op, OffsetV, GEP->getOperand (0 )->getName () + " .add" );
582+ NewInsts[GEP] = Builder.CreateAdd (
583+ Op, OffsetV, GEP->getOperand (0 )->getName () + " .add" ,
584+ /* NUW=*/ NW.hasNoUnsignedWrap (),
585+ /* NSW=*/ NW.hasNoUnsignedSignedWrap ());
583586 continue ;
584587 }
585588 if (isa<PHINode>(Val))
@@ -613,8 +616,8 @@ static Value *rewriteGEPAsOffset(Value *Start, Value *Base,
613616
614617 setInsertionPoint (Builder, Val, false );
615618 // Create GEP for external users.
616- Value *NewVal = Builder.CreateInBoundsGEP (
617- Builder. getInt8Ty (), Base, NewInsts[Val], Val->getName () + " .ptr" );
619+ Value *NewVal = Builder.CreateGEP (Builder. getInt8Ty (), Base, NewInsts[Val],
620+ Val->getName () + " .ptr" , NW );
618621 IC.replaceInstUsesWith (*cast<Instruction>(Val), NewVal);
619622 // Add old instruction to worklist for DCE. We don't directly remove it
620623 // here because the original compare is one of the users.
@@ -649,8 +652,8 @@ static Instruction *transformToIndexedCompare(GEPOperator *GEPLHS, Value *RHS,
649652
650653 // The set of nodes that will take part in this transformation.
651654 SetVector<Value *> Nodes;
652-
653- if (!canRewriteGEPAsOffset (RHS, PtrBase, DL, Nodes))
655+ GEPNoWrapFlags NW = GEPLHS-> getNoWrapFlags ();
656+ if (!canRewriteGEPAsOffset (RHS, PtrBase, NW, DL, Nodes))
654657 return nullptr ;
655658
656659 // We know we can re-write this as
@@ -659,7 +662,7 @@ static Instruction *transformToIndexedCompare(GEPOperator *GEPLHS, Value *RHS,
659662 // can't have overflow on either side. We can therefore re-write
660663 // this as:
661664 // OFFSET1 cmp OFFSET2
662- Value *NewRHS = rewriteGEPAsOffset (RHS, PtrBase, DL, Nodes, IC);
665+ Value *NewRHS = rewriteGEPAsOffset (RHS, PtrBase, NW, DL, Nodes, IC);
663666
664667 // RewriteGEPAsOffset has replaced RHS and all of its uses with a re-written
665668 // GEP having PtrBase as the pointer base, and has returned in NewRHS the
0 commit comments