[RISCV] Improve detection of when to skip (and (srl x, c2) c1) -> (srli (slli x, c3-c2), c3) isel.

We have a special case to skip this transform if c1 is 0xffffffff
and x is sext_inreg in order to use sraiw+zext.w. But we were only
checking that we have a sext_inreg opcode, not how many bits are
being sign extended.

This commit adds a check that it is a sext_inreg from i32 so we know for
sure that an sraiw can be created.
This commit is contained in:
Craig Topper 2022-03-16 13:57:21 -07:00
parent 50f82e6847
commit 2e10671ec7
2 changed files with 65 additions and 2 deletions

View File

@ -774,7 +774,8 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
// (srli (slli x, c3-c2), c3).
// Skip it in order to select sraiw.
bool Skip = Subtarget->hasStdExtZba() && C3 == 32 &&
X.getOpcode() == ISD::SIGN_EXTEND_INREG;
X.getOpcode() == ISD::SIGN_EXTEND_INREG &&
cast<VTSDNode>(X.getOperand(1))->getVT() == MVT::i32;
if (OneUseOrZExtW && !IsANDI && !Skip) {
SDNode *SLLI = CurDAG->getMachineNode(
RISCV::SLLI, DL, XLenVT, X,

View File

@ -2,7 +2,9 @@
; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=RV64I
; RUN: llc -mtriple=riscv64 -mattr=+m,+zba -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=RV64ZBA
; RUN: | FileCheck %s -check-prefixes=RV64ZBA,RV64ZBANOZBB
; RUN: llc -mtriple=riscv64 -mattr=+m,+zba,+zbb -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefixes=RV64ZBA,RV64ZBAZBB
define i64 @slliuw(i64 %a) nounwind {
; RV64I-LABEL: slliuw:
@ -1155,3 +1157,63 @@ define i64 @addshl64_5_8(i64 %a, i64 %b) {
%e = add i64 %c, %d
ret i64 %e
}
; Make sure we use sext.h+slli+srli for Zba+Zbb.
; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
; RV64I-LABEL: sext_ashr_zext_i8:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a0, a0, 56
; RV64I-NEXT: srai a0, a0, 56
; RV64I-NEXT: slli a0, a0, 23
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: ret
;
; RV64ZBANOZBB-LABEL: sext_ashr_zext_i8:
; RV64ZBANOZBB: # %bb.0:
; RV64ZBANOZBB-NEXT: slli a0, a0, 56
; RV64ZBANOZBB-NEXT: srai a0, a0, 56
; RV64ZBANOZBB-NEXT: slli a0, a0, 23
; RV64ZBANOZBB-NEXT: srli a0, a0, 32
; RV64ZBANOZBB-NEXT: ret
;
; RV64ZBAZBB-LABEL: sext_ashr_zext_i8:
; RV64ZBAZBB: # %bb.0:
; RV64ZBAZBB-NEXT: sext.b a0, a0
; RV64ZBAZBB-NEXT: slli a0, a0, 23
; RV64ZBAZBB-NEXT: srli a0, a0, 32
; RV64ZBAZBB-NEXT: ret
%ext = sext i8 %a to i32
%1 = ashr i32 %ext, 9
ret i32 %1
}
; Make sure we use sext.h+slli+srli for Zba+Zbb.
; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
; RV64I-LABEL: sext_ashr_zext_i16:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a0, a0, 48
; RV64I-NEXT: srai a0, a0, 48
; RV64I-NEXT: slli a0, a0, 23
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: ret
;
; RV64ZBANOZBB-LABEL: sext_ashr_zext_i16:
; RV64ZBANOZBB: # %bb.0:
; RV64ZBANOZBB-NEXT: slli a0, a0, 48
; RV64ZBANOZBB-NEXT: srai a0, a0, 48
; RV64ZBANOZBB-NEXT: slli a0, a0, 23
; RV64ZBANOZBB-NEXT: srli a0, a0, 32
; RV64ZBANOZBB-NEXT: ret
;
; RV64ZBAZBB-LABEL: sext_ashr_zext_i16:
; RV64ZBAZBB: # %bb.0:
; RV64ZBAZBB-NEXT: sext.h a0, a0
; RV64ZBAZBB-NEXT: slli a0, a0, 23
; RV64ZBAZBB-NEXT: srli a0, a0, 32
; RV64ZBAZBB-NEXT: ret
%ext = sext i16 %a to i32
%1 = ashr i32 %ext, 9
ret i32 %1
}