Skip to content

Commit 8e748ac

Browse files
committed
[RISCV] Add ISel patterns for Xqciac QC.MULIADD instruction
Add basic isel patterns for the multiple accumulate QC.MULIADD instruction.
1 parent 15e7753 commit 8e748ac

File tree

3 files changed

+193
-0
lines changed

3 files changed

+193
-0
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15895,6 +15895,13 @@ static SDValue expandMulToNAFSequence(SDNode *N, SelectionDAG &DAG,
1589515895
// X * (2^N +/- 2^M) -> (add/sub (shl X, C1), (shl X, C2))
1589615896
static SDValue expandMulToAddOrSubOfShl(SDNode *N, SelectionDAG &DAG,
1589715897
uint64_t MulAmt) {
15898+
// Don't do this is if the Xqciac extension is enabled and the MulAmt is
15899+
// simm12.
15900+
const RISCVSubtarget &Subtarget =
15901+
DAG.getMachineFunction().getSubtarget<RISCVSubtarget>();
15902+
if (Subtarget.hasVendorXqciac() && isInt<12>(MulAmt))
15903+
return SDValue();
15904+
1589815905
uint64_t MulAmtLowBit = MulAmt & (-MulAmt);
1589915906
ISD::NodeType Op;
1590015907
uint64_t ShiftAmt1;
@@ -23700,6 +23707,10 @@ bool RISCVTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
2370023707
auto *ConstNode = cast<ConstantSDNode>(C);
2370123708
const APInt &Imm = ConstNode->getAPIntValue();
2370223709

23710+
// Don't do this if the Xqciac extension is enabled and the Imm in simm12.
23711+
if (Subtarget.hasVendorXqciac() && Imm.isSignedIntN(12))
23712+
return false;
23713+
2370323714
// Break the MUL to a SLLI and an ADD/SUB.
2370423715
if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2() ||
2370523716
(1 - Imm).isPowerOf2() || (-1 - Imm).isPowerOf2())

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,11 @@ class SelectQCbi<CondCode Cond, DAGOperand InTyImm, Pseudo OpNode >
13321332
(OpNode GPRNoX0:$lhs, InTyImm:$Constant,
13331333
(IntCCtoRISCVCC $cc), GPRNoX0:$truev, GPRNoX0:$falsev)>;
13341334

1335+
let Predicates = [HasVendorXqciac, IsRV32] in {
1336+
def : Pat<(XLenVT (add GPRNoX0:$rd, (mul GPRNoX0:$rs1, simm12:$imm12))),
1337+
(QC_MULIADD GPRNoX0:$rd, GPRNoX0:$rs1, simm12:$imm12)>;
1338+
} // Predicates = [HasVendorXqciac, IsRV32]
1339+
13351340
/// Simple arithmetic operations
13361341

13371342
let Predicates = [HasVendorXqcilia, IsRV32] in {

llvm/test/CodeGen/RISCV/xqciac.ll

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=riscv32 -mattr=+m -verify-machineinstrs < %s \
3+
; RUN: | FileCheck %s -check-prefix=RV32IM
4+
; RUN: llc -mtriple=riscv32 -mattr=+m,+experimental-xqciac -verify-machineinstrs < %s \
5+
; RUN: | FileCheck %s -check-prefix=RV32IMXQCIAC
6+
; RUN: llc -mtriple=riscv32 -mattr=+m,+experimental-xqciac,+zba -verify-machineinstrs < %s \
7+
; RUN: | FileCheck %s -check-prefix=RV32IZBAMXQCIAC
8+
9+
define dso_local i32 @mul(i32 %a, i32 %b) local_unnamed_addr #0 {
10+
; RV32IM-LABEL: mul:
11+
; RV32IM: # %bb.0: # %entry
12+
; RV32IM-NEXT: slli a0, a1, 5
13+
; RV32IM-NEXT: add a0, a0, a1
14+
; RV32IM-NEXT: ret
15+
;
16+
; RV32IMXQCIAC-LABEL: mul:
17+
; RV32IMXQCIAC: # %bb.0: # %entry
18+
; RV32IMXQCIAC-NEXT: li a0, 33
19+
; RV32IMXQCIAC-NEXT: mul a0, a1, a0
20+
; RV32IMXQCIAC-NEXT: ret
21+
;
22+
; RV32IZBAMXQCIAC-LABEL: mul:
23+
; RV32IZBAMXQCIAC: # %bb.0: # %entry
24+
; RV32IZBAMXQCIAC-NEXT: li a0, 33
25+
; RV32IZBAMXQCIAC-NEXT: mul a0, a1, a0
26+
; RV32IZBAMXQCIAC-NEXT: ret
27+
entry:
28+
%mul = mul nsw i32 %b, 33
29+
ret i32 %mul
30+
}
31+
32+
define dso_local i32 @muliadd(i32 %a, i32 %b) local_unnamed_addr #0 {
33+
; RV32IM-LABEL: muliadd:
34+
; RV32IM: # %bb.0: # %entry
35+
; RV32IM-NEXT: li a2, 165
36+
; RV32IM-NEXT: mul a1, a1, a2
37+
; RV32IM-NEXT: add a0, a1, a0
38+
; RV32IM-NEXT: ret
39+
;
40+
; RV32IMXQCIAC-LABEL: muliadd:
41+
; RV32IMXQCIAC: # %bb.0: # %entry
42+
; RV32IMXQCIAC-NEXT: qc.muliadd a0, a1, 165
43+
; RV32IMXQCIAC-NEXT: ret
44+
;
45+
; RV32IZBAMXQCIAC-LABEL: muliadd:
46+
; RV32IZBAMXQCIAC: # %bb.0: # %entry
47+
; RV32IZBAMXQCIAC-NEXT: qc.muliadd a0, a1, 165
48+
; RV32IZBAMXQCIAC-NEXT: ret
49+
entry:
50+
%mul = mul nsw i32 %b, 165
51+
%add = add nsw i32 %mul, %a
52+
ret i32 %add
53+
}
54+
55+
define dso_local i32 @muliadd_neg(i32 %a, i32 %b) local_unnamed_addr #0 {
56+
; RV32IM-LABEL: muliadd_neg:
57+
; RV32IM: # %bb.0: # %entry
58+
; RV32IM-NEXT: li a2, -165
59+
; RV32IM-NEXT: mul a1, a1, a2
60+
; RV32IM-NEXT: add a0, a1, a0
61+
; RV32IM-NEXT: ret
62+
;
63+
; RV32IMXQCIAC-LABEL: muliadd_neg:
64+
; RV32IMXQCIAC: # %bb.0: # %entry
65+
; RV32IMXQCIAC-NEXT: qc.muliadd a0, a1, -165
66+
; RV32IMXQCIAC-NEXT: ret
67+
;
68+
; RV32IZBAMXQCIAC-LABEL: muliadd_neg:
69+
; RV32IZBAMXQCIAC: # %bb.0: # %entry
70+
; RV32IZBAMXQCIAC-NEXT: qc.muliadd a0, a1, -165
71+
; RV32IZBAMXQCIAC-NEXT: ret
72+
entry:
73+
%mul = mul nsw i32 %b, -165
74+
%add = add nsw i32 %mul, %a
75+
ret i32 %add
76+
}
77+
78+
define dso_local i32 @pow2immplus1(i32 %a, i32 %b) local_unnamed_addr #0 {
79+
; RV32IM-LABEL: pow2immplus1:
80+
; RV32IM: # %bb.0: # %entry
81+
; RV32IM-NEXT: slli a2, a1, 5
82+
; RV32IM-NEXT: add a0, a1, a0
83+
; RV32IM-NEXT: add a0, a2, a0
84+
; RV32IM-NEXT: ret
85+
;
86+
; RV32IMXQCIAC-LABEL: pow2immplus1:
87+
; RV32IMXQCIAC: # %bb.0: # %entry
88+
; RV32IMXQCIAC-NEXT: qc.muliadd a0, a1, 33
89+
; RV32IMXQCIAC-NEXT: ret
90+
;
91+
; RV32IZBAMXQCIAC-LABEL: pow2immplus1:
92+
; RV32IZBAMXQCIAC: # %bb.0: # %entry
93+
; RV32IZBAMXQCIAC-NEXT: qc.muliadd a0, a1, 33
94+
; RV32IZBAMXQCIAC-NEXT: ret
95+
entry:
96+
%mul = mul nsw i32 %b, 33
97+
%add = add nsw i32 %mul, %a
98+
ret i32 %add
99+
}
100+
101+
define dso_local i32 @gtsimm12(i32 %a, i32 %b) local_unnamed_addr #0 {
102+
; RV32IM-LABEL: gtsimm12:
103+
; RV32IM: # %bb.0: # %entry
104+
; RV32IM-NEXT: lui a2, 1
105+
; RV32IM-NEXT: addi a2, a2, 477
106+
; RV32IM-NEXT: mul a1, a1, a2
107+
; RV32IM-NEXT: add a0, a1, a0
108+
; RV32IM-NEXT: ret
109+
;
110+
; RV32IMXQCIAC-LABEL: gtsimm12:
111+
; RV32IMXQCIAC: # %bb.0: # %entry
112+
; RV32IMXQCIAC-NEXT: lui a2, 1
113+
; RV32IMXQCIAC-NEXT: addi a2, a2, 477
114+
; RV32IMXQCIAC-NEXT: mul a1, a1, a2
115+
; RV32IMXQCIAC-NEXT: add a0, a0, a1
116+
; RV32IMXQCIAC-NEXT: ret
117+
;
118+
; RV32IZBAMXQCIAC-LABEL: gtsimm12:
119+
; RV32IZBAMXQCIAC: # %bb.0: # %entry
120+
; RV32IZBAMXQCIAC-NEXT: lui a2, 1
121+
; RV32IZBAMXQCIAC-NEXT: addi a2, a2, 477
122+
; RV32IZBAMXQCIAC-NEXT: mul a1, a1, a2
123+
; RV32IZBAMXQCIAC-NEXT: add a0, a0, a1
124+
; RV32IZBAMXQCIAC-NEXT: ret
125+
entry:
126+
%mul = mul nsw i32 %b, 4573
127+
%add = add nsw i32 %mul, %a
128+
ret i32 %add
129+
}
130+
131+
; NOTE: This will become qc.shladd once support is added
132+
define dso_local i32 @pow2(i32 %a, i32 %b) local_unnamed_addr #0 {
133+
; RV32IM-LABEL: pow2:
134+
; RV32IM: # %bb.0: # %entry
135+
; RV32IM-NEXT: slli a1, a1, 5
136+
; RV32IM-NEXT: add a0, a1, a0
137+
; RV32IM-NEXT: ret
138+
;
139+
; RV32IMXQCIAC-LABEL: pow2:
140+
; RV32IMXQCIAC: # %bb.0: # %entry
141+
; RV32IMXQCIAC-NEXT: slli a1, a1, 5
142+
; RV32IMXQCIAC-NEXT: add a0, a0, a1
143+
; RV32IMXQCIAC-NEXT: ret
144+
;
145+
; RV32IZBAMXQCIAC-LABEL: pow2:
146+
; RV32IZBAMXQCIAC: # %bb.0: # %entry
147+
; RV32IZBAMXQCIAC-NEXT: slli a1, a1, 5
148+
; RV32IZBAMXQCIAC-NEXT: add a0, a0, a1
149+
; RV32IZBAMXQCIAC-NEXT: ret
150+
entry:
151+
%mul = mul nsw i32 %b, 32
152+
%add = add nsw i32 %mul, %a
153+
ret i32 %add
154+
}
155+
156+
define dso_local i32 @shxadd(i32 %a, i32 %b) local_unnamed_addr #0 {
157+
; RV32IM-LABEL: shxadd:
158+
; RV32IM: # %bb.0: # %entry
159+
; RV32IM-NEXT: slli a1, a1, 1
160+
; RV32IM-NEXT: add a0, a1, a0
161+
; RV32IM-NEXT: ret
162+
;
163+
; RV32IMXQCIAC-LABEL: shxadd:
164+
; RV32IMXQCIAC: # %bb.0: # %entry
165+
; RV32IMXQCIAC-NEXT: slli a1, a1, 1
166+
; RV32IMXQCIAC-NEXT: add a0, a0, a1
167+
; RV32IMXQCIAC-NEXT: ret
168+
;
169+
; RV32IZBAMXQCIAC-LABEL: shxadd:
170+
; RV32IZBAMXQCIAC: # %bb.0: # %entry
171+
; RV32IZBAMXQCIAC-NEXT: sh1add a0, a1, a0
172+
; RV32IZBAMXQCIAC-NEXT: ret
173+
entry:
174+
%mul = mul nsw i32 %b, 2
175+
%add = add nsw i32 %mul, %a
176+
ret i32 %add
177+
}

0 commit comments

Comments
 (0)