[IndVarSimplify] Forget phi value after changing incoming value.
authorFlorian Hahn <flo@fhahn.com>
Wed, 29 Sep 2021 13:38:35 +0000 (14:38 +0100)
committerFlorian Hahn <flo@fhahn.com>
Wed, 29 Sep 2021 13:44:13 +0000 (14:44 +0100)
This fixes an issue exposed by D71539, where IndVarSimplify tries
to access an invalid cached SCEV expression after making changes to the
underlying PHI instruction earlier.

When changing the incoming value of a PHI, forget the cached SCEV for
the PHI.

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
llvm/test/Transforms/IndVarSimplify/invalidate-modified-lcssa-phi.ll [new file with mode: 0644]

index 6d13b3b..0b5979a 100644 (file)
@@ -494,6 +494,7 @@ bool IndVarSimplify::rewriteFirstIterationLoopExitValues(Loop *L) {
           MadeAnyChanges = true;
           PN.setIncomingValue(IncomingValIdx,
                               ExitVal->getIncomingValue(PreheaderIdx));
+          SE->forgetValue(&PN);
         }
       }
     }
diff --git a/llvm/test/Transforms/IndVarSimplify/invalidate-modified-lcssa-phi.ll b/llvm/test/Transforms/IndVarSimplify/invalidate-modified-lcssa-phi.ll
new file mode 100644 (file)
index 0000000..fcb35a0
--- /dev/null
@@ -0,0 +1,44 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes='loop(indvars,loop-deletion)' -S %s | FileCheck %s
+
+; Make sure indvarsimplify properly forgets the exit value %p.2.lcssa phi after
+; modifying it. Loop deletion is required to show the incorrect use of the cached
+; SCEV value.
+
+define void @test(i1 %c) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[HEADER_1:%.*]]
+; CHECK:       header.1.loopexit:
+; CHECK-NEXT:    br label [[HEADER_1_BACKEDGE:%.*]]
+; CHECK:       header.1:
+; CHECK-NEXT:    br label [[HEADER_2:%.*]]
+; CHECK:       header.2:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[LATCH_1:%.*]], label [[LATCH_2:%.*]]
+; CHECK:       latch.1:
+; CHECK-NEXT:    br label [[HEADER_1_LOOPEXIT:%.*]]
+; CHECK:       latch.2:
+; CHECK-NEXT:    br label [[HEADER_1_BACKEDGE]]
+; CHECK:       header.1.backedge:
+; CHECK-NEXT:    br label [[HEADER_1]]
+;
+entry:
+  br label %header.1
+
+header.1:
+  %p.1 = phi i32 [ 0, %entry ], [ %p.2.lcssa, %latch.2 ], [ 0, %latch.1 ]
+  br label %header.2
+
+header.2:
+  %p.2 = phi i32 [ %p.1, %header.1 ], [ %p.2.next, %latch.1 ]
+  br i1 %c, label %latch.1, label %latch.2
+
+latch.1:
+  %p.2.next = add i32 %p.2, 1
+  br i1 false, label %header.2, label %header.1
+
+latch.2:
+  %p.2.lcssa = phi i32 [ %p.2, %header.2 ]
+  br label %header.1
+
+}