@@ -1153,6 +1153,7 @@ class WidenIV {
11531153
11541154 Instruction *widenIVUse (NarrowIVDefUse DU, SCEVExpander &Rewriter,
11551155 PHINode *OrigPhi, PHINode *WidePhi);
1156+ void truncateIVUse (NarrowIVDefUse DU);
11561157
11571158 bool widenLoopCompare (NarrowIVDefUse DU);
11581159 bool widenWithVariantUse (NarrowIVDefUse DU);
@@ -1569,15 +1570,18 @@ WidenIV::WidenedRecTy WidenIV::getWideRecurrence(WidenIV::NarrowIVDefUse DU) {
15691570
15701571// / This IV user cannot be widened. Replace this use of the original narrow IV
15711572// / with a truncation of the new wide IV to isolate and eliminate the narrow IV.
1572- static void truncateIVUse (WidenIV::NarrowIVDefUse DU, DominatorTree *DT,
1573- LoopInfo *LI) {
1573+ void WidenIV::truncateIVUse (NarrowIVDefUse DU) {
15741574 auto *InsertPt = getInsertPointForUses (DU.NarrowUse , DU.NarrowDef , DT, LI);
15751575 if (!InsertPt)
15761576 return ;
15771577 LLVM_DEBUG (dbgs () << " INDVARS: Truncate IV " << *DU.WideDef << " for user "
15781578 << *DU.NarrowUse << " \n " );
1579+ ExtendKind ExtKind = getExtendKind (DU.NarrowDef );
15791580 IRBuilder<> Builder (InsertPt);
1580- Value *Trunc = Builder.CreateTrunc (DU.WideDef , DU.NarrowDef ->getType ());
1581+ Value *Trunc =
1582+ Builder.CreateTrunc (DU.WideDef , DU.NarrowDef ->getType (), " " ,
1583+ DU.NeverNegative || ExtKind == ExtendKind::Zero,
1584+ DU.NeverNegative || ExtKind == ExtendKind::Sign);
15811585 DU.NarrowUse ->replaceUsesOfWith (DU.NarrowDef , Trunc);
15821586}
15831587
@@ -1826,14 +1830,21 @@ Instruction *WidenIV::widenIVUse(WidenIV::NarrowIVDefUse DU,
18261830 assert (ExtendKindMap.count (DU.NarrowDef ) &&
18271831 " Should already know the kind of extension used to widen NarrowDef" );
18281832
1833+ // This narrow use can be widened by a sext if it's non-negative or its narrow
1834+ // def was widened by a sext. Same for zext.
1835+ bool CanWidenBySExt =
1836+ DU.NeverNegative || getExtendKind (DU.NarrowDef ) == ExtendKind::Sign;
1837+ bool CanWidenByZExt =
1838+ DU.NeverNegative || getExtendKind (DU.NarrowDef ) == ExtendKind::Zero;
1839+
18291840 // Stop traversing the def-use chain at inner-loop phis or post-loop phis.
18301841 if (PHINode *UsePhi = dyn_cast<PHINode>(DU.NarrowUse )) {
18311842 if (LI->getLoopFor (UsePhi->getParent ()) != L) {
18321843 // For LCSSA phis, sink the truncate outside the loop.
18331844 // After SimplifyCFG most loop exit targets have a single predecessor.
18341845 // Otherwise fall back to a truncate within the loop.
18351846 if (UsePhi->getNumOperands () != 1 )
1836- truncateIVUse (DU, DT, LI );
1847+ truncateIVUse (DU);
18371848 else {
18381849 // Widening the PHI requires us to insert a trunc. The logical place
18391850 // for this trunc is in the same BB as the PHI. This is not possible if
@@ -1847,7 +1858,8 @@ Instruction *WidenIV::widenIVUse(WidenIV::NarrowIVDefUse DU,
18471858 WidePhi->addIncoming (DU.WideDef , UsePhi->getIncomingBlock (0 ));
18481859 BasicBlock *WidePhiBB = WidePhi->getParent ();
18491860 IRBuilder<> Builder (WidePhiBB, WidePhiBB->getFirstInsertionPt ());
1850- Value *Trunc = Builder.CreateTrunc (WidePhi, DU.NarrowDef ->getType ());
1861+ Value *Trunc = Builder.CreateTrunc (WidePhi, DU.NarrowDef ->getType (), " " ,
1862+ CanWidenByZExt, CanWidenBySExt);
18511863 UsePhi->replaceAllUsesWith (Trunc);
18521864 DeadInsts.emplace_back (UsePhi);
18531865 LLVM_DEBUG (dbgs () << " INDVARS: Widen lcssa phi " << *UsePhi << " to "
@@ -1857,26 +1869,18 @@ Instruction *WidenIV::widenIVUse(WidenIV::NarrowIVDefUse DU,
18571869 }
18581870 }
18591871
1860- // This narrow use can be widened by a sext if it's non-negative or its narrow
1861- // def was widened by a sext. Same for zext.
1862- auto canWidenBySExt = [&]() {
1863- return DU.NeverNegative || getExtendKind (DU.NarrowDef ) == ExtendKind::Sign;
1864- };
1865- auto canWidenByZExt = [&]() {
1866- return DU.NeverNegative || getExtendKind (DU.NarrowDef ) == ExtendKind::Zero;
1867- };
1868-
18691872 // Our raison d'etre! Eliminate sign and zero extension.
1870- if ((match (DU.NarrowUse , m_SExtLike (m_Value ())) && canWidenBySExt () ) ||
1871- (isa<ZExtInst>(DU.NarrowUse ) && canWidenByZExt () )) {
1873+ if ((match (DU.NarrowUse , m_SExtLike (m_Value ())) && CanWidenBySExt ) ||
1874+ (isa<ZExtInst>(DU.NarrowUse ) && CanWidenByZExt )) {
18721875 Value *NewDef = DU.WideDef ;
18731876 if (DU.NarrowUse ->getType () != WideType) {
18741877 unsigned CastWidth = SE->getTypeSizeInBits (DU.NarrowUse ->getType ());
18751878 unsigned IVWidth = SE->getTypeSizeInBits (WideType);
18761879 if (CastWidth < IVWidth) {
18771880 // The cast isn't as wide as the IV, so insert a Trunc.
18781881 IRBuilder<> Builder (DU.NarrowUse );
1879- NewDef = Builder.CreateTrunc (DU.WideDef , DU.NarrowUse ->getType ());
1882+ NewDef = Builder.CreateTrunc (DU.WideDef , DU.NarrowUse ->getType (), " " ,
1883+ CanWidenByZExt, CanWidenBySExt);
18801884 }
18811885 else {
18821886 // A wider extend was hidden behind a narrower one. This may induce
@@ -1975,7 +1979,7 @@ Instruction *WidenIV::widenIVUse(WidenIV::NarrowIVDefUse DU,
19751979 // This user does not evaluate to a recurrence after widening, so don't
19761980 // follow it. Instead insert a Trunc to kill off the original use,
19771981 // eventually isolating the original narrow IV so it can be removed.
1978- truncateIVUse (DU, DT, LI );
1982+ truncateIVUse (DU);
19791983 return nullptr ;
19801984}
19811985
0 commit comments