[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.
This commit is contained in:
Craig Topper
2022-12-15 11:01:20 -08:00
parent a3b4feff25
commit 992bee045b
2 changed files with 56 additions and 6 deletions

View File

@@ -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();

View File

@@ -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
}