[llvm] 7854a1a - [SimpleLoopUnswitch] Forget SCEVs for replaced phis.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 13 09:39:00 PST 2022


Author: Florian Hahn
Date: 2022-11-13T17:38:39Z
New Revision: 7854a1abfd9a52dec0fe5d668e26de19614faefb

URL: https://github.com/llvm/llvm-project/commit/7854a1abfd9a52dec0fe5d668e26de19614faefb
DIFF: https://github.com/llvm/llvm-project/commit/7854a1abfd9a52dec0fe5d668e26de19614faefb.diff

LOG: [SimpleLoopUnswitch] Forget SCEVs for replaced phis.

Forget SCEVs based on exit phis in case SCEV looked through the phi.
After unswitching, it may not be possible to look through the phi due to
it having multiple incoming values, so it needs to be re-computed.

Fixes #58868

Added: 
    llvm/test/Transforms/SimpleLoopUnswitch/pr58868-scev-invalidation-for-phis.ll

Modified: 
    llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
index f7ecc47947151..f6f3c8fffb8b7 100644
--- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
+++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
@@ -1114,7 +1114,8 @@ static BasicBlock *buildClonedLoopBlocks(
     const SmallDenseMap<BasicBlock *, BasicBlock *, 16> &DominatingSucc,
     ValueToValueMapTy &VMap,
     SmallVectorImpl<DominatorTree::UpdateType> &DTUpdates, AssumptionCache &AC,
-    DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU) {
+    DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU,
+    ScalarEvolution *SE) {
   SmallVector<BasicBlock *, 4> NewBlocks;
   NewBlocks.reserve(L.getNumBlocks() + ExitBlocks.size());
 
@@ -1190,6 +1191,10 @@ static BasicBlock *buildClonedLoopBlocks(
       // We should have a value map between the instruction and its clone.
       assert(VMap.lookup(&I) == &ClonedI && "Mismatch in the value map!");
 
+      // Forget SCEVs based on exit phis in case SCEV looked through the phi.
+      if (SE && isa<PHINode>(I))
+        SE->forgetValue(&I);
+
       auto *MergePN =
           PHINode::Create(I.getType(), /*NumReservedValues*/ 2, ".us-phi",
                           &*MergeBB->getFirstInsertionPt());
@@ -2218,7 +2223,7 @@ static void unswitchNontrivialInvariants(
     VMaps.emplace_back(new ValueToValueMapTy());
     ClonedPHs[SuccBB] = buildClonedLoopBlocks(
         L, LoopPH, SplitBB, ExitBlocks, ParentBB, SuccBB, RetainedSuccBB,
-        DominatingSucc, *VMaps.back(), DTUpdates, AC, DT, LI, MSSAU);
+        DominatingSucc, *VMaps.back(), DTUpdates, AC, DT, LI, MSSAU, SE);
   }
 
   // Drop metadata if we may break its semantics by moving this instr into the

diff  --git a/llvm/test/Transforms/SimpleLoopUnswitch/pr58868-scev-invalidation-for-phis.ll b/llvm/test/Transforms/SimpleLoopUnswitch/pr58868-scev-invalidation-for-phis.ll
new file mode 100644
index 0000000000000..2a8553c69c401
--- /dev/null
+++ b/llvm/test/Transforms/SimpleLoopUnswitch/pr58868-scev-invalidation-for-phis.ll
@@ -0,0 +1,73 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes="loop-mssa(loop-deletion,simple-loop-unswitch<nontrivial;trivial>),loop(indvars)" -verify-scev -S %s | FileCheck %s
+
+define void @pr58868(i1 %c.1, ptr %src, ptr %dst) {
+; CHECK-LABEL: @pr58868(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
+; CHECK:       entry.split.us:
+; CHECK-NEXT:    br label [[OUTER_HEADER_US:%.*]]
+; CHECK:       outer.header.us:
+; CHECK-NEXT:    br label [[OUTER_BB1_US:%.*]]
+; CHECK:       outer.bb1.us:
+; CHECK-NEXT:    br label [[OUTER_BB2_US:%.*]]
+; CHECK:       outer.bb2.us:
+; CHECK-NEXT:    [[LV_US:%.*]] = load i16, ptr [[SRC:%.*]], align 1
+; CHECK-NEXT:    br i1 true, label [[OUTER_HEADER_LOOPEXIT_US:%.*]], label [[OUTER_BB2_SPLIT_SPLIT_US:%.*]]
+; CHECK:       outer.header.loopexit.us:
+; CHECK-NEXT:    br label [[OUTER_HEADER_US]]
+; CHECK:       outer.bb2.split.split.us:
+; CHECK-NEXT:    [[LV_LCSSA_US:%.*]] = phi i16 [ [[LV_US]], [[OUTER_BB2_US]] ]
+; CHECK-NEXT:    br label [[OUTER_BB2_SPLIT:%.*]]
+; CHECK:       entry.split:
+; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
+; CHECK:       outer.header.loopexit:
+; CHECK-NEXT:    unreachable
+; CHECK:       outer.header:
+; CHECK-NEXT:    br label [[OUTER_BB2:%.*]]
+; CHECK:       outer.bb2:
+; CHECK-NEXT:    [[LV:%.*]] = load i16, ptr [[SRC]], align 1
+; CHECK-NEXT:    br i1 false, label [[OUTER_HEADER_LOOPEXIT:%.*]], label [[OUTER_BB2_SPLIT_SPLIT:%.*]]
+; CHECK:       outer.bb2.split.split:
+; CHECK-NEXT:    [[LV_LCSSA:%.*]] = phi i16 [ [[LV]], [[OUTER_BB2]] ]
+; CHECK-NEXT:    br label [[OUTER_BB2_SPLIT]]
+; CHECK:       outer.bb2.split:
+; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i16 [ [[LV_LCSSA]], [[OUTER_BB2_SPLIT_SPLIT]] ], [ [[LV_LCSSA_US]], [[OUTER_BB2_SPLIT_SPLIT_US]] ]
+; CHECK-NEXT:    br label [[INNER_HEADER:%.*]]
+; CHECK:       inner.header:
+; CHECK-NEXT:    [[IV:%.*]] = phi i16 [ [[DOTUS_PHI]], [[OUTER_BB2_SPLIT]] ], [ [[IV_NEXT:%.*]], [[INNER_LATCH:%.*]] ]
+; CHECK-NEXT:    br label [[INNER_LATCH]]
+; CHECK:       inner.latch:
+; CHECK-NEXT:    [[IV_NEXT]] = add nsw i16 [[IV]], 1
+; CHECK-NEXT:    store i16 0, ptr [[DST:%.*]], align 1
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i16 [[IV]], 0
+; CHECK-NEXT:    br i1 [[C_2]], label [[INNER_HEADER]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %outer.header
+
+outer.header:
+  br i1 %c.1, label %outer.bb1, label %outer.bb2
+
+outer.bb1:
+  br label %outer.bb2
+
+outer.bb2:
+  %lv = load i16, ptr %src, align 1
+  br label %inner.header
+
+inner.header:
+  %iv = phi i16 [ %lv, %outer.bb2 ], [ %iv.next, %inner.latch ]
+  br i1 %c.1, label %outer.header, label %inner.latch
+
+inner.latch:
+  %iv.next = add nsw i16 %iv, 1
+  store i16 0, ptr %dst, align 1
+  %c.2 = icmp ne i16 %iv, 0
+  br i1 %c.2, label %inner.header, label %exit
+
+exit:
+  ret void
+}


        


More information about the llvm-commits mailing list