aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-07-06 22:23:01 +0000
committerSanjay Patel <spatel@rotateright.com>2016-07-06 22:23:01 +0000
commit65a51c25c12ad4ef0ae4c2855a4d5b1f97e482ad (patch)
tree21b3fd271f3dba20b3b64f005efa47d280325370 /llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
parentc1c6823976173c16c0c058879d0cf4617f985d88 (diff)
downloadllvm-65a51c25c12ad4ef0ae4c2855a4d5b1f97e482ad.zip
llvm-65a51c25c12ad4ef0ae4c2855a4d5b1f97e482ad.tar.gz
llvm-65a51c25c12ad4ef0ae4c2855a4d5b1f97e482ad.tar.bz2
[InstCombine] enhance (select X, C1, C2 --> ext X) to handle vectors
By replacing dyn_cast of ConstantInt with m_Zero/m_One/m_AllOnes, we allow these transforms for splat vectors. Differential Revision: http://reviews.llvm.org/D21899 llvm-svn: 274696
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp50
1 files changed, 28 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index d89691e5..db4ef6e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -954,32 +954,38 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
return BinaryOperator::CreateOr(TrueVal, FalseVal);
}
- // Selecting between two integer constants?
- if (ConstantInt *TrueValC = dyn_cast<ConstantInt>(TrueVal))
- if (ConstantInt *FalseValC = dyn_cast<ConstantInt>(FalseVal)) {
- // select C, 1, 0 -> zext C to int
- if (FalseValC->isZero() && TrueValC->getValue() == 1)
- return new ZExtInst(CondVal, SI.getType());
-
- // select C, -1, 0 -> sext C to int
- if (FalseValC->isZero() && TrueValC->isAllOnesValue())
- return new SExtInst(CondVal, SI.getType());
-
- // select C, 0, 1 -> zext !C to int
- if (TrueValC->isZero() && FalseValC->getValue() == 1) {
- Value *NotCond = Builder->CreateNot(CondVal, "not."+CondVal->getName());
- return new ZExtInst(NotCond, SI.getType());
- }
+ // Selecting between two integer or vector splat integer constants?
+ //
+ // Note that we don't handle a scalar select of vectors:
+ // select i1 %c, <2 x i8> <1, 1>, <2 x i8> <0, 0>
+ // because that may need 3 instructions to splat the condition value:
+ // extend, insertelement, shufflevector.
+ if (CondVal->getType()->isVectorTy() == SI.getType()->isVectorTy()) {
+ // select C, 1, 0 -> zext C to int
+ if (match(TrueVal, m_One()) && match(FalseVal, m_Zero()))
+ return new ZExtInst(CondVal, SI.getType());
+
+ // select C, -1, 0 -> sext C to int
+ if (match(TrueVal, m_AllOnes()) && match(FalseVal, m_Zero()))
+ return new SExtInst(CondVal, SI.getType());
+
+ // select C, 0, 1 -> zext !C to int
+ if (match(TrueVal, m_Zero()) && match(FalseVal, m_One())) {
+ Value *NotCond = Builder->CreateNot(CondVal, "not." + CondVal->getName());
+ return new ZExtInst(NotCond, SI.getType());
+ }
- // select C, 0, -1 -> sext !C to int
- if (TrueValC->isZero() && FalseValC->isAllOnesValue()) {
- Value *NotCond = Builder->CreateNot(CondVal, "not."+CondVal->getName());
- return new SExtInst(NotCond, SI.getType());
- }
+ // select C, 0, -1 -> sext !C to int
+ if (match(TrueVal, m_Zero()) && match(FalseVal, m_AllOnes())) {
+ Value *NotCond = Builder->CreateNot(CondVal, "not." + CondVal->getName());
+ return new SExtInst(NotCond, SI.getType());
+ }
+ }
+ if (ConstantInt *TrueValC = dyn_cast<ConstantInt>(TrueVal))
+ if (ConstantInt *FalseValC = dyn_cast<ConstantInt>(FalseVal))
if (Value *V = foldSelectICmpAnd(SI, TrueValC, FalseValC, Builder))
return replaceInstUsesWith(SI, V);
- }
// See if we are selecting two values based on a comparison of the two values.
if (FCmpInst *FCI = dyn_cast<FCmpInst>(CondVal)) {