[llvm] daf32b1 - [IndVars] Support opaque pointers in LFTR

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 27 03:32:59 PST 2021


Author: Nikita Popov
Date: 2021-12-27T12:32:50+01:00
New Revision: daf32b13d7009e4c53cad71132564f49bac61cb7

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

LOG: [IndVars] Support opaque pointers in LFTR

Remove the assertion about the pointer element type, only check
that the stride is one. Ultimately, the actual pointer type here
doesn't matter, because SCEVExpander would insert appropriate
casts if necessary.

Added: 
    llvm/test/Transforms/IndVarSimplify/lftr-opaque-pointers.ll

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index 7001d330fce0b..0027e7db055f7 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -982,6 +982,7 @@ static Value *genLoopLimit(PHINode *IndVar, BasicBlock *ExitingBB,
   assert(isLoopCounter(IndVar, L, SE));
   const SCEVAddRecExpr *AR = cast<SCEVAddRecExpr>(SE->getSCEV(IndVar));
   const SCEV *IVInit = AR->getStart();
+  assert(AR->getStepRecurrence(*SE)->isOne() && "only handles unit stride");
 
   // IVInit may be a pointer while ExitCount is an integer when FindLoopCounter
   // finds a valid pointer IV. Sign extend ExitCount in order to materialize a
@@ -1004,13 +1005,6 @@ static Value *genLoopLimit(PHINode *IndVar, BasicBlock *ExitingBB,
     assert(SE->isLoopInvariant(IVOffset, L) &&
            "Computed iteration count is not loop invariant!");
 
-    // We could handle pointer IVs other than i8*, but we need to compensate for
-    // gep index scaling.
-    assert(SE->getSizeOfExpr(IntegerType::getInt64Ty(IndVar->getContext()),
-                             cast<PointerType>(IndVar->getType())
-                                 ->getElementType())->isOne() &&
-           "unit stride pointer IV must be i8*");
-
     const SCEV *IVLimit = SE->getAddExpr(IVInit, IVOffset);
     BranchInst *BI = cast<BranchInst>(ExitingBB->getTerminator());
     return Rewriter.expandCodeFor(IVLimit, IndVar->getType(), BI);
@@ -1026,7 +1020,6 @@ static Value *genLoopLimit(PHINode *IndVar, BasicBlock *ExitingBB,
     // IVInit integer and ExitCount pointer would only occur if a canonical IV
     // were generated on top of case #2, which is not expected.
 
-    assert(AR->getStepRecurrence(*SE)->isOne() && "only handles unit stride");
     // For unit stride, IVCount = Start + ExitCount with 2's complement
     // overflow.
 

diff  --git a/llvm/test/Transforms/IndVarSimplify/lftr-opaque-pointers.ll b/llvm/test/Transforms/IndVarSimplify/lftr-opaque-pointers.ll
new file mode 100644
index 0000000000000..94e0288e534b1
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/lftr-opaque-pointers.ll
@@ -0,0 +1,42 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -indvars -opaque-pointers < %s | FileCheck %s
+
+target datalayout = "n8:16:32:64"
+
+ at data = common global [240 x i8] zeroinitializer, align 16
+
+; Based on the test from lftr.ll
+define void @test_zext(ptr %a) {
+; CHECK-LABEL: @test_zext(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[P_0:%.*]] = phi ptr [ getelementptr inbounds ([240 x i8], ptr @data, i64 0, i64 0), [[ENTRY:%.*]] ], [ [[T3:%.*]], [[LOOP]] ]
+; CHECK-NEXT:    [[DOT0:%.*]] = phi ptr [ [[A:%.*]], [[ENTRY]] ], [ [[T:%.*]], [[LOOP]] ]
+; CHECK-NEXT:    [[T]] = getelementptr inbounds i8, ptr [[DOT0]], i64 1
+; CHECK-NEXT:    [[T2:%.*]] = load i8, ptr [[DOT0]], align 1
+; CHECK-NEXT:    [[T3]] = getelementptr inbounds i8, ptr [[P_0]], i64 1
+; CHECK-NEXT:    store i8 [[T2]], ptr [[P_0]], align 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne ptr [[P_0]], getelementptr (i8, ptr @data, i64 239)
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %loop
+
+loop:
+  %i.0 = phi i8 [ 0, %entry ], [ %t4, %loop ]
+  %p.0 = phi ptr [ getelementptr inbounds ([240 x i8], [240 x i8]* @data, i64 0, i64 0), %entry ], [ %t3, %loop ]
+  %.0 = phi ptr [ %a, %entry ], [ %t, %loop ]
+  %t = getelementptr inbounds i8, ptr %.0, i64 1
+  %t2 = load i8, ptr %.0, align 1
+  %t3 = getelementptr inbounds i8, ptr %p.0, i64 1
+  store i8 %t2, ptr %p.0, align 1
+  %t4 = add i8 %i.0, 1
+  %t5 = icmp ult i8 %t4, -16
+  br i1 %t5, label %loop, label %exit
+
+exit:
+  ret void
+}


        


More information about the llvm-commits mailing list