[llvm] r268633 - [LV] Identify more induction PHIs by coercing expressions to AddRecExprs
Richard Smith via llvm-commits
llvm-commits at lists.llvm.org
Thu May 5 15:27:45 PDT 2016
This change broke the modules buildbot:
http://lab.llvm.org:8011/builders/clang-x86_64-linux-selfhost-modules/builds/15321/steps/compile.llvm.stage2/logs/stdio
Looks like you're missing a #include for the type SCEV that you use in
LoopUtils.h. Please fix.
On Thu, May 5, 2016 at 8:20 AM, Silviu Baranga via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: sbaranga
> Date: Thu May 5 10:20:39 2016
> New Revision: 268633
>
> URL: http://llvm.org/viewvc/llvm-project?rev=268633&view=rev
> Log:
> [LV] Identify more induction PHIs by coercing expressions to AddRecExprs
>
> Summary:
> Some PHIs can have expressions that are not AddRecExprs due to the presence
> of sext/zext instructions. In order to prevent the Loop Vectorizer from
> bailing out when encountering these PHIs, we now coerce the SCEV
> expressions to AddRecExprs using SCEV predicates (when possible).
>
> We only do this when the alternative would be to not vectorize.
>
> Reviewers: mzolotukhin, anemet
>
> Subscribers: mssimpso, sanjoy, mzolotukhin, llvm-commits
>
> Differential Revision: http://reviews.llvm.org/D17153
>
> Modified:
> llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h
> llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
> llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
> llvm/trunk/test/Transforms/LoopVectorize/induction.ll
>
> Modified: llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h?rev=268633&r1=268632&r2=268633&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h (original)
> +++ llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h Thu May 5
> 10:20:39 2016
> @@ -30,6 +30,7 @@ class DominatorTree;
> class Loop;
> class LoopInfo;
> class Pass;
> +class PredicatedScalarEvolution;
> class PredIteratorCache;
> class ScalarEvolution;
> class TargetLibraryInfo;
> @@ -287,8 +288,22 @@ public:
> InductionKind getKind() const { return IK; }
> ConstantInt *getStepValue() const { return StepValue; }
>
> + /// Returns true if \p Phi is an induction. If \p Phi is an induction,
> + /// the induction descriptor \p D will contain the data describing this
> + /// induction. If by some other means the caller has a better SCEV
> + /// expression for \p Phi than the one returned by the ScalarEvolution
> + /// analysis, it can be passed through \p Expr.
> static bool isInductionPHI(PHINode *Phi, ScalarEvolution *SE,
> - InductionDescriptor &D);
> + InductionDescriptor &D,
> + const SCEV *Expr = nullptr);
> +
> + /// Returns true if \p Phi is an induction, in the context associated
> with
> + /// the run-time predicate of PSE. If \p Assume is true, this can add
> further
> + /// SCEV predicates to \p PSE in order to prove that \p Phi is an
> induction.
> + /// If \p Phi is an induction, \p D will contain the data describing
> this
> + /// induction.
> + static bool isInductionPHI(PHINode *Phi, PredicatedScalarEvolution &PSE,
> + InductionDescriptor &D, bool Assume = false);
>
> private:
> /// Private constructor - used by \c isInductionPHI.
>
> Modified: llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp?rev=268633&r1=268632&r2=268633&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp Thu May 5 10:20:39 2016
> @@ -698,16 +698,43 @@ Value *InductionDescriptor::transform(IR
> llvm_unreachable("invalid enum");
> }
>
> -bool InductionDescriptor::isInductionPHI(PHINode *Phi, ScalarEvolution
> *SE,
> - InductionDescriptor &D) {
> +bool InductionDescriptor::isInductionPHI(PHINode *Phi,
> + PredicatedScalarEvolution &PSE,
> + InductionDescriptor &D,
> + bool Assume) {
> + Type *PhiTy = Phi->getType();
> + // We only handle integer and pointer inductions variables.
> + if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy())
> + return false;
> +
> + const SCEV *PhiScev = PSE.getSCEV(Phi);
> + const auto *AR = dyn_cast<SCEVAddRecExpr>(PhiScev);
> +
> + // We need this expression to be an AddRecExpr.
> + if (Assume && !AR)
> + AR = PSE.getAsAddRec(Phi);
> +
> + if (!AR) {
> + DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n");
> + return false;
> + }
> +
> + return isInductionPHI(Phi, PSE.getSE(), D, AR);
> +}
> +
> +bool InductionDescriptor::isInductionPHI(PHINode *Phi,
> + ScalarEvolution *SE,
> + InductionDescriptor &D,
> + const SCEV *Expr) {
> Type *PhiTy = Phi->getType();
> // We only handle integer and pointer inductions variables.
> if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy())
> return false;
>
> // Check that the PHI is consecutive.
> - const SCEV *PhiScev = SE->getSCEV(Phi);
> + const SCEV *PhiScev = Expr ? Expr : SE->getSCEV(Phi);
> const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PhiScev);
> +
> if (!AR) {
> DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n");
> return false;
>
> Modified: llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp?rev=268633&r1=268632&r2=268633&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp (original)
> +++ llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp Thu May 5
> 10:20:39 2016
> @@ -4673,13 +4673,6 @@ bool LoopVectorizationLegality::canVecto
> return false;
> }
>
> - InductionDescriptor ID;
> - if (InductionDescriptor::isInductionPHI(Phi, PSE.getSE(), ID)) {
> - if (!addInductionPhi(Phi, ID))
> - return false;
> - continue;
> - }
> -
> RecurrenceDescriptor RedDes;
> if (RecurrenceDescriptor::isReductionPHI(Phi, TheLoop, RedDes)) {
> if (RedDes.hasUnsafeAlgebra())
> @@ -4689,11 +4682,26 @@ bool LoopVectorizationLegality::canVecto
> continue;
> }
>
> + InductionDescriptor ID;
> + if (InductionDescriptor::isInductionPHI(Phi, PSE, ID)) {
> + if (!addInductionPhi(Phi, ID))
> + return false;
> + continue;
> + }
> +
> if (RecurrenceDescriptor::isFirstOrderRecurrence(Phi, TheLoop,
> DT)) {
> FirstOrderRecurrences.insert(Phi);
> continue;
> }
>
> + // As a last resort, coerce the PHI to a AddRec expression
> + // and re-try classifying it a an induction PHI.
> + if (InductionDescriptor::isInductionPHI(Phi, PSE, ID, true)) {
> + if (!addInductionPhi(Phi, ID))
> + return false;
> + continue;
> + }
> +
> emitAnalysis(VectorizationReport(&*it)
> << "value that could not be identified as "
> "reduction is used outside the loop");
>
> Modified: llvm/trunk/test/Transforms/LoopVectorize/induction.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopVectorize/induction.ll?rev=268633&r1=268632&r2=268633&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Transforms/LoopVectorize/induction.ll (original)
> +++ llvm/trunk/test/Transforms/LoopVectorize/induction.ll Thu May 5
> 10:20:39 2016
> @@ -166,3 +166,78 @@ cond.end.i:
> loopexit:
> ret i32 %and.i
> }
> +
> +; The SCEV expression of %sphi is (zext i8 {%t,+,1}<%loop> to i32)
> +; In order to recognize %sphi as an induction PHI and vectorize this loop,
> +; we need to convert the SCEV expression into an AddRecExpr.
> +; The expression gets converted to {zext i8 %t to i32,+,1}.
> +
> +; CHECK-LABEL: wrappingindvars1
> +; CHECK-LABEL: vector.scevcheck
> +; CHECK-LABEL: vector.body
> +; CHECK: add <2 x i32> {{%[^ ]*}}, <i32 0, i32 1>
> +define void @wrappingindvars1(i8 %t, i32 %len, i32 *%A) {
> + entry:
> + %st = zext i8 %t to i16
> + %ext = zext i8 %t to i32
> + %ecmp = icmp ult i16 %st, 42
> + br i1 %ecmp, label %loop, label %exit
> +
> + loop:
> +
> + %idx = phi i8 [ %t, %entry ], [ %idx.inc, %loop ]
> + %idx.b = phi i32 [ 0, %entry ], [ %idx.b.inc, %loop ]
> + %sphi = phi i32 [ %ext, %entry ], [%idx.inc.ext, %loop]
> +
> + %ptr = getelementptr inbounds i32, i32* %A, i8 %idx
> + store i32 %sphi, i32* %ptr
> +
> + %idx.inc = add i8 %idx, 1
> + %idx.inc.ext = zext i8 %idx.inc to i32
> + %idx.b.inc = add nuw nsw i32 %idx.b, 1
> +
> + %c = icmp ult i32 %idx.b, %len
> + br i1 %c, label %loop, label %exit
> +
> + exit:
> + ret void
> +}
> +
> +; The SCEV expression of %sphi is (4 * (zext i8 {%t,+,1}<%loop> to i32))
> +; In order to recognize %sphi as an induction PHI and vectorize this loop,
> +; we need to convert the SCEV expression into an AddRecExpr.
> +; The expression gets converted to ({4 * (zext %t to i32),+,4}).
> +; CHECK-LABEL: wrappingindvars2
> +; CHECK-LABEL: vector.scevcheck
> +; CHECK-LABEL: vector.body
> +; CHECK: add <2 x i32> {{%[^ ]*}}, <i32 0, i32 4>
> +define void @wrappingindvars2(i8 %t, i32 %len, i32 *%A) {
> +
> +entry:
> + %st = zext i8 %t to i16
> + %ext = zext i8 %t to i32
> + %ext.mul = mul i32 %ext, 4
> +
> + %ecmp = icmp ult i16 %st, 42
> + br i1 %ecmp, label %loop, label %exit
> +
> + loop:
> +
> + %idx = phi i8 [ %t, %entry ], [ %idx.inc, %loop ]
> + %sphi = phi i32 [ %ext.mul, %entry ], [%mul, %loop]
> + %idx.b = phi i32 [ 0, %entry ], [ %idx.b.inc, %loop ]
> +
> + %ptr = getelementptr inbounds i32, i32* %A, i8 %idx
> + store i32 %sphi, i32* %ptr
> +
> + %idx.inc = add i8 %idx, 1
> + %idx.inc.ext = zext i8 %idx.inc to i32
> + %mul = mul i32 %idx.inc.ext, 4
> + %idx.b.inc = add nuw nsw i32 %idx.b, 1
> +
> + %c = icmp ult i32 %idx.b, %len
> + br i1 %c, label %loop, label %exit
> +
> + exit:
> + ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160505/1f56ea76/attachment.html>
More information about the llvm-commits
mailing list