[llvm] 992bee0 - [RISCV] Teach RISCVSExtWRemoval to remove sext.w whose upper bits aren't demanded.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 15 11:01:43 PST 2022


Author: Craig Topper
Date: 2022-12-15T11:01:20-08:00
New Revision: 992bee045b7586774ffd539bb46d9a1e22896f60

URL: https://github.com/llvm/llvm-project/commit/992bee045b7586774ffd539bb46d9a1e22896f60
DIFF: https://github.com/llvm/llvm-project/commit/992bee045b7586774ffd539bb46d9a1e22896f60.diff

LOG: [RISCV] Teach RISCVSExtWRemoval to remove sext.w whose upper bits aren't demanded.

SelectionDAG aggressively creates sext_inreg operations after
promoting an i32 add. If the add is later matched to a sh1add,
sh2add or sh3add, a sext.w from the sext_inreg will get left behind.
In many cases we can prove this sext.w is unnecessary by checking
if its upper bits are ever used.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp
    llvm/test/CodeGen/RISCV/sextw-removal.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp b/llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp
index 113a493a998f..73b9d67f4cc2 100644
--- a/llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp
@@ -6,7 +6,9 @@
 //
 //===---------------------------------------------------------------------===//
 //
-// This pass removes unneeded sext.w instructions at the MI level.
+// This pass removes unneeded sext.w instructions at the MI level. Either
+// because the sign extended bits aren't consumed or because the input was
+// already sign extended by an earlier instruction.
 //
 //===---------------------------------------------------------------------===//
 
@@ -479,9 +481,10 @@ bool RISCVSExtWRemoval::runOnMachineFunction(MachineFunction &MF) {
 
       SmallPtrSet<MachineInstr *, 4> FixableDefs;
 
-      // If all definitions reaching MI sign-extend their output,
-      // then sext.w is redundant
-      if (!isSignExtendedW(SrcReg, MRI, FixableDefs))
+      // If all users only use the lower bits, this sext.w is redundant.
+      // Or if all definitions reaching MI sign-extend their output,
+      // then sext.w is redundant.
+      if (!hasAllWUsers(*MI, MRI) && !isSignExtendedW(SrcReg, MRI, FixableDefs))
         continue;
 
       Register DstReg = MI->getOperand(0).getReg();

diff  --git a/llvm/test/CodeGen/RISCV/sextw-removal.ll b/llvm/test/CodeGen/RISCV/sextw-removal.ll
index ffc441983840..daa1114b429e 100644
--- a/llvm/test/CodeGen/RISCV/sextw-removal.ll
+++ b/llvm/test/CodeGen/RISCV/sextw-removal.ll
@@ -1,9 +1,9 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+f,+zknh -target-abi=lp64f \
 ; RUN:   | FileCheck %s --check-prefixes=CHECK,RV64I
-; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zbb,+f,+zknh -target-abi=lp64f \
+; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zba,+zbb,+f,+zknh -target-abi=lp64f \
 ; RUN:   | FileCheck %s --check-prefixes=CHECK,RV64ZBB
-; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zbb,+f,+zknh -target-abi=lp64f \
+; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zba,+zbb,+f,+zknh -target-abi=lp64f \
 ; RUN:   -riscv-disable-sextw-removal | FileCheck %s --check-prefix=NOREMOVAL
 
 define void @test1(i32 signext %arg, i32 signext %arg1) nounwind {
@@ -1326,3 +1326,50 @@ bb7:                                              ; preds = %bb2
   ret void
 }
 declare i64 @llvm.riscv.sha256sig0.i64(i64)
+
+; The type promotion of %7 forms a sext_inreg, but %7 and %6 are combined to
+; form a sh2add. This leaves behind a sext.w that isn't needed.
+define signext i32 @sextw_sh2add(i1 zeroext %0, i32* %1, i32 signext %2, i32 signext %3, i32 signext %4) {
+; RV64I-LABEL: sextw_sh2add:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    slliw a2, a2, 2
+; RV64I-NEXT:    addw a2, a2, a3
+; RV64I-NEXT:    beqz a0, .LBB22_2
+; RV64I-NEXT:  # %bb.1:
+; RV64I-NEXT:    sw a2, 0(a1)
+; RV64I-NEXT:  .LBB22_2:
+; RV64I-NEXT:    addw a0, a2, a4
+; RV64I-NEXT:    ret
+;
+; RV64ZBB-LABEL: sextw_sh2add:
+; RV64ZBB:       # %bb.0:
+; RV64ZBB-NEXT:    sh2add a2, a2, a3
+; RV64ZBB-NEXT:    beqz a0, .LBB22_2
+; RV64ZBB-NEXT:  # %bb.1:
+; RV64ZBB-NEXT:    sw a2, 0(a1)
+; RV64ZBB-NEXT:  .LBB22_2:
+; RV64ZBB-NEXT:    addw a0, a2, a4
+; RV64ZBB-NEXT:    ret
+;
+; NOREMOVAL-LABEL: sextw_sh2add:
+; NOREMOVAL:       # %bb.0:
+; NOREMOVAL-NEXT:    sh2add a2, a2, a3
+; NOREMOVAL-NEXT:    sext.w a2, a2
+; NOREMOVAL-NEXT:    beqz a0, .LBB22_2
+; NOREMOVAL-NEXT:  # %bb.1:
+; NOREMOVAL-NEXT:    sw a2, 0(a1)
+; NOREMOVAL-NEXT:  .LBB22_2:
+; NOREMOVAL-NEXT:    addw a0, a2, a4
+; NOREMOVAL-NEXT:    ret
+  %6 = shl i32 %2, 2
+  %7 = add i32 %6, %3
+  br i1 %0, label %8, label %9
+
+8:                                                ; preds = %5
+  store i32 %7, i32* %1, align 4
+  br label %9
+
+9:                                                ; preds = %5, %8
+  %10 = add i32 %7, %4
+  ret i32 %10
+}


        


More information about the llvm-commits mailing list