https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/79512
>From 299a055e271264f918321bf7360ee37c6ede8b26 Mon Sep 17 00:00:00 2001 From: Florian Hahn <f...@fhahn.com> Date: Tue, 23 Jan 2024 13:39:38 +0000 Subject: [PATCH 1/2] [SCEVExp] Keep NUW/NSW if both original inc and isomporphic inc agree. 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. --- .../Utils/ScalarEvolutionExpander.cpp | 28 +++++++++++++++++-- .../Transforms/IndVarSimplify/iv-poison.ll | 12 ++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp index cf8cea937a6bf..902c4db883769 100644 --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -1607,11 +1607,35 @@ void SCEVExpander::replaceCongruentIVInc( const SCEV *TruncExpr = SE.getTruncateOrNoop(SE.getSCEV(OrigInc), IsomorphicInc->getType()); if (OrigInc == IsomorphicInc || TruncExpr != SE.getSCEV(IsomorphicInc) || - !SE.LI.replacementPreservesLCSSAForm(IsomorphicInc, OrigInc) || - !hoistIVInc(OrigInc, IsomorphicInc, + !SE.LI.replacementPreservesLCSSAForm(IsomorphicInc, OrigInc)) + return; + + bool BothHaveNUW = false; + bool BothHaveNSW = false; + auto *OBOIncV = dyn_cast<OverflowingBinaryOperator>(OrigInc); + auto *OBOIsomorphic = dyn_cast<OverflowingBinaryOperator>(IsomorphicInc); + assert(OrigInc->getType()->getScalarSizeInBits() >= + IsomorphicInc->getType()->getScalarSizeInBits()) && "Should only replace an increment with a wider one."); + if (OBOIncV && OBOIsomorphic) { + BothHaveNUW = + OBOIncV->hasNoUnsignedWrap() && OBOIsomorphic->hasNoUnsignedWrap(); + BothHaveNSW = + OBOIncV->hasNoSignedWrap() && OBOIsomorphic->hasNoSignedWrap(); + } + + if (!hoistIVInc(OrigInc, IsomorphicInc, /*RecomputePoisonFlags*/ true)) return; + // 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. + if (BothHaveNUW || BothHaveNSW) { + OrigInc->setHasNoUnsignedWrap(OBOIncV->hasNoUnsignedWrap() || BothHaveNUW); + OrigInc->setHasNoSignedWrap(OBOIncV->hasNoSignedWrap() || BothHaveNSW); + } + SCEV_DEBUG_WITH_TYPE(DebugType, dbgs() << "INDVARS: Eliminated congruent iv.inc: " << *IsomorphicInc << '\n'); diff --git a/llvm/test/Transforms/IndVarSimplify/iv-poison.ll b/llvm/test/Transforms/IndVarSimplify/iv-poison.ll index 38299e0a6b353..383599f614357 100644 --- a/llvm/test/Transforms/IndVarSimplify/iv-poison.ll +++ b/llvm/test/Transforms/IndVarSimplify/iv-poison.ll @@ -64,7 +64,7 @@ define i2 @iv_hoist_both_adds_nsw(i2 %arg) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV_0:%.*]] = phi i2 [ 1, [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i2 [[IV_0]], 1 +; CHECK-NEXT: [[IV_0_NEXT]] = add nuw nsw i2 [[IV_0]], 1 ; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i2 1, [[ARG:%.*]] ; CHECK-NEXT: br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]] ; CHECK: exit: @@ -92,7 +92,7 @@ define i4 @iv_hoist_both_adds_nsw_extra_use(i4 %arg) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ 1, [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1 +; CHECK-NEXT: [[IV_0_NEXT]] = add nuw nsw i4 [[IV_0]], 1 ; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]]) ; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]]) ; 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) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ 1, [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1 +; CHECK-NEXT: [[IV_0_NEXT]] = add nuw nsw i4 [[IV_0]], 1 ; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]]) ; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]]) ; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 1, [[ARG:%.*]] @@ -244,7 +244,7 @@ define i2 @iv_hoist_both_adds_nuw(i2 %arg, i2 %start) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV_0:%.*]] = phi i2 [ [[START:%.*]], [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[IV_0_NEXT]] = add i2 [[IV_0]], 1 +; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i2 [[IV_0]], 1 ; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i2 [[START]], [[ARG:%.*]] ; CHECK-NEXT: br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]] ; CHECK: exit: @@ -272,7 +272,7 @@ define i4 @iv_hoist_both_adds_nuw_extra_use(i4 %arg, i4 %start) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[IV_0_NEXT]] = add i4 [[IV_0]], 1 +; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1 ; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]]) ; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]]) ; 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) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[IV_0_NEXT]] = add i4 [[IV_0]], 1 +; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1 ; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]]) ; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]]) ; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[START]], [[ARG:%.*]] >From d75c570c47b1463d9c677ed9f295ed7aaae17b60 Mon Sep 17 00:00:00 2001 From: Florian Hahn <f...@fhahn.com> Date: Thu, 1 Feb 2024 09:39:56 +0000 Subject: [PATCH 2/2] !fixup remove extra ) from assert, move to comment. --- llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp index e2e086b2a17b8..ed55a13072aaa 100644 --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -1611,8 +1611,6 @@ void SCEVExpander::replaceCongruentIVInc( bool BothHaveNSW = false; auto *OBOIncV = dyn_cast<OverflowingBinaryOperator>(OrigInc); auto *OBOIsomorphic = dyn_cast<OverflowingBinaryOperator>(IsomorphicInc); - assert(OrigInc->getType()->getScalarSizeInBits() >= - IsomorphicInc->getType()->getScalarSizeInBits()) && "Should only replace an increment with a wider one."); if (OBOIncV && OBOIsomorphic) { BothHaveNUW = OBOIncV->hasNoUnsignedWrap() && OBOIsomorphic->hasNoUnsignedWrap(); @@ -1628,6 +1626,9 @@ void SCEVExpander::replaceCongruentIVInc( // 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. + assert(OrigInc->getType()->getScalarSizeInBits() >= + IsomorphicInc->getType()->getScalarSizeInBits() && + "Should only replace an increment with a wider one."); if (BothHaveNUW || BothHaveNSW) { OrigInc->setHasNoUnsignedWrap(OBOIncV->hasNoUnsignedWrap() || BothHaveNUW); OrigInc->setHasNoSignedWrap(OBOIncV->hasNoSignedWrap() || BothHaveNSW); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits