diff options
author | Craig Topper <craig.topper@sifive.com> | 2021-06-23 15:38:03 -0700 |
---|---|---|
committer | Craig Topper <craig.topper@sifive.com> | 2021-06-23 15:38:11 -0700 |
commit | 91319534ba00910fc8027dc4be3eeea4c321621d (patch) | |
tree | 203b52775d0da35bb757ec22e43e78b514fdbdb3 /llvm/lib/CodeGen/CodeGenPrepare.cpp | |
parent | f09ec01f1fbbf8920db65a77791d511bf4d03d3c (diff) | |
download | llvm-91319534ba00910fc8027dc4be3eeea4c321621d.zip llvm-91319534ba00910fc8027dc4be3eeea4c321621d.tar.gz llvm-91319534ba00910fc8027dc4be3eeea4c321621d.tar.bz2 |
[CGP][RISCV] Teach CodeGenPrepare::optimizeSwitchInst to honor isSExtCheaperThanZExt.
This optimization pre-promotes the input and constants for a
switch instruction to a legal type so that all the generated compares
share the same extend. Since RISCV prefers sext for i32 to i64
extends, we should honor that to use sext.w instead of a pair
of shifts.
Reviewed By: jrtc27
Differential Revision: https://reviews.llvm.org/D104612
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 20 |
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); |