[llvm] [RISCV] Add macro fusion support for the Xqci extension instructions (PR #209542)

Pankaj Gode via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 28 05:11:41 PDT 2026


https://github.com/pgodeq updated https://github.com/llvm/llvm-project/pull/209542

>From 5f17a7f73f72970f8263688c6f3aedcd7d33ae61 Mon Sep 17 00:00:00 2001
From: Pankaj Gode <pgode at qti.qualcomm.com>
Date: Tue, 14 Jul 2026 00:38:24 +0530
Subject: [PATCH 1/6] [RISCV] Add macro fusion support for the Xqci extension
 instructions

Add macro fusion definitions for the Qualcomm Xqci extension covering
movimm-alu, movimm-mul, movimm-ldst, movimm-jump, movimm-longlogical,
movimm-mov, mov-mov, mov-longlogical fusions.

The fusion definitions live in a new RISCVMacroFusionXQCI.td which is
included from RISCVMacroFusion.td. A MIR test and the feature list
test are updated accordingly.

To accomodate additional features, increased MAX_SUBTARGET_FEATURES
to 448 (from 384).

Signed-off-by: Pankaj Gode <pgode at qti.qualcomm.com>
---
 .../llvm/TargetParser/SubtargetFeature.h      |   2 +-
 llvm/lib/Target/RISCV/RISCVMacroFusion.td     |   4 +
 llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td | 146 ++++++++++++
 llvm/test/CodeGen/RISCV/features-info.ll      |   8 +
 .../test/CodeGen/RISCV/macro-fusions-xqci.mir | 211 ++++++++++++++++++
 5 files changed, 370 insertions(+), 1 deletion(-)
 create mode 100644 llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
 create mode 100644 llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir

diff --git a/llvm/include/llvm/TargetParser/SubtargetFeature.h b/llvm/include/llvm/TargetParser/SubtargetFeature.h
index 3c136b27374dd..96820371fa3d0 100644
--- a/llvm/include/llvm/TargetParser/SubtargetFeature.h
+++ b/llvm/include/llvm/TargetParser/SubtargetFeature.h
@@ -33,7 +33,7 @@ namespace llvm {
 class raw_ostream;
 class Triple;
 
-const unsigned MAX_SUBTARGET_WORDS = 6;
+const unsigned MAX_SUBTARGET_WORDS = 7;
 const unsigned MAX_SUBTARGET_FEATURES = MAX_SUBTARGET_WORDS * 64;
 
 /// Container class for subtarget features.
diff --git a/llvm/lib/Target/RISCV/RISCVMacroFusion.td b/llvm/lib/Target/RISCV/RISCVMacroFusion.td
index ca02aaa7980f9..cf11cbac583e6 100644
--- a/llvm/lib/Target/RISCV/RISCVMacroFusion.td
+++ b/llvm/lib/Target/RISCV/RISCVMacroFusion.td
@@ -267,3 +267,7 @@ def TuneFusionShiftBitExtract
                        return false;
                    }]>,
                  ]>;
