Skip to content

Commit 6b83fe5

Browse files
preamesmshockwave
andauthored
[RISCV] Strength reduce mul by 2^n + 2/4/8 + 1 (#88911)
With zba, we can expand this to (add (shl X, C1), (shXadd X, X)). Note that this is our first expansion to a three instruction sequence. I believe this to general be a reasonable tradeoff for most architectures, but we may want to (someday) consider a tuning flag here. I plan to support 2^n + (2/4/8 + 1) eventually as well, but that comes behind 2^N - 2^M. Both are also three instruction sequences. --------- Co-authored-by: Min-Yih Hsu <[email protected]>
1 parent aefff77 commit 6b83fe5

File tree

2 files changed

+73
-15
lines changed

2 files changed

+73
-15
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13437,6 +13437,43 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
1343713437
return DAG.getNode(ISD::ADD, DL, VT, Shift1, Shift2);
1343813438
}
1343913439
}
13440+
13441+
// 2^(1,2,3) * 3,5,9 + 1 -> (shXadd (shYadd x, x), x)
13442+
// Matched in tablegen, avoid perturbing patterns.
13443+
switch (MulAmt) {
13444+
case 11:
13445+
case 13:
13446+
case 19:
13447+
case 21:
13448+
case 25:
13449+
case 27:
13450+
case 29:
13451+
case 37:
13452+
case 41:
13453+
case 45:
13454+
case 73:
13455+
case 91:
13456+
return SDValue();
13457+
default:
13458+
break;
13459+
}
13460+
13461+
// 2^n + 2/4/8 + 1 -> (add (shl X, C1), (shXadd X, X))
13462+
if (MulAmt > 2 && isPowerOf2_64((MulAmt - 1) & (MulAmt - 2))) {
13463+
unsigned ScaleShift = llvm::countr_zero(MulAmt - 1);
13464+
if (ScaleShift >= 1 && ScaleShift < 4) {
13465+
unsigned ShiftAmt = Log2_64(((MulAmt - 1) & (MulAmt - 2)));
13466+
SDLoc DL(N);
13467+
SDValue Shift1 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
13468+
DAG.getConstant(ShiftAmt, DL, VT));
13469+
SDValue Shift2 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
13470+
DAG.getConstant(ScaleShift, DL, VT));
13471+
return DAG.getNode(
13472+
ISD::ADD, DL, VT, Shift1,
13473+
DAG.getNode(ISD::ADD, DL, VT, Shift2, N->getOperand(0)));
13474+
}
13475+
}
13476+
1344013477
return SDValue();
1344113478
}
1344213479

llvm/test/CodeGen/RISCV/rv64zba.ll

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -598,31 +598,52 @@ define i64 @mul125(i64 %a) {
598598
}
599599

600600
define i64 @mul131(i64 %a) {
601-
; CHECK-LABEL: mul131:
602-
; CHECK: # %bb.0:
603-
; CHECK-NEXT: li a1, 131
604-
; CHECK-NEXT: mul a0, a0, a1
605-
; CHECK-NEXT: ret
601+
; RV64I-LABEL: mul131:
602+
; RV64I: # %bb.0:
603+
; RV64I-NEXT: li a1, 131
604+
; RV64I-NEXT: mul a0, a0, a1
605+
; RV64I-NEXT: ret
606+
;
607+
; RV64ZBA-LABEL: mul131:
608+
; RV64ZBA: # %bb.0:
609+
; RV64ZBA-NEXT: sh1add a1, a0, a0
610+
; RV64ZBA-NEXT: slli a0, a0, 7
611+
; RV64ZBA-NEXT: add a0, a0, a1
612+
; RV64ZBA-NEXT: ret
606613
%c = mul i64 %a, 131
607614
ret i64 %c
608615
}
609616

610617
define i64 @mul133(i64 %a) {
611-
; CHECK-LABEL: mul133:
612-
; CHECK: # %bb.0:
613-
; CHECK-NEXT: li a1, 133
614-
; CHECK-NEXT: mul a0, a0, a1
615-
; CHECK-NEXT: ret
618+
; RV64I-LABEL: mul133:
619+
; RV64I: # %bb.0:
620+
; RV64I-NEXT: li a1, 133
621+
; RV64I-NEXT: mul a0, a0, a1
622+
; RV64I-NEXT: ret
623+
;
624+
; RV64ZBA-LABEL: mul133:
625+
; RV64ZBA: # %bb.0:
626+
; RV64ZBA-NEXT: sh2add a1, a0, a0
627+
; RV64ZBA-NEXT: slli a0, a0, 7
628+
; RV64ZBA-NEXT: add a0, a0, a1
629+
; RV64ZBA-NEXT: ret
616630
%c = mul i64 %a, 133
617631
ret i64 %c
618632
}
619633

620634
define i64 @mul137(i64 %a) {
621-
; CHECK-LABEL: mul137:
622-
; CHECK: # %bb.0:
623-
; CHECK-NEXT: li a1, 137
624-
; CHECK-NEXT: mul a0, a0, a1
625-
; CHECK-NEXT: ret
635+
; RV64I-LABEL: mul137:
636+
; RV64I: # %bb.0:
637+
; RV64I-NEXT: li a1, 137
638+
; RV64I-NEXT: mul a0, a0, a1
639+
; RV64I-NEXT: ret
640+
;
641+
; RV64ZBA-LABEL: mul137:
642+
; RV64ZBA: # %bb.0:
643+
; RV64ZBA-NEXT: sh3add a1, a0, a0
644+
; RV64ZBA-NEXT: slli a0, a0, 7
645+
; RV64ZBA-NEXT: add a0, a0, a1
646+
; RV64ZBA-NEXT: ret
626647
%c = mul i64 %a, 137
627648
ret i64 %c
628649
}

0 commit comments

Comments
 (0)