diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2010-12-22 23:12:15 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2010-12-22 23:12:15 +0000 |
commit | 4ac19470dc26decba85f5bf4dd7e6edb54d77152 (patch) | |
tree | 6400c2c3d7b946d8c8883d39534f808d27d5c9f4 | |
parent | e915ff30cd15f71ed9bb87ba0bf6c7d8b5a84747 (diff) |
InstCombine: creating selects from -1 and 0 is fine, they combine into a sext from i1.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122453 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineSelect.cpp | 9 | ||||
-rw-r--r-- | test/Transforms/InstCombine/select.ll | 12 |
2 files changed, 18 insertions, 3 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineSelect.cpp b/lib/Transforms/InstCombine/InstCombineSelect.cpp index 82ce31128c..c15378bc74 100644 --- a/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -195,7 +195,10 @@ static bool isSelect01(Constant *C1, Constant *C2) { ConstantInt *C2I = dyn_cast<ConstantInt>(C2); if (!C2I) return false; - return (C1I->isZero() || C1I->isOne()) && (C2I->isZero() || C2I->isOne()); + if (!C1I->isZero() && !C2I->isZero()) // One side must be zero. + return false; + return C1I->isOne() || C1I->isAllOnesValue() || + C2I->isOne() || C2I->isAllOnesValue(); } /// FoldSelectIntoOp - Try fold the select into one of the operands to @@ -219,7 +222,7 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal, Constant *C = GetSelectFoldableConstant(TVI); Value *OOp = TVI->getOperand(2-OpToFold); // Avoid creating select between 2 constants unless it's selecting - // between 0 and 1. + // between 0, 1 and -1. if (!isa<Constant>(OOp) || isSelect01(C, cast<Constant>(OOp))) { Instruction *NewSel = SelectInst::Create(SI.getCondition(), OOp, C); InsertNewInstBefore(NewSel, SI); @@ -248,7 +251,7 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal, Constant *C = GetSelectFoldableConstant(FVI); Value *OOp = FVI->getOperand(2-OpToFold); // Avoid creating select between 2 constants unless it's selecting - // between 0 and 1. + // between 0, 1 and -1. if (!isa<Constant>(OOp) || isSelect01(C, cast<Constant>(OOp))) { Instruction *NewSel = SelectInst::Create(SI.getCondition(), C, OOp); InsertNewInstBefore(NewSel, SI); diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll index 772299c29f..fd3937d3da 100644 --- a/test/Transforms/InstCombine/select.ll +++ b/test/Transforms/InstCombine/select.ll @@ -584,3 +584,15 @@ define i32 @test41(i1 %cond, i32 %x, i32 %y) { ; CHECK-NEXT: and i32 %x, %y ; CHECK-NEXT: ret i32 } + +define i32 @test42(i32 %x, i32 %y) { + %b = add i32 %y, -1 + %cond = icmp eq i32 %x, 0 + %c = select i1 %cond, i32 %b, i32 %y + ret i32 %c +; CHECK: @test42 +; CHECK-NEXT: %cond = icmp eq i32 %x, 0 +; CHECK-NEXT: %b = sext i1 %cond to i32 +; CHECK-NEXT: %c = add i32 %b, %y +; CHECK-NEXT: ret i32 %c +} |