+
+
+// Xqci macro fusions.
+include "RISCVMacroFusionXQCI.td"
diff --git a/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
new file mode 100644
index 0000000000000..689ceb24df375
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
@@ -0,0 +1,146 @@
+//==---- RISCVMacroFusionXQCI.td - Macro Fusions for XQCI -----*- tablegen-*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// ===---------------------------------------------------------------------===//
+// The following definitions describe macro fusion predicators applicable to
+// Xqci instructions.
+
+// Fuse two instructions where the destination register of the first
+// instruction is the same as the destination register of the second
+// instruction.
+class FirstRdEqSecondRdFusion<string name, string fieldName, string desc,
+                   MCInstPredicate firstPred, MCInstPredicate secondPred,
+                   int secondOpIdx=0, int firstOpIdx=0>
+  : Fusion<name, fieldName, desc,
+           [
+             SecondFusionPredicateWithMCInstPredicate<secondPred>,
+             WildcardTrue,
+             FirstFusionPredicateWithMCInstPredicate<firstPred>,
+             TieReg<firstOpIdx, secondOpIdx>
+           ]>;
+
+// Fuse two operations without tying any of their register operands.
+class XqciFusionNoTie<string name, string fieldName, string desc,
+                        MCInstPredicate firstPred, MCInstPredicate secondPred>
+  : Fusion<name, fieldName, desc,
+           [
+             SecondFusionPredicateWithMCInstPredicate<secondPred>,
+             WildcardTrue,
+             FirstFusionPredicateWithMCInstPredicate<firstPred>
+           ]>;
+
+defvar LoadAndMoveImmOp = [ADDI, LUI, QC_E_LI, QC_LI];
+defvar LoadImmOp = [LUI, QC_E_LI, QC_LI];
+// 48-bit load store
+defvar LongLoadStoreXqciOp = [QC_E_LB, QC_E_LBU, QC_E_LH, QC_E_LHU, QC_E_LW,
+                              QC_E_SB, QC_E_SH, QC_E_SW];
+// 48-bit logical operations
+defvar LongLogicalXqciOp = [QC_E_XORAI, QC_E_ORAI, QC_E_ANDAI, QC_E_ADDAI];
+
+// Fuse load-immediate/move-immediate followed by arithmetic/logic.
+def TuneMOVIMMALUXqciFusion
+  : SimpleFusion<"xqci-movimm-alu", "HasMOVIMMALUXqciFusion",
+                "Enable MOVIMM + ALU operations macrofusion",
+                CheckAny<[
+                  CheckOpcode<[AUIPC]>,
+                  CheckOpcode<LoadAndMoveImmOp>,
+                ]>,
+                CheckOpcode<[
+                  ADD, ADDI, SUB, MUL,
+                  AND, ANDI, OR, ORI, ORN, XOR, XORI, XNOR,
+                  QC_E_ANDI, QC_E_ORI, QC_E_XORI,
+                  SLLI, SRLI, SRAI, QC_LI, QC_E_LI,
+                  MAX, MAXU, MIN, MINU
+                ]>>;
+
+// Fuse load-immediate/move-immediate followed by multiply.
+def TuneMOVIMMMULXqciFusion
+  : SimpleFusion<"xqci-movimm-mul", "HasMOVIMMMULXqciFusion",
+                 "Enable MOVIMM + multiply macrofusion",
+                 CheckOpcode<LoadAndMoveImmOp>,
+                 CheckOpcode<[MUL]>>;
+
+// Fuse load-immediate/move-immediate followed by long load/store.
+def TuneMOVIMMLoadStoreXqciFusion
+  : SimpleFusion<"xqci-movimm-ldst", "HasMOVIMMLoadStoreXqciFusion",
+                 "Enable MOVIMM + long Load/Store macrofusion",
+                 CheckOpcode<LoadAndMoveImmOp>,
+                 CheckOpcode<LongLoadStoreXqciOp>>;
+
+// Fuse load-immediate/move-immediate followed by a jump.
+def TuneMOVIMMJumpXqciFusion
+  : SimpleFusion<"xqci-movimm-jump", "HasMOVIMMJumpXqciFusion",
+                 "Enable MOVIMM + Jump macrofusion",
+                 CheckOpcode<LoadAndMoveImmOp>,
+                 CheckOpcode<[JALR]>>;
+
+// Fuse load-immediate/move-immediate followed by long logical operation.
+// The destination register of the first operation is the same as the
+// destination register of the second operation.
+def TuneMOVIMMLongLogicalXciFusion
+  : FirstRdEqSecondRdFusion<"xqci-movimm-longlogical",
+                 "HasMOVIMMLongLogicalXqciFusion",
+                 "Enable MOVIMM + long logical operation macrofusion",
+                 CheckOpcode<LoadAndMoveImmOp>,
+                 CheckOpcode<LongLogicalXqciOp>
+                 >;
+
+// Fuse load-immediate/move-immediate followed by move.
+def TuneMOVIMMMovXqciFusion
+  : SimpleFusion<"xqci-movimm-mov", "HasMOVIMMMovXqciFusion",
+                 "Enable MOVIMM + Move macrofusion",
+                 CheckAny<[
+                   CheckAll<[
+                     CheckOpcode<[ADDI]>,
+                     CheckRegOperand<1, X0>
+                   ]>,
+                   CheckOpcode<LoadImmOp>,
+                 ]>,
+                 CheckAny<[
+                   CheckAll<[
+                     CheckOpcode<[ADDI]>,
+                     CheckIsImmOperand<2>,
+                     CheckImmOperand<2, 0>
+                   ]>,
+                   CheckOpcode<LoadImmOp>
+                 ]>
+                >;
+
+// Fuse two adjacent moves.
+def TuneMovMovXqciFusion
+  : XqciFusionNoTie<"xqci-mov-mov", "HasMovMovXqciFusion",
+                 "Enable move + move macrofusion",
+                 CheckAny<[
+                   CheckAll<[
+                     CheckOpcode<[ADDI]>,
+                     CheckIsImmOperand<2>,
+                     CheckImmOperand<2, 0>
+                   ]>,
+                   CheckOpcode<LoadImmOp>,
+                 ]>,
+                 CheckAny<[
+                   CheckAll<[
+                     CheckOpcode<[ADDI]>,
+                     CheckIsImmOperand<2>,
+                     CheckImmOperand<2, 0>
+                   ]>,
+                   CheckOpcode<LoadImmOp>
+                 ]>
+                 >;
+
+// Fuse move followed by long logical operation.
+def TuneMovALUXqciFusion
+  : FirstRdEqSecondRdFusion<"xqci-mov-longlogical", "HasMovALUXqciFusion",
+                            "Enable MOV + long logical operation macrofusion",
+                            CheckAll<[
+                              CheckOpcode<[ADDI]>,
+                              CheckIsImmOperand<2>,
+                              CheckImmOperand<2, 0>
+                            ]>,
+                            CheckOpcode<LongLogicalXqciOp>
+                            >;
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 142e6b2694937..5523fa4ed8539 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -72,6 +72,14 @@
 ; CHECK-NEXT:   fusion-shift-bit-extract         - Enable SLLI+SRLI/SRAI macrofusion.
 ; CHECK-NEXT:   fusion-shifted-zextw             - Enable SLLI+SRLI to be fused when computing (shifted) word zero extension.
 ; CHECK-NEXT:   fusion-shxadd-load               - Enable SH(1|2|3)ADD(.UW) + load macrofusion.
+; CHECK-NEXT:   fusion-xqci-mov-longlogical      - Enable MOV + long logical operation macrofusion.
+; CHECK-NEXT:   fusion-xqci-mov-mov              - Enable move + move macrofusion.
+; CHECK-NEXT:   fusion-xqci-movimm-alu           - Enable MOVIMM + ALU operations macrofusion.
+; CHECK-NEXT:   fusion-xqci-movimm-jump          - Enable MOVIMM + Jump macrofusion.
+; CHECK-NEXT:   fusion-xqci-movimm-ldst          - Enable MOVIMM + long Load/Store macrofusion.
+; CHECK-NEXT:   fusion-xqci-movimm-longlogical   - Enable MOVIMM + long logical operation macrofusion.
+; CHECK-NEXT:   fusion-xqci-movimm-mov           - Enable MOVIMM + Move macrofusion.
+; CHECK-NEXT:   fusion-xqci-movimm-mul           - Enable MOVIMM + multiply macrofusion.
 ; CHECK-NEXT:   fusion-zexth                     - Enable SLLI+SRLI to be fused to zero extension of halfword.
 ; CHECK-NEXT:   fusion-zextw                     - Enable SLLI+SRLI to be fused to zero extension of word.
 ; CHECK-NEXT:   h                                - 'H' (Hypervisor).
