diff options
| author | Akira Hatanaka <ahatanaka@apple.com> | 2014-10-15 19:05:50 +0000 |
|---|---|---|
| committer | Akira Hatanaka <ahatanaka@apple.com> | 2014-10-15 19:05:50 +0000 |
| commit | 5bb9346a45573a10421e376808c0d3b59a3b0ab5 (patch) | |
| tree | ab7f5f165a73b228fcc2f8aaddef35291bea3a10 /llvm/lib/Transforms/InstCombine | |
| parent | f82c987a5cc1ecce7b5e3e11fff974e278e89c81 (diff) | |
| download | bcm5719-llvm-5bb9346a45573a10421e376808c0d3b59a3b0ab5.tar.gz bcm5719-llvm-5bb9346a45573a10421e376808c0d3b59a3b0ab5.zip | |
InstCombine: Narrow switch instructions using known bits.
Truncate the operands of a switch instruction to a narrower type if the upper
bits are known to be all ones or zeros.
rdar://problem/17720004
llvm-svn: 219832
Diffstat (limited to 'llvm/lib/Transforms/InstCombine')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index ac0c01e3c7b..e158c11b1fd 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2075,6 +2075,37 @@ Instruction *InstCombiner::visitBranchInst(BranchInst &BI) { Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) { Value *Cond = SI.getCondition(); + unsigned BitWidth = cast<IntegerType>(Cond->getType())->getBitWidth(); + APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); + computeKnownBits(Cond, KnownZero, KnownOne); + unsigned LeadingKnownZeros = KnownZero.countLeadingOnes(); + unsigned LeadingKnownOnes = KnownOne.countLeadingOnes(); + + // Compute the number of leading bits we can ignore. + for (auto &C : SI.cases()) { + LeadingKnownZeros = std::min( + LeadingKnownZeros, C.getCaseValue()->getValue().countLeadingZeros()); + LeadingKnownOnes = std::min( + LeadingKnownOnes, C.getCaseValue()->getValue().countLeadingOnes()); + } + + unsigned NewWidth = BitWidth - std::max(LeadingKnownZeros, LeadingKnownOnes); + + // Truncate the condition operand if the new type is equal to or larger than + // the largest legal integer type. We need to be conservative here since + // x86 generates redundant zero-extenstion instructions if the operand is + // truncated to i8 or i16. + if (BitWidth > NewWidth && NewWidth >= DL->getLargestLegalIntTypeSize()) { + IntegerType *Ty = IntegerType::get(SI.getContext(), NewWidth); + Builder->SetInsertPoint(&SI); + Value *NewCond = Builder->CreateTrunc(SI.getCondition(), Ty, "trunc"); + SI.setCondition(NewCond); + + for (auto &C : SI.cases()) + static_cast<SwitchInst::CaseIt *>(&C)->setValue( + ConstantInt::get(Ty, C.getCaseValue()->getValue().getZExtValue())); + } + if (Instruction *I = dyn_cast<Instruction>(Cond)) { if (I->getOpcode() == Instruction::Add) if (ConstantInt *AddRHS = dyn_cast<ConstantInt>(I->getOperand(1))) { |

