diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2014-12-19 17:12:35 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2014-12-19 17:12:35 +0000 |
commit | f6cf8ad4e5ad260e12153156fb7e90b8c29604ea (patch) | |
tree | cf4ac7099205bbd3f4e300fd09c95cd96e3457ab /llvm/lib/Transforms | |
parent | b811030b47908fcf083be6ef6a4ad90b3e5086ca (diff) | |
download | bcm5719-llvm-f6cf8ad4e5ad260e12153156fb7e90b8c29604ea.tar.gz bcm5719-llvm-f6cf8ad4e5ad260e12153156fb7e90b8c29604ea.zip |
Reapply: [InstCombine] Fix visitSwitchInst to use right operand types for sub cstexpr
The visitSwitchInst generates SUB constant expressions to recompute the
switch condition. When truncating the condition to a smaller type, SUB
expressions should use the previous type (before trunc) for both
operands. Also, fix code to also return the modified switch when only
the truncation is performed.
This fixes an assertion crash.
Differential Revision: http://reviews.llvm.org/D6644
rdar://problem/19191835
llvm-svn: 224588
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 5eee15f6489..898e5708ff1 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2095,8 +2095,10 @@ Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) { // 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. + bool TruncCond = false; if (DL && BitWidth > NewWidth && NewWidth >= DL->getLargestLegalIntTypeSize()) { + TruncCond = true; IntegerType *Ty = IntegerType::get(SI.getContext(), NewWidth); Builder->SetInsertPoint(&SI); Value *NewCond = Builder->CreateTrunc(SI.getCondition(), Ty, "trunc"); @@ -2115,8 +2117,12 @@ Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) { for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) { ConstantInt* CaseVal = i.getCaseValue(); - Constant* NewCaseVal = ConstantExpr::getSub(cast<Constant>(CaseVal), - AddRHS); + Constant *LHS = CaseVal; + if (TruncCond) + LHS = LeadingKnownZeros + ? ConstantExpr::getZExt(CaseVal, Cond->getType()) + : ConstantExpr::getSExt(CaseVal, Cond->getType()); + Constant* NewCaseVal = ConstantExpr::getSub(LHS, AddRHS); assert(isa<ConstantInt>(NewCaseVal) && "Result of expression should be constant"); i.setValue(cast<ConstantInt>(NewCaseVal)); @@ -2126,7 +2132,8 @@ Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) { return &SI; } } - return nullptr; + + return TruncCond ? &SI : nullptr; } Instruction *InstCombiner::visitExtractValueInst(ExtractValueInst &EV) { |