diff --git a/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir b/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir
new file mode 100644
index 0000000000000..c138093766f69
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir
@@ -0,0 +1,211 @@
+# REQUIRES: asserts
+# RUN: llc -mtriple=riscv32-linux-gnu -x=mir < %s \
+# RUN:   -debug-only=machine-scheduler -start-before=machine-scheduler 2>&1 \
+# RUN:   -mattr=+xqcilia,+xqcili,+xqcilo,+zmmul,+fusion-xqci-movimm-alu \
+# RUN:   -mattr=+fusion-xqci-movimm-mul,+fusion-xqci-movimm-ldst \
+# RUN:   -mattr=+fusion-xqci-movimm-jump \
+# RUN:   -mattr=+fusion-xqci-movimm-longlogical,+fusion-xqci-movimm-mov \
+# RUN:   -mattr=+fusion-xqci-mov-mov \
+# RUN:   -mattr=+fusion-xqci-mov-longlogical \
+# RUN:   | FileCheck %s
+
+# CHECK: movimm_alu_xqci:%bb.0
+# CHECK: Macro fuse: {{.*}}LUI - QC_E_ANDI
+---
+name: movimm_alu_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+    %1:gprnox0 = COPY $x10
+    %2:gprnox0 = LUI 1
+    %3:gprnox0 = XORI %1, 2
+    %4:gprnox0 = QC_E_ANDI %2, 3
+    $x10 = COPY %3
+    $x11 = COPY %4
+    PseudoRET
+...
+
+# CHECK: neg_movimm_alu_xqci:%bb.0
+# CHECK-NOT: Macro fuse: {{.*}}LUI - SUB
+name: neg_movimm_alu_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x0
+    %0:gpr = COPY $x0
+    %1:gprnox0 = ADDI %0, 1
+    %2:gprnox0 = MUL  %1, %1
+    %3:gprnox0 = LUI 5
+    %4:gprnox0 = SUB  %1, %3
+    $x11 = COPY %2
+    $x12 = COPY %4
+    PseudoRET
+...
+
+
+# CHECK: movimm_mul_xqci:%bb.0
+# CHECK: Macro fuse: {{.*}}QC_LI - MUL
+name: movimm_mul_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+    %1:gpr = COPY $x10
+    %2:gprnox0 = QC_LI 1
+    %3:gpr = XORI %1, 2
+    %4:gpr = MUL %2, %1
+    $x10 = COPY %3
+    $x11 = COPY %4
+    PseudoRET
+...
+
+# CHECK: movimm_ldst_xqci:%bb.0
+# CHECK: Macro fuse: {{.*}}QC_LI - QC_E_LW
+name: movimm_ldst_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+    %1:gpr = COPY $x10
+    %2:gprnox0 = QC_LI 100
+    %3:gpr = XORI %1, 2
+    %4:gpr = QC_E_LW %2, 0
+    $x10 = COPY %3
+    $x11 = COPY %4
+    PseudoRET
+...
+
+# CHECK: movimm_jump_xqci:%bb.0
+# CHECK: Macro fuse: {{.*}}QC_E_LI - JALR
+name: movimm_jump_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+    %1:gpr = COPY $x10
+    %2:gprnox0 = QC_E_LI 1
+    %3:gpr = XORI %1, 2
+    %4:gpr = JALR %2, 0
+    $x10 = COPY %3
+    $x11 = COPY %4
+    PseudoRET
+...
+
+# CHECK: movimm_alujump_xqci:%bb.0
+# CHECK: Macro fuse: {{.*}}QC_LI - QC_E_XORAI
+name: movimm_alujump_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+    %1:gpr = COPY $x10
+    %2:gprnox0 = QC_LI 1
+    %3:gpr = XORI %1, 2
+    %2:gprnox0 = QC_E_XORAI %2, 0
+    $x10 = COPY %3
+    $x11 = COPY %2
+    PseudoRET
+...
+
+# CHECK: movimm_mov_xqci:%bb.0
+# CHECK: Macro fuse: {{.*}}ADDI - ADDI
+name: movimm_mov_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+    %0:gpr = COPY $x10
+    %1:gpr = ADDI $x0, 5
+    %2:gpr = MUL  %0, %0
+    %3:gpr = ADDI %1, 0
+    %4:gpr = SUB  %2, %3
+    $x11 = COPY %3
+    $x12 = COPY %4
+    PseudoRET
+...
+
+
+# CHECK: neg_movimm_mov_xqci:%bb.0
+# CHECK-NOT: Macro fuse: {{.*}}ADDI - ADDI
+name: neg_movimm_mov_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x0
+    %0:gpr = COPY $x0
+    %1:gpr = ADDI %0, 5
+    %2:gpr = MUL  %1, %1
+    %3:gpr = ADDI %2, 0
+    %4:gpr = SUB  %3, %1
+    $x11 = COPY %2
+    $x12 = COPY %4
+    PseudoRET
+...
+
+# CHECK: mov_mov1_xqci:%bb.0
+# CHECK-NOT: Macro fuse: {{.*}}ADDI - ADDI
+name: mov_mov1_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11, $x12
+    %0:gpr = COPY $x10
+    %1:gpr = COPY $x11
+    %2:gpr = COPY $x12
+    %3:gpr = ADDI %0, 0
+    %4:gpr = XORI %1, 2
+    %5:gpr = ADDI %2, 0
+    $x10 = COPY %3
+    $x11 = COPY %4
+    $x12 = COPY %5
+    PseudoRET
+...
+
+# CHECK: mov_mov2_xqci:%bb.0
+# CHECK: Macro fuse: {{.*}}ADDI - ADDI
+name: mov_mov2_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+    %1:gpr = COPY $x10
+    %2:gpr = ADDI %1, 0
+    %3:gpr = XORI %1, 2
+    %4:gpr = ADDI %2, 0
+    $x10 = COPY %3
+    $x11 = COPY %4
+    PseudoRET
+...
+
+# CHECK: neg_mov_mov2_xqci:%bb.0
+# CHECK-NOT: Macro fuse: {{.*}}ADDI - QC_LI
+name: neg_mov_mov2_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+    %1:gpr = COPY $x10
+    %2:gpr = ADDI %1, 0
+    %3:gpr = XORI %1, 2
+    %4:gprnox0 = QC_LI 0
+    $x10 = COPY %3
+    $x11 = COPY %4
+    PseudoRET
+...
+
+# CHECK: mov_alu_xqci:%bb.0
+# CHECK: Macro fuse: {{.*}}ADDI - QC_E_XORAI
+name: mov_alu_xqci
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+    %0:gpr = COPY $x10
+    %2:gprnox0 = ADDI %0, 0
+    %3:gpr = XORI %0, 2
+    %2:gprnox0 = QC_E_XORAI %2, 3
+    $x10 = COPY %2
+    $x11 = COPY %3
+    PseudoRET
+...

>From a636ed1636b2ecc877bb18c8360fa944791b3a18 Mon Sep 17 00:00:00 2001
From: Pankaj Gode <pgode at qti.qualcomm.com>
Date: Mon, 20 Jul 2026 01:19:39 +0530
Subject: [PATCH 2/6] Fixed indent. Included ANDN. Reworked mov-mov fusion

---
 llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td | 94 +++++++++----------
 llvm/test/CodeGen/RISCV/features-info.ll      |  3 +-
 .../test/CodeGen/RISCV/macro-fusions-xqci.mir | 78 +--------------
 3 files changed, 51 insertions(+), 124 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
