aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/CodeGenPrepare.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp20
1 files changed, 14 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 04fa74a..baf674c 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -6988,7 +6988,8 @@ bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
Value *Cond = SI->getCondition();
Type *OldType = Cond->getType();
LLVMContext &Context = Cond->getContext();
- MVT RegType = TLI->getRegisterType(Context, TLI->getValueType(*DL, OldType));
+ EVT OldVT = TLI->getValueType(*DL, OldType);
+ MVT RegType = TLI->getRegisterType(Context, OldVT);
unsigned RegWidth = RegType.getSizeInBits();
if (RegWidth <= cast<IntegerType>(OldType)->getBitWidth())
@@ -7002,14 +7003,21 @@ bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
// where N is the number of cases in the switch.
auto *NewType = Type::getIntNTy(Context, RegWidth);
- // Zero-extend the switch condition and case constants unless the switch
- // condition is a function argument that is already being sign-extended.
- // In that case, we can avoid an unnecessary mask/extension by sign-extending
- // everything instead.
+ // Extend the switch condition and case constants using the target preferred
+ // extend unless the switch condition is a function argument with an extend
+ // attribute. In that case, we can avoid an unnecessary mask/extension by
+ // matching the argument extension instead.
Instruction::CastOps ExtType = Instruction::ZExt;
- if (auto *Arg = dyn_cast<Argument>(Cond))
+ // Some targets prefer SExt over ZExt.
+ if (TLI->isSExtCheaperThanZExt(OldVT, RegType))
+ ExtType = Instruction::SExt;
+
+ if (auto *Arg = dyn_cast<Argument>(Cond)) {
if (Arg->hasSExtAttr())
ExtType = Instruction::SExt;
+ if (Arg->hasZExtAttr())
+ ExtType = Instruction::ZExt;
+ }
auto *ExtInst = CastInst::Create(ExtType, Cond, NewType);
ExtInst->insertBefore(SI);