Skip to content

Commit 00cfbf5

Browse files
fhahnsmithp35
authored andcommitted
[SCEVExp] Keep NUW/NSW if both original inc and isomporphic inc agree. (llvm#79512)
We are replacing with a wider increment. If both OrigInc and IsomorphicInc are NUW/NSW, then we can preserve them on the wider increment; the narrower IsomorphicInc would wrap before the wider OrigInc, so the replacement won't make IsomorphicInc's uses more poisonous. PR: llvm#79512
1 parent 8afe476 commit 00cfbf5

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,11 +1604,36 @@ void SCEVExpander::replaceCongruentIVInc(
16041604
const SCEV *TruncExpr =
16051605
SE.getTruncateOrNoop(SE.getSCEV(OrigInc), IsomorphicInc->getType());
16061606
if (OrigInc == IsomorphicInc || TruncExpr != SE.getSCEV(IsomorphicInc) ||
1607-
!SE.LI.replacementPreservesLCSSAForm(IsomorphicInc, OrigInc) ||
1608-
!hoistIVInc(OrigInc, IsomorphicInc,
1607+
!SE.LI.replacementPreservesLCSSAForm(IsomorphicInc, OrigInc))
1608+
return;
1609+
1610+
bool BothHaveNUW = false;
1611+
bool BothHaveNSW = false;
1612+
auto *OBOIncV = dyn_cast<OverflowingBinaryOperator>(OrigInc);
1613+
auto *OBOIsomorphic = dyn_cast<OverflowingBinaryOperator>(IsomorphicInc);
1614+
if (OBOIncV && OBOIsomorphic) {
1615+
BothHaveNUW =
1616+
OBOIncV->hasNoUnsignedWrap() && OBOIsomorphic->hasNoUnsignedWrap();
1617+
BothHaveNSW =
1618+
OBOIncV->hasNoSignedWrap() && OBOIsomorphic->hasNoSignedWrap();
1619+
}
1620+
1621+
if (!hoistIVInc(OrigInc, IsomorphicInc,
16091622
/*RecomputePoisonFlags*/ true))
16101623
return;
16111624

1625+
// We are replacing with a wider increment. If both OrigInc and IsomorphicInc
1626+
// are NUW/NSW, then we can preserve them on the wider increment; the narrower
1627+
// IsomorphicInc would wrap before the wider OrigInc, so the replacement won't
1628+
// make IsomorphicInc's uses more poisonous.
1629+
assert(OrigInc->getType()->getScalarSizeInBits() >=
1630+
IsomorphicInc->getType()->getScalarSizeInBits() &&
1631+
"Should only replace an increment with a wider one.");
1632+
if (BothHaveNUW || BothHaveNSW) {
1633+
OrigInc->setHasNoUnsignedWrap(OBOIncV->hasNoUnsignedWrap() || BothHaveNUW);
1634+
OrigInc->setHasNoSignedWrap(OBOIncV->hasNoSignedWrap() || BothHaveNSW);
1635+
}
1636+
16121637
SCEV_DEBUG_WITH_TYPE(DebugType,
16131638
dbgs() << "INDVARS: Eliminated congruent iv.inc: "
16141639
<< *IsomorphicInc << '\n');

llvm/test/Transforms/IndVarSimplify/iv-poison.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ define i2 @iv_hoist_both_adds_nsw(i2 %arg) {
6464
; CHECK-NEXT: br label [[LOOP:%.*]]
6565
; CHECK: loop:
6666
; CHECK-NEXT: [[IV_0:%.*]] = phi i2 [ 1, [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
67-
; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i2 [[IV_0]], 1
67+
; CHECK-NEXT: [[IV_0_NEXT]] = add nuw nsw i2 [[IV_0]], 1
6868
; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i2 1, [[ARG:%.*]]
6969
; CHECK-NEXT: br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
7070
; CHECK: exit:
@@ -92,7 +92,7 @@ define i4 @iv_hoist_both_adds_nsw_extra_use(i4 %arg) {
9292
; CHECK-NEXT: br label [[LOOP:%.*]]
9393
; CHECK: loop:
9494
; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ 1, [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
95-
; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1
95+
; CHECK-NEXT: [[IV_0_NEXT]] = add nuw nsw i4 [[IV_0]], 1
9696
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
9797
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
9898
; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 1, [[ARG:%.*]]
@@ -124,7 +124,7 @@ define i4 @iv_hoist_both_adds_nsw_extra_use_incs_reordered(i4 %arg) {
124124
; CHECK-NEXT: br label [[LOOP:%.*]]
125125
; CHECK: loop:
126126
; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ 1, [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
127-
; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1
127+
; CHECK-NEXT: [[IV_0_NEXT]] = add nuw nsw i4 [[IV_0]], 1
128128
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
129129
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
130130
; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 1, [[ARG:%.*]]
@@ -244,7 +244,7 @@ define i2 @iv_hoist_both_adds_nuw(i2 %arg, i2 %start) {
244244
; CHECK-NEXT: br label [[LOOP:%.*]]
245245
; CHECK: loop:
246246
; CHECK-NEXT: [[IV_0:%.*]] = phi i2 [ [[START:%.*]], [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
247-
; CHECK-NEXT: [[IV_0_NEXT]] = add i2 [[IV_0]], 1
247+
; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i2 [[IV_0]], 1
248248
; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i2 [[START]], [[ARG:%.*]]
249249
; CHECK-NEXT: br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
250250
; CHECK: exit:
@@ -272,7 +272,7 @@ define i4 @iv_hoist_both_adds_nuw_extra_use(i4 %arg, i4 %start) {
272272
; CHECK-NEXT: br label [[LOOP:%.*]]
273273
; CHECK: loop:
274274
; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
275-
; CHECK-NEXT: [[IV_0_NEXT]] = add i4 [[IV_0]], 1
275+
; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1
276276
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
277277
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
278278
; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[START]], [[ARG:%.*]]
@@ -304,7 +304,7 @@ define i4 @iv_hoist_both_adds_nuw_extra_use_incs_reordered(i4 %arg, i4 %start) {
304304
; CHECK-NEXT: br label [[LOOP:%.*]]
305305
; CHECK: loop:
306306
; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
307-
; CHECK-NEXT: [[IV_0_NEXT]] = add i4 [[IV_0]], 1
307+
; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1
308308
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
309309
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
310310
; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[START]], [[ARG:%.*]]

0 commit comments

Comments
 (0)