index 689ceb24df375..fc22da71edfa4 100644
--- a/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
+++ b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
@@ -14,8 +14,9 @@
 // instruction is the same as the destination register of the second
 // instruction.
 class FirstRdEqSecondRdFusion<string name, string fieldName, string desc,
-                   MCInstPredicate firstPred, MCInstPredicate secondPred,
-                   int secondOpIdx=0, int firstOpIdx=0>
+                              MCInstPredicate firstPred,
+                              MCInstPredicate secondPred,
+                              int secondOpIdx=0, int firstOpIdx=0>
   : Fusion<name, fieldName, desc,
            [
              SecondFusionPredicateWithMCInstPredicate<secondPred>,
@@ -24,17 +25,6 @@ class FirstRdEqSecondRdFusion<string name, string fieldName, string desc,
              TieReg<firstOpIdx, secondOpIdx>
            ]>;
 
-// Fuse two operations without tying any of their register operands.
-class XqciFusionNoTie<string name, string fieldName, string desc,
-                        MCInstPredicate firstPred, MCInstPredicate secondPred>
-  : Fusion<name, fieldName, desc,
-           [
-             SecondFusionPredicateWithMCInstPredicate<secondPred>,
-             WildcardTrue,
-             FirstFusionPredicateWithMCInstPredicate<firstPred>
-           ]>;
-
-defvar LoadAndMoveImmOp = [ADDI, LUI, QC_E_LI, QC_LI];
 defvar LoadImmOp = [LUI, QC_E_LI, QC_LI];
 // 48-bit load store
 defvar LongLoadStoreXqciOp = [QC_E_LB, QC_E_LBU, QC_E_LH, QC_E_LHU, QC_E_LW,
@@ -45,38 +35,60 @@ defvar LongLogicalXqciOp = [QC_E_XORAI, QC_E_ORAI, QC_E_ANDAI, QC_E_ADDAI];
 // Fuse load-immediate/move-immediate followed by arithmetic/logic.
 def TuneMOVIMMALUXqciFusion
   : SimpleFusion<"xqci-movimm-alu", "HasMOVIMMALUXqciFusion",
-                "Enable MOVIMM + ALU operations macrofusion",
-                CheckAny<[
-                  CheckOpcode<[AUIPC]>,
-                  CheckOpcode<LoadAndMoveImmOp>,
-                ]>,
-                CheckOpcode<[
-                  ADD, ADDI, SUB, MUL,
-                  AND, ANDI, OR, ORI, ORN, XOR, XORI, XNOR,
-                  QC_E_ANDI, QC_E_ORI, QC_E_XORI,
-                  SLLI, SRLI, SRAI, QC_LI, QC_E_LI,
-                  MAX, MAXU, MIN, MINU
-                ]>>;
+                 "Enable MOVIMM + ALU operations macrofusion",
+                 CheckAny<[
+                   CheckAll<[
+                     CheckOpcode<[ADDI]>,
+                     CheckRegOperand<1, X0>
+                   ]>,
+                   CheckOpcode<LoadImmOp>,
+                   CheckOpcode<[AUIPC]>,
+                 ]>,
+                 CheckOpcode<[
+                   ADD, ADDI, SUB, MUL,
+                   AND, ANDI, ANDN, OR, ORI, ORN, XOR, XORI, XNOR,
+                   QC_E_ANDI, QC_E_ORI, QC_E_XORI,
+                   SLLI, SRLI, SRAI, QC_LI, QC_E_LI,
+                   MAX, MAXU, MIN, MINU
+                 ]>>;
 
 // Fuse load-immediate/move-immediate followed by multiply.
 def TuneMOVIMMMULXqciFusion
   : SimpleFusion<"xqci-movimm-mul", "HasMOVIMMMULXqciFusion",
                  "Enable MOVIMM + multiply macrofusion",
-                 CheckOpcode<LoadAndMoveImmOp>,
+                 CheckAny<[
+                   CheckAll<[
+                     CheckOpcode<[ADDI]>,
+                     CheckRegOperand<1, X0>
+                   ]>,
+                   CheckOpcode<LoadImmOp>,
+                 ]>,
                  CheckOpcode<[MUL]>>;
 
 // Fuse load-immediate/move-immediate followed by long load/store.
 def TuneMOVIMMLoadStoreXqciFusion
   : SimpleFusion<"xqci-movimm-ldst", "HasMOVIMMLoadStoreXqciFusion",
                  "Enable MOVIMM + long Load/Store macrofusion",
-                 CheckOpcode<LoadAndMoveImmOp>,
+                 CheckAny<[
+                   CheckAll<[
+                     CheckOpcode<[ADDI]>,
+                     CheckRegOperand<1, X0>
+                   ]>,
+                   CheckOpcode<LoadImmOp>,
+                 ]>,
                  CheckOpcode<LongLoadStoreXqciOp>>;
 
 // Fuse load-immediate/move-immediate followed by a jump.
 def TuneMOVIMMJumpXqciFusion
   : SimpleFusion<"xqci-movimm-jump", "HasMOVIMMJumpXqciFusion",
                  "Enable MOVIMM + Jump macrofusion",
-                 CheckOpcode<LoadAndMoveImmOp>,
+                 CheckAny<[
+                   CheckAll<[
+                     CheckOpcode<[ADDI]>,
+                     CheckRegOperand<1, X0>
+                   ]>,
+                   CheckOpcode<LoadImmOp>,
+                 ]>,
                  CheckOpcode<[JALR]>>;
 
 // Fuse load-immediate/move-immediate followed by long logical operation.
@@ -86,14 +98,6 @@ def TuneMOVIMMLongLogicalXciFusion
   : FirstRdEqSecondRdFusion<"xqci-movimm-longlogical",
                  "HasMOVIMMLongLogicalXqciFusion",
                  "Enable MOVIMM + long logical operation macrofusion",
-                 CheckOpcode<LoadAndMoveImmOp>,
-                 CheckOpcode<LongLogicalXqciOp>
-                 >;
-
-// Fuse load-immediate/move-immediate followed by move.
-def TuneMOVIMMMovXqciFusion
-  : SimpleFusion<"xqci-movimm-mov", "HasMOVIMMMovXqciFusion",
-                 "Enable MOVIMM + Move macrofusion",
                  CheckAny<[
                    CheckAll<[
                      CheckOpcode<[ADDI]>,
@@ -101,21 +105,17 @@ def TuneMOVIMMMovXqciFusion
                    ]>,
                    CheckOpcode<LoadImmOp>,
                  ]>,
+                 CheckOpcode<LongLogicalXqciOp>>;
+
+// Fuse two adjacent moves.
+def TuneMOVIMMMovXqciFusion
+  : SimpleFusion<"xqci-mov-mov", "HasMovMovXqciFusion",
+                 "Enable Move + Move macrofusion",
                  CheckAny<[
                    CheckAll<[
                      CheckOpcode<[ADDI]>,
-                     CheckIsImmOperand<2>,
-                     CheckImmOperand<2, 0>
+                     CheckRegOperand<1, X0>
                    ]>,
-                   CheckOpcode<LoadImmOp>
-                 ]>
-                >;
-
-// Fuse two adjacent moves.
-def TuneMovMovXqciFusion
-  : XqciFusionNoTie<"xqci-mov-mov", "HasMovMovXqciFusion",
-                 "Enable move + move macrofusion",
-                 CheckAny<[
                    CheckAll<[
                      CheckOpcode<[ADDI]>,
                      CheckIsImmOperand<2>,
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 5523fa4ed8539..8aad82d0ab5b6 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -73,12 +73,11 @@
 ; CHECK-NEXT:   fusion-shifted-zextw             - Enable SLLI+SRLI to be fused when computing (shifted) word zero extension.
 ; CHECK-NEXT:   fusion-shxadd-load               - Enable SH(1|2|3)ADD(.UW) + load macrofusion.
 ; CHECK-NEXT:   fusion-xqci-mov-longlogical      - Enable MOV + long logical operation macrofusion.
-; CHECK-NEXT:   fusion-xqci-mov-mov              - Enable move + move macrofusion.
+; CHECK-NEXT:   fusion-xqci-mov-mov              - Enable Move + Move macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-alu           - Enable MOVIMM + ALU operations macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-jump          - Enable MOVIMM + Jump macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-ldst          - Enable MOVIMM + long Load/Store macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-longlogical   - Enable MOVIMM + long logical operation macrofusion.
-; CHECK-NEXT:   fusion-xqci-movimm-mov           - Enable MOVIMM + Move macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-mul           - Enable MOVIMM + multiply macrofusion.
 ; CHECK-NEXT:   fusion-zexth                     - Enable SLLI+SRLI to be fused to zero extension of halfword.
 ; CHECK-NEXT:   fusion-zextw                     - Enable SLLI+SRLI to be fused to zero extension of word.
diff --git a/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir b/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir
index c138093766f69..691e2e57e74e1 100644
--- a/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir
+++ b/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir
@@ -4,8 +4,7 @@
 # RUN:   -mattr=+xqcilia,+xqcili,+xqcilo,+zmmul,+fusion-xqci-movimm-alu \
 # RUN:   -mattr=+fusion-xqci-movimm-mul,+fusion-xqci-movimm-ldst \
 # RUN:   -mattr=+fusion-xqci-movimm-jump \
-# RUN:   -mattr=+fusion-xqci-movimm-longlogical,+fusion-xqci-movimm-mov \
-# RUN:   -mattr=+fusion-xqci-mov-mov \
+# RUN:   -mattr=+fusion-xqci-movimm-longlogical,+fusion-xqci-mov-mov \
 # RUN:   -mattr=+fusion-xqci-mov-longlogical \
 # RUN:   | FileCheck %s
 
@@ -26,24 +25,6 @@ body:             |
     PseudoRET
 ...
 
-# CHECK: neg_movimm_alu_xqci:%bb.0
-# CHECK-NOT: Macro fuse: {{.*}}LUI - SUB
-name: neg_movimm_alu_xqci
-tracksRegLiveness: true
-body:             |
-  bb.0.entry:
-    liveins: $x0
-    %0:gpr = COPY $x0
-    %1:gprnox0 = ADDI %0, 1
-    %2:gprnox0 = MUL  %1, %1
-    %3:gprnox0 = LUI 5
-    %4:gprnox0 = SUB  %1, %3
-    $x11 = COPY %2
-    $x12 = COPY %4
-    PseudoRET
-...
-
-
 # CHECK: movimm_mul_xqci:%bb.0
 # CHECK: Macro fuse: {{.*}}QC_LI - MUL
 name: movimm_mul_xqci
@@ -108,9 +89,9 @@ body:             |
     PseudoRET
 ...
 
-# CHECK: movimm_mov_xqci:%bb.0
+# CHECK: mov_mov1_xqci:%bb.0
 # CHECK: Macro fuse: {{.*}}ADDI - ADDI
-name: movimm_mov_xqci
+name: mov_mov1_xqci
 tracksRegLiveness: true
 body:             |
   bb.0.entry:
@@ -125,43 +106,6 @@ body:             |
     PseudoRET
 ...
 
-
-# CHECK: neg_movimm_mov_xqci:%bb.0
-# CHECK-NOT: Macro fuse: {{.*}}ADDI - ADDI
-name: neg_movimm_mov_xqci
-tracksRegLiveness: true
-body:             |
-  bb.0.entry:
-    liveins: $x0
-    %0:gpr = COPY $x0
-    %1:gpr = ADDI %0, 5
-    %2:gpr = MUL  %1, %1
-    %3:gpr = ADDI %2, 0
-    %4:gpr = SUB  %3, %1
-    $x11 = COPY %2
-    $x12 = COPY %4
-    PseudoRET
-...
-
-# CHECK: mov_mov1_xqci:%bb.0
-# CHECK-NOT: Macro fuse: {{.*}}ADDI - ADDI
-name: mov_mov1_xqci
-tracksRegLiveness: true
-body:             |
-  bb.0.entry:
-    liveins: $x10, $x11, $x12
-    %0:gpr = COPY $x10
-    %1:gpr = COPY $x11
-    %2:gpr = COPY $x12
-    %3:gpr = ADDI %0, 0
-    %4:gpr = XORI %1, 2
-    %5:gpr = ADDI %2, 0
-    $x10 = COPY %3
-    $x11 = COPY %4
-    $x12 = COPY %5
-    PseudoRET
-...
-
 # CHECK: mov_mov2_xqci:%bb.0
 # CHECK: Macro fuse: {{.*}}ADDI - ADDI
 name: mov_mov2_xqci
@@ -178,22 +122,6 @@ body:             |
     PseudoRET
 ...
 
-# CHECK: neg_mov_mov2_xqci:%bb.0
-# CHECK-NOT: Macro fuse: {{.*}}ADDI - QC_LI
-name: neg_mov_mov2_xqci
-tracksRegLiveness: true
-body:             |
-  bb.0.entry:
-    liveins: $x10
-    %1:gpr = COPY $x10
-    %2:gpr = ADDI %1, 0
-    %3:gpr = XORI %1, 2
-    %4:gprnox0 = QC_LI 0
-    $x10 = COPY %3
-    $x11 = COPY %4
-    PseudoRET
-...
-
 # CHECK: mov_alu_xqci:%bb.0
 # CHECK: Macro fuse: {{.*}}ADDI - QC_E_XORAI
 name: mov_alu_xqci

>From d81b96d4d3d7f1d6eed3ca8a5d2ba9063680eb3f Mon Sep 17 00:00:00 2001
From: Pankaj Gode <pgode at qti.qualcomm.com>
Date: Thu, 23 Jul 2026 17:59:42 +0530
Subject: [PATCH 3/6] Removed mov-mov fusion

---
 llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td | 26 --------------
 llvm/test/CodeGen/RISCV/features-info.ll      |  1 -
 .../test/CodeGen/RISCV/macro-fusions-xqci.mir | 35 +------------------
 3 files changed, 1 insertion(+), 61 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
index fc22da71edfa4..a06ca9bc4258e 100644
--- a/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
+++ b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
@@ -107,32 +107,6 @@ def TuneMOVIMMLongLogicalXciFusion
                  ]>,
                  CheckOpcode<LongLogicalXqciOp>>;
 
-// Fuse two adjacent moves.
-def TuneMOVIMMMovXqciFusion
-  : SimpleFusion<"xqci-mov-mov", "HasMovMovXqciFusion",
-                 "Enable Move + Move macrofusion",
-                 CheckAny<[
-                   CheckAll<[
-                     CheckOpcode<[ADDI]>,
-                     CheckRegOperand<1, X0>
-                   ]>,
-                   CheckAll<[
-                     CheckOpcode<[ADDI]>,
-                     CheckIsImmOperand<2>,
-                     CheckImmOperand<2, 0>
-                   ]>,
-                   CheckOpcode<LoadImmOp>,
-                 ]>,
-                 CheckAny<[
-                   CheckAll<[
-                     CheckOpcode<[ADDI]>,
-                     CheckIsImmOperand<2>,
-                     CheckImmOperand<2, 0>
-                   ]>,
-                   CheckOpcode<LoadImmOp>
-                 ]>
-                 >;
-
 // Fuse move followed by long logical operation.
 def TuneMovALUXqciFusion
   : FirstRdEqSecondRdFusion<"xqci-mov-longlogical", "HasMovALUXqciFusion",
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 8aad82d0ab5b6..5c546f542ec1b 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -73,7 +73,6 @@
 ; CHECK-NEXT:   fusion-shifted-zextw             - Enable SLLI+SRLI to be fused when computing (shifted) word zero extension.
 ; CHECK-NEXT:   fusion-shxadd-load               - Enable SH(1|2|3)ADD(.UW) + load macrofusion.
 ; CHECK-NEXT:   fusion-xqci-mov-longlogical      - Enable MOV + long logical operation macrofusion.
-; CHECK-NEXT:   fusion-xqci-mov-mov              - Enable Move + Move macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-alu           - Enable MOVIMM + ALU operations macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-jump          - Enable MOVIMM + Jump macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-ldst          - Enable MOVIMM + long Load/Store macrofusion.
diff --git a/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir b/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir
index 691e2e57e74e1..eaea240d283a4 100644
--- a/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir
+++ b/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir
@@ -4,7 +4,7 @@
 # RUN:   -mattr=+xqcilia,+xqcili,+xqcilo,+zmmul,+fusion-xqci-movimm-alu \
 # RUN:   -mattr=+fusion-xqci-movimm-mul,+fusion-xqci-movimm-ldst \
 # RUN:   -mattr=+fusion-xqci-movimm-jump \
-# RUN:   -mattr=+fusion-xqci-movimm-longlogical,+fusion-xqci-mov-mov \
+# RUN:   -mattr=+fusion-xqci-movimm-longlogical \
 # RUN:   -mattr=+fusion-xqci-mov-longlogical \
 # RUN:   | FileCheck %s
 
@@ -89,39 +89,6 @@ body:             |
     PseudoRET
 ...
 
-# CHECK: mov_mov1_xqci:%bb.0
-# CHECK: Macro fuse: {{.*}}ADDI - ADDI
-name: mov_mov1_xqci
-tracksRegLiveness: true
-body:             |
-  bb.0.entry:
-    liveins: $x10
-    %0:gpr = COPY $x10
-    %1:gpr = ADDI $x0, 5
-    %2:gpr = MUL  %0, %0
-    %3:gpr = ADDI %1, 0
-    %4:gpr = SUB  %2, %3
-    $x11 = COPY %3
-    $x12 = COPY %4
-    PseudoRET
-...
-
-# CHECK: mov_mov2_xqci:%bb.0
-# CHECK: Macro fuse: {{.*}}ADDI - ADDI
-name: mov_mov2_xqci
-tracksRegLiveness: true
-body:             |
-  bb.0.entry:
-    liveins: $x10
-    %1:gpr = COPY $x10
-    %2:gpr = ADDI %1, 0
-    %3:gpr = XORI %1, 2
-    %4:gpr = ADDI %2, 0
-    $x10 = COPY %3
-    $x11 = COPY %4
-    PseudoRET
-...
-
 # CHECK: mov_alu_xqci:%bb.0
 # CHECK: Macro fuse: {{.*}}ADDI - QC_E_XORAI
 name: mov_alu_xqci

>From 86d6598359c84803cdc2fb2efa6a6eded59d9d2c Mon Sep 17 00:00:00 2001
From: Pankaj Gode <pgode at qti.qualcomm.com>
Date: Sun, 26 Jul 2026 19:57:44 +0530
Subject: [PATCH 4/6] Reorganized fusions, where destination is same for fused
 instructions. Rewrote tests for these

---
 llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td | 78 ++++++++++---------
 llvm/test/CodeGen/RISCV/features-info.ll      |  4 +-
 .../test/CodeGen/RISCV/macro-fusions-xqci.mir | 31 ++++----
 3 files changed, 56 insertions(+), 57 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
index a06ca9bc4258e..8147f2232823a 100644
--- a/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
+++ b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
@@ -10,27 +10,12 @@
 // The following definitions describe macro fusion predicators applicable to
 // Xqci instructions.
 
-// Fuse two instructions where the destination register of the first
-// instruction is the same as the destination register of the second
-// instruction.
-class FirstRdEqSecondRdFusion<string name, string fieldName, string desc,
-                              MCInstPredicate firstPred,
-                              MCInstPredicate secondPred,
-                              int secondOpIdx=0, int firstOpIdx=0>
-  : Fusion<name, fieldName, desc,
-           [
-             SecondFusionPredicateWithMCInstPredicate<secondPred>,
-             WildcardTrue,
-             FirstFusionPredicateWithMCInstPredicate<firstPred>,
-             TieReg<firstOpIdx, secondOpIdx>
-           ]>;
-
 defvar LoadImmOp = [LUI, QC_E_LI, QC_LI];
 // 48-bit load store
 defvar LongLoadStoreXqciOp = [QC_E_LB, QC_E_LBU, QC_E_LH, QC_E_LHU, QC_E_LW,
                               QC_E_SB, QC_E_SH, QC_E_SW];
 // 48-bit logical operations
-defvar LongLogicalXqciOp = [QC_E_XORAI, QC_E_ORAI, QC_E_ANDAI, QC_E_ADDAI];
+defvar LongAccumXqciOp = [QC_E_XORAI, QC_E_ORAI, QC_E_ANDAI, QC_E_ADDAI];
 
 // Fuse load-immediate/move-immediate followed by arithmetic/logic.
 def TuneMOVIMMALUXqciFusion
@@ -91,30 +76,47 @@ def TuneMOVIMMJumpXqciFusion
                  ]>,
                  CheckOpcode<[JALR]>>;
 
-// Fuse load-immediate/move-immediate followed by long logical operation.
 // The destination register of the first operation is the same as the
 // destination register of the second operation.
-def TuneMOVIMMLongLogicalXciFusion
-  : FirstRdEqSecondRdFusion<"xqci-movimm-longlogical",
-                 "HasMOVIMMLongLogicalXqciFusion",
-                 "Enable MOVIMM + long logical operation macrofusion",
-                 CheckAny<[
-                   CheckAll<[
-                     CheckOpcode<[ADDI]>,
-                     CheckRegOperand<1, X0>
-                   ]>,
-                   CheckOpcode<LoadImmOp>,
+
+// Fuse load-immediate/move-immediate followed by long accumulate operation.
+def TuneMOVIMMLongAccumXciFusion
+  : Fusion<"xqci-movimm-longlogical", "HasMOVIMMLongAccumXqciFusion",
+           "Enable MOVIMM + long accumulate macrofusion",
+           [
+             SecondFusionPredicateWithMCInstPredicate<
+               CheckOpcode<LongAccumXqciOp>
+             >,
+             WildcardTrue,
+             FirstFusionPredicateWithMCInstPredicate<
+               CheckAny<[
+                 CheckAll<[
+                   CheckOpcode<[ADDI]>,
+                   CheckRegOperand<1, X0>
                  ]>,
-                 CheckOpcode<LongLogicalXqciOp>>;
+                 CheckOpcode<LoadImmOp>,
+               ]>
+             >,
+             TieReg<0, 0>,
+             TieReg<0, 1>,
+           ]>;
 
-// Fuse move followed by long logical operation.
+// Fuse move followed by long accumulate operation.
 def TuneMovALUXqciFusion
-  : FirstRdEqSecondRdFusion<"xqci-mov-longlogical", "HasMovALUXqciFusion",
-                            "Enable MOV + long logical operation macrofusion",
-                            CheckAll<[
-                              CheckOpcode<[ADDI]>,
-                              CheckIsImmOperand<2>,
-                              CheckImmOperand<2, 0>
-                            ]>,
-                            CheckOpcode<LongLogicalXqciOp>
-                            >;
+  : Fusion<"xqci-mov-longlogical", "HasMovALUXqciFusion",
+           "Enable MOV + long accumulate macrofusion",
+           [
+             SecondFusionPredicateWithMCInstPredicate<
+               CheckOpcode<LongAccumXqciOp>
+             >,
+             WildcardTrue,
+             FirstFusionPredicateWithMCInstPredicate<
+               CheckAll<[
+                 CheckOpcode<[ADDI]>,
+                 CheckIsImmOperand<2>,
+                 CheckImmOperand<2, 0>
+               ]>
+             >,
+             TieReg<0, 0>,
+             TieReg<0, 1>
+           ]>;
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 5c546f542ec1b..a6ac7487a816e 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -72,11 +72,11 @@
 ; CHECK-NEXT:   fusion-shift-bit-extract         - Enable SLLI+SRLI/SRAI macrofusion.
 ; CHECK-NEXT:   fusion-shifted-zextw             - Enable SLLI+SRLI to be fused when computing (shifted) word zero extension.
 ; CHECK-NEXT:   fusion-shxadd-load               - Enable SH(1|2|3)ADD(.UW) + load macrofusion.
-; CHECK-NEXT:   fusion-xqci-mov-longlogical      - Enable MOV + long logical operation macrofusion.
+; CHECK-NEXT:   fusion-xqci-mov-longlogical      - Enable MOV + long accumulate macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-alu           - Enable MOVIMM + ALU operations macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-jump          - Enable MOVIMM + Jump macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-ldst          - Enable MOVIMM + long Load/Store macrofusion.
-; CHECK-NEXT:   fusion-xqci-movimm-longlogical   - Enable MOVIMM + long logical operation macrofusion.
+; CHECK-NEXT:   fusion-xqci-movimm-longlogical   - Enable MOVIMM + long accumulate macrofusion.
 ; CHECK-NEXT:   fusion-xqci-movimm-mul           - Enable MOVIMM + multiply macrofusion.
 ; CHECK-NEXT:   fusion-zexth                     - Enable SLLI+SRLI to be fused to zero extension of halfword.
 ; CHECK-NEXT:   fusion-zextw                     - Enable SLLI+SRLI to be fused to zero extension of word.
diff --git a/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir b/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir
index eaea240d283a4..56e6284980d89 100644
--- a/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir
+++ b/llvm/test/CodeGen/RISCV/macro-fusions-xqci.mir
@@ -73,34 +73,31 @@ body:             |
     PseudoRET
 ...
 
-# CHECK: movimm_alujump_xqci:%bb.0
+# CHECK: movimm_longaccum_xqci:%bb.0
 # CHECK: Macro fuse: {{.*}}QC_LI - QC_E_XORAI
-name: movimm_alujump_xqci
+name: movimm_longaccum_xqci
 tracksRegLiveness: true
 body:             |
   bb.0.entry:
     liveins: $x10
-    %1:gpr = COPY $x10
-    %2:gprnox0 = QC_LI 1
-    %3:gpr = XORI %1, 2
-    %2:gprnox0 = QC_E_XORAI %2, 0
-    $x10 = COPY %3
-    $x11 = COPY %2
+    $x11 = QC_LI 1
+    $x12 = XORI $x10, 2
+    $x11 = QC_E_XORAI $x11, 3
+    $x13 = COPY $x12
+    $x10 = COPY $x11
     PseudoRET
 ...
 
-# CHECK: mov_alu_xqci:%bb.0
+# CHECK: mov_longaccum_xqci:%bb.0
 # CHECK: Macro fuse: {{.*}}ADDI - QC_E_XORAI
-name: mov_alu_xqci
+name: mov_longaccum_xqci
 tracksRegLiveness: true
 body:             |
   bb.0.entry:
     liveins: $x10
-    %0:gpr = COPY $x10
-    %2:gprnox0 = ADDI %0, 0
-    %3:gpr = XORI %0, 2
-    %2:gprnox0 = QC_E_XORAI %2, 3
-    $x10 = COPY %2
-    $x11 = COPY %3
-    PseudoRET
+    $x11 = ADDI $x10, 0
+    $x12 = XORI $x10, 2
+    $x11 = QC_E_XORAI $x11, 3
+    $x13 = COPY $x12
+    $x10 = COPY $x11
 ...

>From 1f18368a1cf4c4daa7058f9ac1e038fd6e80be88 Mon Sep 17 00:00:00 2001
From: Pankaj Gode <pgode at qti.qualcomm.com>
Date: Mon, 27 Jul 2026 15:22:50 +0530
Subject: [PATCH 5/6] Simplified 2 fusions to SimpleFusion

---
 llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td | 56 +++++++------------
 1 file changed, 21 insertions(+), 35 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
index 8147f2232823a..370fe573dfddb 100644
--- a/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
+++ b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
@@ -81,42 +81,28 @@ def TuneMOVIMMJumpXqciFusion
 
 // Fuse load-immediate/move-immediate followed by long accumulate operation.
 def TuneMOVIMMLongAccumXciFusion
-  : Fusion<"xqci-movimm-longlogical", "HasMOVIMMLongAccumXqciFusion",
-           "Enable MOVIMM + long accumulate macrofusion",
-           [
-             SecondFusionPredicateWithMCInstPredicate<
-               CheckOpcode<LongAccumXqciOp>
-             >,
-             WildcardTrue,
-             FirstFusionPredicateWithMCInstPredicate<
-               CheckAny<[
-                 CheckAll<[
-                   CheckOpcode<[ADDI]>,
-                   CheckRegOperand<1, X0>
+  : SimpleFusion<"xqci-movimm-longlogical", "HasMOVIMMLongAccumXqciFusion",
+                 "Enable MOVIMM + long accumulate macrofusion",
+                 CheckAny<[
+                   CheckAll<[
+                     CheckOpcode<[ADDI]>,
+                     CheckRegOperand<1, X0>
+                   ]>,
+                   CheckOpcode<LoadImmOp>,
                  ]>,
-                 CheckOpcode<LoadImmOp>,
-               ]>
-             >,
-             TieReg<0, 0>,
-             TieReg<0, 1>,
-           ]>;
+                 CheckOpcode<LongAccumXqciOp>,
+                 [],
+                 [TieReg<0, 0>]>;
 
 // Fuse move followed by long accumulate operation.
 def TuneMovALUXqciFusion
-  : Fusion<"xqci-mov-longlogical", "HasMovALUXqciFusion",
-           "Enable MOV + long accumulate macrofusion",
-           [
-             SecondFusionPredicateWithMCInstPredicate<
-               CheckOpcode<LongAccumXqciOp>
-             >,
-             WildcardTrue,
-             FirstFusionPredicateWithMCInstPredicate<
-               CheckAll<[
-                 CheckOpcode<[ADDI]>,
-                 CheckIsImmOperand<2>,
-                 CheckImmOperand<2, 0>
-               ]>
-             >,
-             TieReg<0, 0>,
-             TieReg<0, 1>
-           ]>;
+  : SimpleFusion<"xqci-mov-longlogical", "HasMovALUXqciFusion",
+                 "Enable MOV + long accumulate macrofusion",
+                 CheckAll<[
+                   CheckOpcode<[ADDI]>,
+                   CheckIsImmOperand<2>,
+                   CheckImmOperand<2, 0>
+                 ]>,
+                 CheckOpcode<LongAccumXqciOp>,
+                 [],
+                 [TieReg<0, 0>]>;

>From 336423777c835ad84351f38b55a2462d68774dce Mon Sep 17 00:00:00 2001
From: Pankaj Gode <pgode at qti.qualcomm.com>
Date: Tue, 28 Jul 2026 17:41:23 +0530
Subject: [PATCH 6/6] Included suggestion about epilog

---
 llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
index 370fe573dfddb..4a20457888c8f 100644
--- a/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
+++ b/llvm/lib/Target/RISCV/RISCVMacroFusionXQCI.td
@@ -91,8 +91,7 @@ def TuneMOVIMMLongAccumXciFusion
                    CheckOpcode<LoadImmOp>,
                  ]>,
                  CheckOpcode<LongAccumXqciOp>,
-                 [],
-                 [TieReg<0, 0>]>;
+                 epilog=[TieReg<0, 0>]>;
 
 // Fuse move followed by long accumulate operation.
 def TuneMovALUXqciFusion
@@ -104,5 +103,4 @@ def TuneMovALUXqciFusion
                    CheckImmOperand<2, 0>
                  ]>,
                  CheckOpcode<LongAccumXqciOp>,
-                 [],
-                 [TieReg<0, 0>]>;
+                 epilog=[TieReg<0, 0>]>;



More information about the llvm-commits mailing list