[PATCH] D50778: [LV] Vectorize loops where non-phi instructions used outside loop
Anna Thomas via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 20 07:26:13 PDT 2018
anna added inline comments.
================
Comment at: lib/Transforms/Vectorize/LoopVectorize.cpp:3727
+ if (isa<Instruction>(IncomingValue))
+ LastLane = Cost->isUniformAfterVectorization(
+ cast<Instruction>(IncomingValue), VF)
----------------
Ayal wrote:
> anna wrote:
> > I have trouble getting a test case that exercises this path. Tried couple of different uniform instructions (GEPs with constant operands). In all cases, we were vectorizing these and then extracting the VF -1 th element.
> > Any ideas on what will be a good test case for this? Thanks.
> >
> Yes, the GEPs themselves are immune, because they are checked by `UsersAreMemAccesses()` to see if all their users are loads/stores, so if they have a loop-closed phi as a user they will not be regarded as uniform. The following should work:
>
> ```
> ; RUN: opt < %s -loop-vectorize -S
>
> target datalayout = "E-m:e-p:32:32-i64:32-f64:32:64-a:0:32-n32-S128"
>
> @tab = common global [32 x i8] zeroinitializer, align 1
>
> define i32 @uniform_live_out() {
> entry:
> br label %for.body
>
> for.body: ; preds = %for.body, %entry
> %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
> %i.09 = add i32 %i.08, 7
> %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.09
> %0 = load i8, i8* %arrayidx, align 1
> %bump = add i8 %0, 1
> store i8 %bump, i8* %arrayidx, align 1
> %inc = add nsw i32 %i.08, 1
> %exitcond = icmp eq i32 %i.08, 20000
> br i1 %exitcond, label %for.end, label %for.body
>
> for.end: ; preds = %for.body
> %lcssa = phi i32 [%i.09, %for.body]
> %arrayidx.out = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %lcssa
> store i8 42, i8* %arrayidx.out, align 1
> ret i32 0
> }
> ```
>
> Sorry about this. It's really due to the way uniform values are stored. Would be better to have an API for obtaining the scalar value corresponding to the last VF-1 lane, regardless of how it's stored, instead of having users check if VF-1 or 0 should be passed.
>
> But wait, this test shows that `LoopVectorizationCostModel::collectLoopUniforms()` must be updated too, to refrain from recognizing instructions with live-outs as being uniform; except for instructions that are inherently uniform/invariant (i.e., all VF values will be the same), and induction variables with their bumps - which are pre-computed rather than have their last-iteration value taken.
thanks Ayal. I've made the change in `collectLoopUniforms` to avoid incorrectly recognizing instructions with outside uses as uniform (unless those uses themselves were uniform). So, `%i.09 = add i32 %i.08, 7` is no longer scalarized and we extract the VF-1th element. Without that change, we were recognizing i.09 as uniform.
I will add this test case and find another one where the live-out is of a really uniform instruction.
Repository:
rL LLVM
https://reviews.llvm.org/D50778
More information about the llvm-commits
mailing list