[llvm] bec7181 - [SCEVExpander] Don't use recursive expansion for ptr IV inc

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 7 02:31:06 PST 2024


Author: Nikita Popov
Date: 2024-02-07T11:27:26+01:00
New Revision: bec7181d5b9d1828129d78d440fd9e02d5cb63e8

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

LOG: [SCEVExpander] Don't use recursive expansion for ptr IV inc

Similar to the non-ptr case, directly create the getelementptr
instruction. Going through expandAddToGEP() no longer makes sense
with opaque pointers, where generating the necessary instruction
is trivial.

This avoids recursive expansion of (the SCEV of) StepV while the
IR is in an inconsistent state, in particular with an incomplete
IV phi node, which utilities may not be prepared to deal with.

Fixes https://github.com/llvm/llvm-project/issues/80954.

Added: 
    llvm/test/Transforms/LoopIdiom/pr80954.ll

Modified: 
    llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 58dbac0e85fb04..3a28909473d95f 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -795,7 +795,8 @@ Value *SCEVExpander::expandIVInc(PHINode *PN, Value *StepV, const Loop *L,
   Value *IncV;
   // If the PHI is a pointer, use a GEP, otherwise use an add or sub.
   if (PN->getType()->isPointerTy()) {
-    IncV = expandAddToGEP(SE.getSCEV(StepV), PN);
+    // TODO: Change name to IVName.iv.next.
+    IncV = Builder.CreatePtrAdd(PN, StepV, "scevgep");
   } else {
     IncV = useSubtract ?
       Builder.CreateSub(PN, StepV, Twine(IVName) + ".iv.next") :

diff  --git a/llvm/test/Transforms/LoopIdiom/pr80954.ll b/llvm/test/Transforms/LoopIdiom/pr80954.ll
new file mode 100644
index 00000000000000..55bdcb44c2c283
--- /dev/null
+++ b/llvm/test/Transforms/LoopIdiom/pr80954.ll
@@ -0,0 +1,68 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -S -passes=loop-idiom < %s | FileCheck %s
+
+; Make sure this does not assert in SCEVExpander.
+
+define void @test(ptr %p, i8 %arg, i64 %arg1, i32 %arg2) {
+; CHECK-LABEL: define void @test(
+; CHECK-SAME: ptr [[P:%.*]], i8 [[ARG:%.*]], i64 [[ARG1:%.*]], i32 [[ARG2:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SEXT:%.*]] = sext i8 [[ARG]] to i64
+; CHECK-NEXT:    [[ADD:%.*]] = add i64 [[ARG1]], -1
+; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[ARG2]] to i64
+; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[ARG1]], [[TMP0]]
+; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[TMP1]], [[SEXT]]
+; CHECK-NEXT:    [[TMP3:%.*]] = add i64 [[TMP2]], -1
+; CHECK-NEXT:    [[TMP4:%.*]] = shl i64 [[TMP3]], 2
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[LOOP_IDIOM_IV:%.*]] = phi ptr [ [[SCEVGEP:%.*]], [[LATCH:%.*]] ], [ [[P]], [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[INDVAR:%.*]] = phi i64 [ [[INDVAR_NEXT:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[IV_NEXT:%.*]], [[LATCH]] ]
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[ARG2]], [[ENTRY]] ], [ [[ADD9:%.*]], [[LATCH]] ]
+; CHECK-NEXT:    [[TMP5:%.*]] = shl i64 [[INDVAR]], 2
+; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[TMP4]], [[TMP5]]
+; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[LOOP_IDIOM_IV]], i8 0, i64 0, i1 false)
+; CHECK-NEXT:    br label [[LOOP2:%.*]]
+; CHECK:       loop2:
+; CHECK-NEXT:    [[IV2:%.*]] = phi i64 [ [[IV2_NEXT:%.*]], [[LOOP2]] ], [ 0, [[LOOP]] ]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [4 x i8], ptr [[P]], i64 [[IV]], i64 [[IV2]]
+; CHECK-NEXT:    [[IV2_NEXT]] = add i64 [[IV2]], 1
+; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq i64 [[IV2_NEXT]], 0
+; CHECK-NEXT:    br i1 [[ICMP]], label [[LATCH]], label [[LOOP2]]
+; CHECK:       latch:
+; CHECK-NEXT:    [[ADD9]] = add nsw i32 [[PHI]], 1
+; CHECK-NEXT:    [[SEXT10:%.*]] = sext i32 [[PHI]] to i64
+; CHECK-NEXT:    [[ADD11:%.*]] = add i64 [[ADD]], [[SEXT10]]
+; CHECK-NEXT:    [[ADD12:%.*]] = add i64 [[ADD11]], [[SEXT]]
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[ADD12]], [[IV]]
+; CHECK-NEXT:    [[INDVAR_NEXT]] = add i64 [[INDVAR]], 1
+; CHECK-NEXT:    [[SCEVGEP]] = getelementptr i8, ptr [[LOOP_IDIOM_IV]], i64 [[TMP6]]
+; CHECK-NEXT:    br label [[LOOP]]
+;
+entry:
+  %sext = sext i8 %arg to i64
+  %add = add i64 %arg1, -1
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
+  %phi = phi i32 [ %arg2, %entry ], [ %add9, %latch ]
+  br label %loop2
+
+loop2:
+  %iv2 = phi i64 [ %iv2.next, %loop2 ], [ 0, %loop ]
+  %gep = getelementptr [4 x i8], ptr %p, i64 %iv, i64 %iv2
+  store i8 0, ptr %gep, align 1
+  %iv2.next = add i64 %iv2, 1
+  %icmp = icmp eq i64 %iv2.next, 0
+  br i1 %icmp, label %latch, label %loop2
+
+latch:
+  %add9 = add nsw i32 %phi, 1
+  %sext10 = sext i32 %phi to i64
+  %add11 = add i64 %add, %sext10
+  %add12 = add i64 %add11, %sext
+  %iv.next = add i64 %add12, %iv
+  br label %loop
+}


        


More information about the llvm-commits mailing list