[PATCH] D50778: [LV] Vectorize loops where non-phi instructions used outside loop
Ayal Zaks via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 19 01:02:50 PDT 2018
Ayal added inline comments.
================
Comment at: lib/Transforms/Vectorize/LoopVectorize.cpp:3727
+ if (isa<Instruction>(IncomingValue))
+ LastLane = Cost->isUniformAfterVectorization(
+ cast<Instruction>(IncomingValue), VF)
----------------
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.
Repository:
rL LLVM
https://reviews.llvm.org/D50778
More information about the llvm-commits
mailing list