mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-20 08:54:08 +00:00
Vectorizer: optimize the generation of selects. If the condition is uniform, generate a scalar-cond select (i1 as selector).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166409 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e0fa403e23
commit
565048e78a
@ -725,12 +725,22 @@ SingleBlockLoopVectorizer::vectorizeLoop(LoopVectorizationLegality *Legal) {
|
||||
}
|
||||
case Instruction::Select: {
|
||||
// Widen selects.
|
||||
// TODO: If the selector is loop invariant we can issue a select
|
||||
// instruction with a scalar condition.
|
||||
Value *A = getVectorValue(Inst->getOperand(0));
|
||||
Value *B = getVectorValue(Inst->getOperand(1));
|
||||
Value *C = getVectorValue(Inst->getOperand(2));
|
||||
WidenMap[Inst] = Builder.CreateSelect(A, B, C);
|
||||
// If the selector is loop invariant we can create a select
|
||||
// instruction with a scalar condition. Otherwise, use vector-select.
|
||||
Value *Cond = Inst->getOperand(0);
|
||||
bool InvariantCond = SE->isLoopInvariant(SE->getSCEV(Cond), Orig);
|
||||
|
||||
// The condition can be loop invariant but still defined inside the
|
||||
// loop. This means that we can't just use the original 'cond' value.
|
||||
// We have to take the 'vectorized' value and pick the first lane.
|
||||
// Instcombine will make this a no-op.
|
||||
Cond = getVectorValue(Cond);
|
||||
if (InvariantCond)
|
||||
Cond = Builder.CreateExtractElement(Cond, Builder.getInt32(0));
|
||||
|
||||
Value *Op0 = getVectorValue(Inst->getOperand(1));
|
||||
Value *Op1 = getVectorValue(Inst->getOperand(2));
|
||||
WidenMap[Inst] = Builder.CreateSelect(Cond, Op0, Op1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
37
test/Transforms/LoopVectorize/scalar-select.ll
Normal file
37
test/Transforms/LoopVectorize/scalar-select.ll
Normal file
@ -0,0 +1,37 @@
|
||||
; RUN: opt < %s -loop-vectorize -dce -instcombine -licm -S | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-macosx10.8.0"
|
||||
|
||||
@a = common global [2048 x i32] zeroinitializer, align 16
|
||||
@b = common global [2048 x i32] zeroinitializer, align 16
|
||||
@c = common global [2048 x i32] zeroinitializer, align 16
|
||||
|
||||
;CHECK: @example1
|
||||
;CHECK: load <4 x i32>
|
||||
; make sure that we have a scalar condition and a vector operand.
|
||||
;CHECK: select i1 %cond, <4 x i32>
|
||||
;CHECK: store <4 x i32>
|
||||
;CHECK: ret void
|
||||
define void @example1(i1 %cond) nounwind uwtable ssp {
|
||||
br label %1
|
||||
|
||||
; <label>:1 ; preds = %1, %0
|
||||
%indvars.iv = phi i64 [ 0, %0 ], [ %indvars.iv.next, %1 ]
|
||||
%2 = getelementptr inbounds [2048 x i32]* @b, i64 0, i64 %indvars.iv
|
||||
%3 = load i32* %2, align 4
|
||||
%4 = getelementptr inbounds [2048 x i32]* @c, i64 0, i64 %indvars.iv
|
||||
%5 = load i32* %4, align 4
|
||||
%6 = add nsw i32 %5, %3
|
||||
%7 = getelementptr inbounds [2048 x i32]* @a, i64 0, i64 %indvars.iv
|
||||
%sel = select i1 %cond, i32 %6, i32 zeroinitializer
|
||||
store i32 %sel, i32* %7, align 4
|
||||
%indvars.iv.next = add i64 %indvars.iv, 1
|
||||
%lftr.wideiv = trunc i64 %indvars.iv.next to i32
|
||||
%exitcond = icmp eq i32 %lftr.wideiv, 256
|
||||
br i1 %exitcond, label %8, label %1
|
||||
|
||||
; <label>:8 ; preds = %1
|
||||
ret void
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user