Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions llvm/include/llvm/CodeGen/SDPatternMatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,11 @@ template <typename LHS, typename RHS>
inline BinaryOpc_match<LHS, RHS> m_Srl(const LHS &L, const RHS &R) {
return BinaryOpc_match<LHS, RHS>(ISD::SRL, L, R);
}
template <typename LHS, typename RHS>
inline auto m_ExactSr(const LHS &L, const RHS &R) {
return m_AnyOf(BinaryOpc_match<LHS, RHS>(ISD::SRA, L, R, SDNodeFlags::Exact),
BinaryOpc_match<LHS, RHS>(ISD::SRL, L, R, SDNodeFlags::Exact));
}

template <typename LHS, typename RHS>
inline BinaryOpc_match<LHS, RHS> m_Rotl(const LHS &L, const RHS &R) {
Expand Down
11 changes: 6 additions & 5 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16802,9 +16802,7 @@ static SDValue expandMulToAddOrSubOfShl(SDNode *N, SelectionDAG &DAG,
// because X is exact (Y >> M + 2).
uint64_t ShAmt = Log2_64(MulAmtLowBit) + 2;
using namespace SDPatternMatch;
return sd_match(X, m_AnyOf(m_Sra(m_Value(), m_SpecificInt(ShAmt)),
m_Srl(m_Value(), m_SpecificInt(ShAmt)))) &&
X->getFlags().hasExact();
return sd_match(X, m_ExactSr(m_Value(), m_SpecificInt(ShAmt)));
};
if (isPowerOf2_64(MulAmt - MulAmtLowBit) && !(CanSub && PreferSub())) {
Op = ISD::ADD;
Expand All @@ -16829,10 +16827,13 @@ static SDValue getShlAddShlAdd(SDNode *N, SelectionDAG &DAG, unsigned ShX,
SDLoc DL(N);
EVT VT = N->getValueType(0);
SDValue X = N->getOperand(0);
// Put the shift first if we can fold a zext into the shift forming a slli.uw.
// Put the shift first if we can fold:
// a. a zext into the shift forming a slli.uw
// b. an exact shift right forming one shorter shift or no shift at all
using namespace SDPatternMatch;
if (Shift != 0 &&
sd_match(X, m_And(m_Value(), m_SpecificInt(UINT64_C(0xffffffff))))) {
sd_match(X, m_AnyOf(m_And(m_Value(), m_SpecificInt(UINT64_C(0xffffffff))),
m_ExactSr(m_Value(), m_ConstInt())))) {
X = DAG.getNode(ISD::SHL, DL, VT, X, DAG.getConstant(Shift, DL, VT));
Shift = 0;
}
Expand Down
71 changes: 71 additions & 0 deletions llvm/test/CodeGen/RISCV/rv64zba.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5016,3 +5016,74 @@ define ptr @shl_add_knownbits(ptr %p, i64 %i) {
%r = getelementptr i8, ptr %p, i64 %shr
ret ptr %r
}

define i64 @exactashr1mul6(i64 %a) {
; RV64I-LABEL: exactashr1mul6:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a0, 1
; RV64I-NEXT: add a0, a1, a0
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: exactashr1mul6:
; RV64ZBA: # %bb.0:
; RV64ZBA-NEXT: sh1add a0, a0, a0
; RV64ZBA-NEXT: ret
;
; RV64XANDESPERF-LABEL: exactashr1mul6:
; RV64XANDESPERF: # %bb.0:
; RV64XANDESPERF-NEXT: nds.lea.h a0, a0, a0
; RV64XANDESPERF-NEXT: ret
%c = ashr exact i64 %a, 1
%d = mul i64 %c, 6
ret i64 %d
}

define i64 @exactlshr3mul22(i64 %a) {
; RV64I-LABEL: exactlshr3mul22:
; RV64I: # %bb.0:
; RV64I-NEXT: srli a0, a0, 3
; RV64I-NEXT: li a1, 22
; RV64I-NEXT: mul a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: exactlshr3mul22:
; RV64ZBA: # %bb.0:
; RV64ZBA-NEXT: srli a0, a0, 2
; RV64ZBA-NEXT: sh2add a1, a0, a0
; RV64ZBA-NEXT: sh1add a0, a1, a0
; RV64ZBA-NEXT: ret
;
; RV64XANDESPERF-LABEL: exactlshr3mul22:
; RV64XANDESPERF: # %bb.0:
; RV64XANDESPERF-NEXT: srli a0, a0, 2
; RV64XANDESPERF-NEXT: nds.lea.w a1, a0, a0
; RV64XANDESPERF-NEXT: nds.lea.h a0, a0, a1
; RV64XANDESPERF-NEXT: ret
%c = lshr exact i64 %a, 3
%d = mul i64 %c, 22
ret i64 %d
}

define i64 @exactashr1mul36(i64 %a) {
; RV64I-LABEL: exactashr1mul36:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a0, 1
; RV64I-NEXT: slli a0, a0, 4
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: exactashr1mul36:
; RV64ZBA: # %bb.0:
; RV64ZBA-NEXT: slli a0, a0, 1
; RV64ZBA-NEXT: sh3add a0, a0, a0
; RV64ZBA-NEXT: ret
;
; RV64XANDESPERF-LABEL: exactashr1mul36:
; RV64XANDESPERF: # %bb.0:
; RV64XANDESPERF-NEXT: slli a0, a0, 1
; RV64XANDESPERF-NEXT: nds.lea.d a0, a0, a0
; RV64XANDESPERF-NEXT: ret
%c = ashr exact i64 %a, 1
%d = mul i64 %c, 36
ret i64 %d
}
Loading