Skip to content

Commit 9d9a50d

Browse files
committed
[MacroFusion] Support commutable instructions
If the second instruction is commutable, we should be able to check its commutable operands. A simple RISCV fusion is contained in this PR to show the functionality is correct, I may remove it when landing. There are some other issues I should fix. For example, we should be able to check that the destination register is tha same as the commutable operands. But I post this PR here firstly to gather feedbacks. Fixes #82738
1 parent e7c6091 commit 9d9a50d

File tree

5 files changed

+74
-5
lines changed

5 files changed

+74
-5
lines changed

llvm/include/llvm/Target/TargetSchedule.td

+2
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,8 @@ class BothFusionPredicateWithMCInstPredicate<MCInstPredicate pred>
620620
// Tie firstOpIdx and secondOpIdx. The operand of `FirstMI` at position
621621
// `firstOpIdx` should be the same as the operand of `SecondMI` at position
622622
// `secondOpIdx`.
623+
// If the operand at `secondOpIdx` has commutable operand, then the commutable
624+
// operand will be checked too.
623625
class TieReg<int firstOpIdx, int secondOpIdx> : BothFusionPredicate {
624626
int FirstOpIdx = firstOpIdx;
625627
int SecondOpIdx = secondOpIdx;

llvm/lib/Target/RISCV/RISCVMacroFusion.td

+21
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,24 @@ def TuneLDADDFusion
9191
CheckIsImmOperand<2>,
9292
CheckImmOperand<2, 0>
9393
]>>;
94+
95+
// These should be covered by Zba extension.
96+
// * shift left by one and add:
97+
// slli r1, r0, 1
98+
// add r1, r1, r2
99+
// * shift left by two and add:
100+
// slli r1, r0, 2
101+
// add r1, r1, r2
102+
// * shift left by three and add:
103+
// slli r1, r0, 3
104+
// add r1, r1, r2
105+
def ShiftNAddFusion
106+
: SimpleFusion<"shift-n-add-fusion", "HasShiftNAddFusion",
107+
"Enable SLLI+ADD to be fused to shift left by 1/2/3 and add",
108+
CheckAll<[
109+
CheckOpcode<[SLLI]>,
110+
CheckAny<[CheckImmOperand<2, 1>,
111+
CheckImmOperand<2, 2>,
112+
CheckImmOperand<2, 3>]>
113+
]>,
114+
CheckOpcode<[ADD]>>;

llvm/test/CodeGen/RISCV/macro-fusions.mir

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# REQUIRES: asserts
22
# RUN: llc -mtriple=riscv64-linux-gnu -x=mir < %s \
33
# RUN: -debug-only=machine-scheduler -start-before=machine-scheduler 2>&1 \
4-
# RUN: -mattr=+lui-addi-fusion,+auipc-addi-fusion,+zexth-fusion,+zextw-fusion,+shifted-zextw-fusion,+ld-add-fusion \
4+
# RUN: -mattr=+lui-addi-fusion,+auipc-addi-fusion,+zexth-fusion,+zextw-fusion,+shifted-zextw-fusion,+ld-add-fusion,+shift-n-add-fusion \
55
# RUN: | FileCheck %s
66

77
# CHECK: lui_addi:%bb.0
@@ -174,3 +174,31 @@ body: |
174174
$x11 = COPY %5
175175
PseudoRET
176176
...
177+
178+
# CHECK: shift_n_add:%bb.0
179+
# CHECK: Macro fuse: {{.*}}SLLI - ADD
180+
---
181+
name: shift_n_add
182+
tracksRegLiveness: true
183+
body: |
184+
bb.0.entry:
185+
liveins: $x10, $x11
186+
$x10 = SLLI $x10, 1
187+
$x12 = XORI $x11, 3
188+
$x11 = ADD $x11, $x10
189+
PseudoRET
190+
...
191+
192+
# CHECK: shift_n_add_commutable:%bb.0
193+
# CHECK: Macro fuse: {{.*}}SLLI - ADD
194+
---
195+
name: shift_n_add_commutable
196+
tracksRegLiveness: true
197+
body: |
198+
bb.0.entry:
199+
liveins: $x10, $x11
200+
$x10 = SLLI $x10, 1
201+
$x12 = XORI $x11, 3
202+
$x10 = ADD $x10, $x11
203+
PseudoRET
204+
...

llvm/test/TableGen/MacroFusion.td

+9-2
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,15 @@ def TestFusion: SimpleFusion<"test-fusion", "HasTestFusion", "Test Fusion",
9090
// CHECK-PREDICATOR-NEXT: }
9191
// CHECK-PREDICATOR-NEXT: if (!(FirstMI->getOperand(0).isReg() &&
9292
// CHECK-PREDICATOR-NEXT: SecondMI.getOperand(1).isReg() &&
93-
// CHECK-PREDICATOR-NEXT: FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
94-
// CHECK-PREDICATOR-NEXT: return false;
93+
// CHECK-PREDICATOR-NEXT: FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg())) {
94+
// CHECK-PREDICATOR-NEXT: if (!SecondMI.getDesc().isCommutable())
95+
// CHECK-PREDICATOR-NEXT: return false;
96+
// CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
97+
// CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
98+
// CHECK-PREDICATOR-NEXT: if (!(FirstMI->getOperand(0).getReg() ==
99+
// CHECK-PREDICATOR-NEXT: SecondMI.getOperand(SrcOpIdx2).getReg()))
100+
// CHECK-PREDICATOR-NEXT: return false;
101+
// CHECK-PREDICATOR-NEXT: }
95102
// CHECK-PREDICATOR-NEXT: return true;
96103
// CHECK-PREDICATOR-NEXT: }
97104
// CHECK-PREDICATOR-NEXT: } // end namespace llvm

llvm/utils/TableGen/MacroFusionPredicatorEmitter.cpp

+13-2
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,19 @@ void MacroFusionPredicatorEmitter::emitBothPredicate(Record *Predicate,
208208
<< ").isReg() &&\n";
209209
OS.indent(2) << " FirstMI->getOperand(" << FirstOpIdx
210210
<< ").getReg() == SecondMI.getOperand(" << SecondOpIdx
211-
<< ").getReg()))\n";
212-
OS.indent(2) << " return false;\n";
211+
<< ").getReg())) {\n";
212+
213+
OS.indent(4) << "if (!SecondMI.getDesc().isCommutable())\n";
214+
OS.indent(4) << " return false;\n";
215+
216+
OS.indent(4) << "unsigned SrcOpIdx1 = " << SecondOpIdx
217+
<< ", SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;\n";
218+
OS.indent(4)
219+
<< "if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))\n";
220+
OS.indent(4) << " if (!(FirstMI->getOperand(0).getReg() ==\n";
221+
OS.indent(4) << " SecondMI.getOperand(SrcOpIdx2).getReg()))\n";
222+
OS.indent(4) << " return false;\n";
223+
OS.indent(2) << "}\n";
213224
} else
214225
PrintFatalError(Predicate->getLoc(),
215226
"Unsupported predicate for both instruction: " +

0 commit comments

Comments
 (0)