diff options
author | Chris Lattner <sabre@nondot.org> | 2004-03-30 19:37:13 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-03-30 19:37:13 +0000 |
commit | c32b30a42999e7f67b87125e0301330608ec1287 (patch) | |
tree | 3d85af6945df0aef6e5ef0114117f381811ec0a2 | |
parent | 6d0996866c3beab23a4b0036fc13c2ed057a4570 (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.cpp | 36 |
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; } |