aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-03-30 19:37:13 +0000
committerChris Lattner <sabre@nondot.org>2004-03-30 19:37:13 +0000
commitc32b30a42999e7f67b87125e0301330608ec1287 (patch)
tree3d85af6945df0aef6e5ef0114117f381811ec0a2
parent6d0996866c3beab23a4b0036fc13c2ed057a4570 (diff)
Implement select.ll:test[3-6]
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12544 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp36
1 files changed, 32 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 9b91705110..13c6b26db1 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -1994,14 +1994,42 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
}
Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
- if (ConstantBool *C = dyn_cast<ConstantBool>(SI.getCondition()))
+ Value *CondVal = SI.getCondition();
+ Value *TrueVal = SI.getTrueValue();
+ Value *FalseVal = SI.getFalseValue();
+
+ // select true, X, Y -> X
+ // select false, X, Y -> Y
+ if (ConstantBool *C = dyn_cast<ConstantBool>(CondVal))
if (C == ConstantBool::True)
- return ReplaceInstUsesWith(SI, SI.getTrueValue());
+ return ReplaceInstUsesWith(SI, TrueVal);
else {
assert(C == ConstantBool::False);
- return ReplaceInstUsesWith(SI, SI.getFalseValue());
+ return ReplaceInstUsesWith(SI, FalseVal);
+ }
+
+ // select C, X, X -> X
+ if (TrueVal == FalseVal)
+ return ReplaceInstUsesWith(SI, TrueVal);
+
+ // Selecting between two constants?
+ if (Constant *TrueValC = dyn_cast<Constant>(TrueVal))
+ if (Constant *FalseValC = dyn_cast<Constant>(FalseVal)) {
+ if (SI.getType() == Type::BoolTy &&
+ isa<ConstantBool>(TrueValC) && isa<ConstantBool>(FalseValC)) {
+ // select C, true, false -> C
+ if (TrueValC == ConstantBool::True)
+ return ReplaceInstUsesWith(SI, CondVal);
+ // select C, false, true -> !C
+ return BinaryOperator::createNot(CondVal);
+ }
+
+ // If the true constant is a 1 and the false is a zero, turn this into a
+ // cast from bool.
+ if (FalseValC->isNullValue() && isa<ConstantInt>(TrueValC) &&
+ cast<ConstantInt>(TrueValC)->getRawValue() == 1)
+ return new CastInst(CondVal, SI.getType());
}
- // Other transformations are possible!
return 0;
}