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:
Nadav Rotem
2012-10-22 04:38:00 +00:00
parent e0fa403e23
commit 565048e78a
2 changed files with 53 additions and 6 deletions

View File

@ -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;
}