[llvm] 9131953 - [CGP][RISCV] Teach CodeGenPrepare::optimizeSwitchInst to honor isSExtCheaperThanZExt.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 23 15:43:21 PDT 2021


Author: Craig Topper
Date: 2021-06-23T15:38:11-07:00
New Revision: 91319534ba00910fc8027dc4be3eeea4c321621d

URL: https://github.com/llvm/llvm-project/commit/91319534ba00910fc8027dc4be3eeea4c321621d
DIFF: https://github.com/llvm/llvm-project/commit/91319534ba00910fc8027dc4be3eeea4c321621d.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/CodeGen/CodeGenPrepare.cpp
    llvm/test/CodeGen/RISCV/jumptable.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 04fa74ab5285..baf674cea565 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);

diff  --git a/llvm/test/CodeGen/RISCV/jumptable.ll b/llvm/test/CodeGen/RISCV/jumptable.ll
index 0eebc698759d..f3c65462cd6b 100644
--- a/llvm/test/CodeGen/RISCV/jumptable.ll
+++ b/llvm/test/CodeGen/RISCV/jumptable.ll
@@ -75,8 +75,7 @@ define void @below_threshold(i32 %in, i32* %out) nounwind {
 ;
 ; RV64I-SMALL-LABEL: below_threshold:
 ; RV64I-SMALL:       # %bb.0: # %entry
-; RV64I-SMALL-NEXT:    slli a0, a0, 32
-; RV64I-SMALL-NEXT:    srli a0, a0, 32
+; RV64I-SMALL-NEXT:    sext.w a0, a0
 ; RV64I-SMALL-NEXT:    addi a2, zero, 2
 ; RV64I-SMALL-NEXT:    blt a2, a0, .LBB0_4
 ; RV64I-SMALL-NEXT:  # %bb.1: # %entry
@@ -109,8 +108,7 @@ define void @below_threshold(i32 %in, i32* %out) nounwind {
 ;
 ; RV64I-MEDIUM-LABEL: below_threshold:
 ; RV64I-MEDIUM:       # %bb.0: # %entry
-; RV64I-MEDIUM-NEXT:    slli a0, a0, 32
-; RV64I-MEDIUM-NEXT:    srli a0, a0, 32
+; RV64I-MEDIUM-NEXT:    sext.w a0, a0
 ; RV64I-MEDIUM-NEXT:    addi a2, zero, 2
 ; RV64I-MEDIUM-NEXT:    blt a2, a0, .LBB0_4
 ; RV64I-MEDIUM-NEXT:  # %bb.1: # %entry
@@ -236,8 +234,7 @@ define void @above_threshold(i32 %in, i32* %out) nounwind {
 ;
 ; RV64I-SMALL-LABEL: above_threshold:
 ; RV64I-SMALL:       # %bb.0: # %entry
-; RV64I-SMALL-NEXT:    slli a0, a0, 32
-; RV64I-SMALL-NEXT:    srli a0, a0, 32
+; RV64I-SMALL-NEXT:    sext.w a0, a0
 ; RV64I-SMALL-NEXT:    addi a0, a0, -1
 ; RV64I-SMALL-NEXT:    addi a2, zero, 5
 ; RV64I-SMALL-NEXT:    bltu a2, a0, .LBB1_9
@@ -272,8 +269,7 @@ define void @above_threshold(i32 %in, i32* %out) nounwind {
 ;
 ; RV64I-MEDIUM-LABEL: above_threshold:
 ; RV64I-MEDIUM:       # %bb.0: # %entry
-; RV64I-MEDIUM-NEXT:    slli a0, a0, 32
-; RV64I-MEDIUM-NEXT:    srli a0, a0, 32
+; RV64I-MEDIUM-NEXT:    sext.w a0, a0
 ; RV64I-MEDIUM-NEXT:    addi a0, a0, -1
 ; RV64I-MEDIUM-NEXT:    addi a2, zero, 5
 ; RV64I-MEDIUM-NEXT:    bltu a2, a0, .LBB1_9


        


More information about the llvm-commits mailing list