[llvm] b7fcf66 - [GISel] Add new combines for G_ADD
Michael Kitzan via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 6 11:20:01 PDT 2022
Author: Michael Kitzan
Date: 2022-06-06T11:19:45-07:00
New Revision: b7fcf6632fe30cdb89493b6c6b59cf1741a00dfc
URL: https://github.com/llvm/llvm-project/commit/b7fcf6632fe30cdb89493b6c6b59cf1741a00dfc
DIFF: https://github.com/llvm/llvm-project/commit/b7fcf6632fe30cdb89493b6c6b59cf1741a00dfc.diff
LOG: [GISel] Add new combines for G_ADD
Patch adds new GICombineRules for G_ADD:
G_ADD(x, G_SUB(y, x)) -> y
G_ADD(G_SUB(y, x), x) -> y
Patch additionally adds new combine tests for AArch64 target for
these new rules.
Reviewed by: paquette
Differential Revision: https://reviews.llvm.org/D87936
Added:
llvm/test/CodeGen/AArch64/GlobalISel/combine-add.mir
Modified:
llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
llvm/include/llvm/Target/GlobalISel/Combine.td
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index e2c503a94e00..73edc3c37970 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -736,6 +736,10 @@ class CombinerHelper {
bool matchCombineFMinMaxNaN(MachineInstr &MI, unsigned &Info);
+ /// Transform G_ADD(x, G_SUB(y, x)) to y.
+ /// Transform G_ADD(G_SUB(y, x), x) to y.
+ bool matchAddSubSameReg(MachineInstr &MI, Register &Src);
+
private:
/// Given a non-indexed load or store instruction \p MI, find an offset that
/// can be usefully and legally folded into it as a post-indexing operation.
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 38c5abb074cc..89f08d200021 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -891,13 +891,21 @@ def combine_fsub_fpext_fneg_fmul_to_fmad_or_fma: GICombineRule<
*${root}, ${info}); }]),
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])>;
-def combine_minmax_nan_matchinfo: GIDefMatchData<"unsigned">;
def combine_minmax_nan: GICombineRule<
- (defs root:$root, combine_minmax_nan_matchinfo:$info),
+ (defs root:$root, unsigned_matchinfo:$info),
(match (wip_match_opcode G_FMINNUM, G_FMAXNUM, G_FMINIMUM, G_FMAXIMUM):$root,
[{ return Helper.matchCombineFMinMaxNaN(*${root}, ${info}); }]),
(apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, ${info}); }])>;
+// Transform (add x, (sub y, x)) -> y
+// Transform (add (sub y, x), x) -> y
+def add_sub_reg: GICombineRule <
+ (defs root:$root, register_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_ADD):$root,
+ [{ return Helper.matchAddSubSameReg(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithReg(*${root},
+ ${matchinfo}); }])>;
+
// FIXME: These should use the custom predicate feature once it lands.
def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
undef_to_negative_one,
@@ -913,7 +921,8 @@ def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
binop_same_val, binop_left_to_zero,
binop_right_to_zero, p2i_to_i2p,
i2p_to_p2i, anyext_trunc_fold,
- fneg_fneg_fold, right_identity_one]>;
+ fneg_fneg_fold, right_identity_one,
+ add_sub_reg]>;
def const_combines : GICombineGroup<[constant_fp_op, const_ptradd_to_i2p,
overlapping_and, mulo_by_2, mulo_by_0,
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index b1798d681fa3..d742b8070b01 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -5633,6 +5633,22 @@ bool CombinerHelper::matchCombineFMinMaxNaN(MachineInstr &MI,
return MatchNaN(1) || MatchNaN(2);
}
+bool CombinerHelper::matchAddSubSameReg(MachineInstr &MI, Register &Src) {
+ assert(MI.getOpcode() == TargetOpcode::G_ADD && "Expected a G_ADD");
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+
+ // Helper lambda to check for opportunities for
+ // A + (B - A) -> B
+ // (B - A) + A -> B
+ auto CheckFold = [&](Register MaybeSub, Register MaybeSameReg) {
+ Register Reg;
+ return mi_match(MaybeSub, MRI, m_GSub(m_Reg(Src), m_Reg(Reg))) &&
+ Reg == MaybeSameReg;
+ };
+ return CheckFold(LHS, RHS) || CheckFold(RHS, LHS);
+}
+
bool CombinerHelper::tryCombine(MachineInstr &MI) {
if (tryCombineCopy(MI))
return true;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-add.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-add.mir
new file mode 100644
index 000000000000..9a81a5fc176a
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-add.mir
@@ -0,0 +1,129 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s
+
+---
+name: add_lhs_sub_reg
+alignment: 4
+tracksRegLiveness: true
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: add_lhs_sub_reg
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: $w0 = COPY [[COPY]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w1
+ %2:_(s32) = G_SUB %0, %1
+ %3:_(s32) = G_ADD %2, %1
+ $w0 = COPY %3
+...
+---
+name: add_lhs_sub_reg_wide
+alignment: 4
+tracksRegLiveness: true
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: add_lhs_sub_reg_wide
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $q0
+ ; CHECK-NEXT: $q0 = COPY [[COPY]](s128)
+ %0:_(s128) = COPY $q0
+ %1:_(s128) = COPY $q1
+ %2:_(s128) = G_SUB %0, %1
+ %3:_(s128) = G_ADD %2, %1
+ $q0 = COPY %3
+...
+---
+name: add_lhs_sub_reg_vec
+alignment: 4
+tracksRegLiveness: true
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $x0, $x1
+ ; CHECK-LABEL: name: add_lhs_sub_reg_vec
+ ; CHECK: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $x0
+ ; CHECK-NEXT: $x0 = COPY [[COPY]](<4 x s16>)
+ %0:_(<4 x s16>) = COPY $x0
+ %1:_(<4 x s16>) = COPY $x1
+ %2:_(<4 x s16>) = G_SUB %0, %1
+ %3:_(<4 x s16>) = G_ADD %2, %1
+ $x0 = COPY %3
+...
+---
+name: add_rhs_sub_reg
+alignment: 4
+tracksRegLiveness: true
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: add_rhs_sub_reg
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: $w0 = COPY [[COPY]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w1
+ %2:_(s32) = G_SUB %0, %1
+ %3:_(s32) = G_ADD %1, %2
+ $w0 = COPY %3
+...
+---
+name: add_rhs_sub_reg_wide
+alignment: 4
+tracksRegLiveness: true
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: add_rhs_sub_reg_wide
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $q0
+ ; CHECK-NEXT: $q0 = COPY [[COPY]](s128)
+ %0:_(s128) = COPY $q0
+ %1:_(s128) = COPY $q1
+ %2:_(s128) = G_SUB %0, %1
+ %3:_(s128) = G_ADD %1, %2
+ $q0 = COPY %3
+...
+---
+name: add_rhs_sub_reg_vec
+alignment: 4
+tracksRegLiveness: true
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $x0, $x1
+ ; CHECK-LABEL: name: add_rhs_sub_reg_vec
+ ; CHECK: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $x0
+ ; CHECK-NEXT: $x0 = COPY [[COPY]](<4 x s16>)
+ %0:_(<4 x s16>) = COPY $x0
+ %1:_(<4 x s16>) = COPY $x1
+ %2:_(<4 x s16>) = G_SUB %0, %1
+ %3:_(<4 x s16>) = G_ADD %1, %2
+ $x0 = COPY %3
+...
More information about the llvm-commits
mailing list