From daf32b13d7009e4c53cad71132564f49bac61cb7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 27 Dec 2021 12:31:02 +0100 Subject: [PATCH] [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. --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 9 +---- .../IndVarSimplify/lftr-opaque-pointers.ll | 42 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 llvm/test/Transforms/IndVarSimplify/lftr-opaque-pointers.ll diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index 7001d33..0027e7d 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(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(IndVar->getType()) - ->getElementType())->isOne() && - "unit stride pointer IV must be i8*"); - const SCEV *IVLimit = SE->getAddExpr(IVInit, IVOffset); BranchInst *BI = cast(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 0000000..94e0288 --- /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" + +@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 +} -- 2.7.4