[llvm] 1cdffa3 - [MachineCombiner][RISCV] Support inverse instructions reassociation
Anton Sidorenko via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 15 05:48:59 PST 2022
Author: Anton Sidorenko
Date: 2022-12-15T16:48:30+03:00
New Revision: 1cdffa359a3344f966ed309de17af17f8abfbe4d
URL: https://github.com/llvm/llvm-project/commit/1cdffa359a3344f966ed309de17af17f8abfbe4d
DIFF: https://github.com/llvm/llvm-project/commit/1cdffa359a3344f966ed309de17af17f8abfbe4d.diff
LOG: [MachineCombiner][RISCV] Support inverse instructions reassociation
This patch adds reassociation of FADD/FSUB instruction pairs.
Differential Revision: https://reviews.llvm.org/D138660
Added:
Modified:
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
llvm/lib/Target/RISCV/RISCVInstrInfo.h
llvm/test/CodeGen/RISCV/machine-combiner.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index acee7a994707..92e8fca53c12 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -1203,8 +1203,12 @@ bool RISCVInstrInfo::hasReassociableSibling(const MachineInstr &Inst,
bool RISCVInstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst,
bool Invert) const {
unsigned Opc = Inst.getOpcode();
- if (Invert)
- return false;
+ if (Invert) {
+ auto InverseOpcode = getInverseOpcode(Opc);
+ if (!InverseOpcode)
+ return false;
+ Opc = *InverseOpcode;
+ }
if (isFADD(Opc) || isFMUL(Opc))
return Inst.getFlag(MachineInstr::MIFlag::FmReassoc) &&
@@ -1212,6 +1216,26 @@ bool RISCVInstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst,
return false;
}
+std::optional<unsigned>
+RISCVInstrInfo::getInverseOpcode(unsigned Opcode) const {
+ switch (Opcode) {
+ default:
+ return std::nullopt;
+ case RISCV::FADD_H:
+ return RISCV::FSUB_H;
+ case RISCV::FADD_S:
+ return RISCV::FSUB_S;
+ case RISCV::FADD_D:
+ return RISCV::FSUB_D;
+ case RISCV::FSUB_H:
+ return RISCV::FADD_H;
+ case RISCV::FSUB_S:
+ return RISCV::FADD_S;
+ case RISCV::FSUB_D:
+ return RISCV::FADD_D;
+ }
+}
+
static bool canCombineFPFusedMultiply(const MachineInstr &Root,
const MachineOperand &MO,
bool DoRegPressureReduce) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
index eac190f7c99d..ceddbacf61e0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -208,6 +208,8 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
bool isAssociativeAndCommutative(const MachineInstr &Inst,
bool Invert) const override;
+ std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override;
+
protected:
const RISCVSubtarget &STI;
};
diff --git a/llvm/test/CodeGen/RISCV/machine-combiner.ll b/llvm/test/CodeGen/RISCV/machine-combiner.ll
index 8c5db3479f30..55551044cd7d 100644
--- a/llvm/test/CodeGen/RISCV/machine-combiner.ll
+++ b/llvm/test/CodeGen/RISCV/machine-combiner.ll
@@ -129,18 +129,18 @@ define double @test_reassoc_big1(double %a0, double %a1, double %a2, double %a3,
define double @test_reassoc_big2(double %a0, double %a1, i32 %a2, double %a3, i32 %a4, double %a5) {
; CHECK-LABEL: test_reassoc_big2:
; CHECK: # %bb.0:
-; CHECK-NEXT: fcvt.d.w ft0, a0
-; CHECK-NEXT: fcvt.d.w ft1, a1
-; CHECK-NEXT: fmul.d ft0, fa2, ft0
-; CHECK-NEXT: fmul.d ft1, ft1, fa1
-; CHECK-NEXT: fadd.d ft2, fa0, fa1
-; CHECK-NEXT: fadd.d ft3, fa2, fa1
-; CHECK-NEXT: fmul.d ft0, ft1, ft0
-; CHECK-NEXT: fadd.d ft1, fa2, ft2
-; CHECK-NEXT: fmul.d ft2, fa0, ft3
-; CHECK-NEXT: fsub.d ft1, fa3, ft1
-; CHECK-NEXT: fmul.d ft0, ft0, ft2
-; CHECK-NEXT: fmul.d fa0, ft1, ft0
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fsub.d ft1, fa3, fa2
+; CHECK-NEXT: fadd.d ft2, fa2, fa1
+; CHECK-NEXT: fcvt.d.w ft3, a0
+; CHECK-NEXT: fcvt.d.w ft4, a1
+; CHECK-NEXT: fmul.d ft3, fa2, ft3
+; CHECK-NEXT: fmul.d ft4, ft4, fa1
+; CHECK-NEXT: fsub.d ft0, ft1, ft0
+; CHECK-NEXT: fmul.d ft1, fa0, ft2
+; CHECK-NEXT: fmul.d ft2, ft4, ft3
+; CHECK-NEXT: fmul.d ft0, ft0, ft1
+; CHECK-NEXT: fmul.d fa0, ft0, ft2
; CHECK-NEXT: ret
%cvt1 = sitofp i32 %a2 to double
%cvt2 = sitofp i32 %a4 to double
@@ -237,3 +237,159 @@ define double @test_fnmsub(double %a0, double %a1, double %a2) {
%t2 = fdiv double %t1, %t0
ret double %t2
}
+
+define double @test_reassoc_fsub1(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub1:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fsub.d ft1, fa2, fa3
+; CHECK-NEXT: fadd.d fa0, ft0, ft1
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fadd nsz reassoc double %t0, %a2
+ %t2 = fsub nsz reassoc double %t1, %a3
+ ret double %t2
+}
+
+define double @test_reassoc_fsub2(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fsub.d ft1, fa2, fa3
+; CHECK-NEXT: fsub.d fa0, ft0, ft1
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fsub nsz reassoc double %t0, %a2
+ %t2 = fadd nsz reassoc double %t1, %a3
+ ret double %t2
+}
+
+define double @test_reassoc_fsub3(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub3:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fadd.d ft1, fa2, fa3
+; CHECK-NEXT: fsub.d fa0, ft0, ft1
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fsub nsz reassoc double %t0, %a2
+ %t2 = fsub nsz reassoc double %t1, %a3
+ ret double %t2
+}
+
+define double @test_reassoc_fsub4(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub4:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fsub.d ft1, fa2, fa3
+; CHECK-NEXT: fadd.d fa0, ft1, ft0
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fadd nsz reassoc double %a2, %t0
+ %t2 = fsub nsz reassoc double %t1, %a3
+ ret double %t2
+}
+
+define double @test_reassoc_fsub5(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub5:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fadd.d ft1, fa2, fa3
+; CHECK-NEXT: fsub.d fa0, ft1, ft0
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fsub nsz reassoc double %a2, %t0
+ %t2 = fadd nsz reassoc double %t1, %a3
+ ret double %t2
+}
+
+define double @test_reassoc_fsub6(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub6:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fsub.d ft1, fa2, fa3
+; CHECK-NEXT: fsub.d fa0, ft1, ft0
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fsub nsz reassoc double %a2, %t0
+ %t2 = fsub nsz reassoc double %t1, %a3
+ ret double %t2
+}
+
+define double @test_reassoc_fsub7(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub7:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fsub.d ft1, fa3, fa2
+; CHECK-NEXT: fsub.d fa0, ft1, ft0
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fadd nsz reassoc double %t0, %a2
+ %t2 = fsub nsz reassoc double %a3, %t1
+ ret double %t2
+}
+
+define double @test_reassoc_fsub8(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fsub.d ft1, fa3, fa2
+; CHECK-NEXT: fadd.d fa0, ft1, ft0
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fsub nsz reassoc double %t0, %a2
+ %t2 = fadd nsz reassoc double %a3, %t1
+ ret double %t2
+}
+
+define double @test_reassoc_fsub9(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub9:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fadd.d ft1, fa3, fa2
+; CHECK-NEXT: fsub.d fa0, ft1, ft0
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fsub nsz reassoc double %t0, %a2
+ %t2 = fsub nsz reassoc double %a3, %t1
+ ret double %t2
+}
+
+define double @test_reassoc_fsub10(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub10:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fsub.d ft1, fa3, fa2
+; CHECK-NEXT: fsub.d fa0, ft1, ft0
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fadd nsz reassoc double %a2, %t0
+ %t2 = fsub nsz reassoc double %a3, %t1
+ ret double %t2
+}
+
+define double @test_reassoc_fsub11(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub11:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fadd.d ft1, fa3, fa2
+; CHECK-NEXT: fsub.d fa0, ft1, ft0
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fsub nsz reassoc double %a2, %t0
+ %t2 = fadd nsz reassoc double %a3, %t1
+ ret double %t2
+}
+
+define double @test_reassoc_fsub12(double %a0, double %a1, double %a2, double %a3) {
+; CHECK-LABEL: test_reassoc_fsub12:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fadd.d ft0, fa0, fa1
+; CHECK-NEXT: fsub.d ft1, fa3, fa2
+; CHECK-NEXT: fadd.d fa0, ft1, ft0
+; CHECK-NEXT: ret
+ %t0 = fadd nsz reassoc double %a0, %a1
+ %t1 = fsub nsz reassoc double %a2, %t0
+ %t2 = fsub nsz reassoc double %a3, %t1
+ ret double %t2
+}
More information about the llvm-commits
mailing list