[llvm] 2d87319 - [GlobalISel] Rewrite some simple rules using MIR Patterns
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 22 00:09:59 PDT 2023
Author: pvanhout
Date: 2023-08-22T09:09:54+02:00
New Revision: 2d87319f06ef936233ba6aaa612da9586c427d68
URL: https://github.com/llvm/llvm-project/commit/2d87319f06ef936233ba6aaa612da9586c427d68
DIFF: https://github.com/llvm/llvm-project/commit/2d87319f06ef936233ba6aaa612da9586c427d68.diff
LOG: [GlobalISel] Rewrite some simple rules using MIR Patterns
Rewrites some simple rules that cause little to no codegen regressions as MIR patterns.
I may have missed some easy cases, but some other rules have intentionally been left as-is because bigger
changes are needed to make them work.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D157690
Added:
Modified:
llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
llvm/include/llvm/Target/GlobalISel/Combine.td
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir
llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-not-really-equiv-insts.mir
llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 0a9f0e931ae09a..6e331d4a68baa1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -386,12 +386,6 @@ class CombinerHelper {
void applyCombineExtOfExt(MachineInstr &MI,
std::tuple<Register, unsigned> &MatchInfo);
- /// Transform fabs(fabs(x)) to fabs(x).
- void applyCombineFAbsOfFAbs(MachineInstr &MI, Register &Src);
-
- /// Transform fabs(fneg(x)) to fabs(x).
- bool matchCombineFAbsOfFNeg(MachineInstr &MI, BuildFnTy &MatchInfo);
-
/// Transform trunc ([asz]ext x) to x or ([asz]ext x) or (trunc x).
bool matchCombineTruncOfExt(MachineInstr &MI,
std::pair<Register, unsigned> &MatchInfo);
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 5c3d382f210212..a9205efb4089ce 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -358,10 +358,10 @@ def select_same_val: GICombineRule<
// Fold (undef ? x : y) -> y
def select_undef_cmp: GICombineRule<
- (defs root:$root),
- (match (wip_match_opcode G_SELECT):$root,
- [{ return Helper.matchUndefSelectCmp(*${root}); }]),
- (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
+ (defs root:$dst),
+ (match (G_IMPLICIT_DEF $undef),
+ (G_SELECT $dst, $undef, $x, $y)),
+ (apply (COPY $dst, $y))
>;
// Fold (true ? x : y) -> x
@@ -400,28 +400,37 @@ def commute_constant_to_rhs : GICombineRule<
>;
// Fold x op 0 -> x
+def right_identity_zero_frags : GICombinePatFrag<
+ (outs root:$dst), (ins $x),
+ !foreach(op,
+ [G_SUB, G_ADD, G_OR, G_XOR, G_SHL, G_ASHR,
+ G_LSHR, G_PTR_ADD, G_ROTL, G_ROTR],
+ (pattern (op $dst, $x, 0)))>;
def right_identity_zero: GICombineRule<
- (defs root:$root),
- (match (wip_match_opcode G_SUB, G_ADD, G_OR, G_XOR, G_SHL, G_ASHR, G_LSHR,
- G_PTR_ADD, G_ROTL, G_ROTR):$root,
- [{ return Helper.matchConstantOp(${root}->getOperand(2), 0); }]),
- (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+ (defs root:$dst),
+ (match (right_identity_zero_frags $dst, $lhs)),
+ (apply (COPY $dst, $lhs))
>;
// Fold x op 1 -> x
def right_identity_one: GICombineRule<
- (defs root:$root),
- (match (wip_match_opcode G_MUL):$root,
- [{ return Helper.matchConstantOp(${root}->getOperand(2), 1); }]),
- (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+ (defs root:$dst),
+ (match (G_MUL $dst, $x, 1)),
+ (apply (COPY $dst, $x))
>;
// Fold (x op x) - > x
+def binop_same_val_frags : GICombinePatFrag<
+ (outs root:$dst), (ins $x),
+ [
+ (pattern (G_AND $dst, $x, $x)),
+ (pattern (G_OR $dst, $x, $x)),
+ ]
+>;
def binop_same_val: GICombineRule<
- (defs root:$root),
- (match (wip_match_opcode G_AND, G_OR):$root,
- [{ return Helper.matchBinOpSameVal(*${root}); }]),
- (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+ (defs root:$dst),
+ (match (binop_same_val_frags $dst, $src)),
+ (apply (COPY $dst, $src))
>;
// Fold (0 op x) - > 0
@@ -470,10 +479,9 @@ def div_rem_to_divrem : GICombineRule<
// Fold (x op 0) - > 0
def binop_right_to_zero: GICombineRule<
- (defs root:$root),
- (match (wip_match_opcode G_MUL):$root,
- [{ return Helper.matchOperandIsZero(*${root}, 2); }]),
- (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
+ (defs root:$dst),
+ (match (G_MUL $dst, $lhs, 0:$zero)),
+ (apply (COPY $dst, $zero))
>;
// Erase stores of undef values.
@@ -637,11 +645,10 @@ def not_cmp_fold : GICombineRule<
// Fold (fneg (fneg x)) -> x.
def fneg_fneg_fold: GICombineRule <
- (defs root:$dst, register_matchinfo:$matchinfo),
+ (defs root:$dst),
(match (G_FNEG $t, $src),
- (G_FNEG $dst, $t):$mi,
- [{ ${matchinfo} = ${src}.getReg(); return true; }]),
- (apply [{ Helper.replaceSingleDefInstWithReg(*${mi}, ${matchinfo}); }])
+ (G_FNEG $dst, $t)),
+ (apply (COPY $dst, $src))
>;
// Fold (unmerge(merge x, y, z)) -> z, y, z.
@@ -663,10 +670,10 @@ def merge_unmerge : GICombineRule<
// Fold (fabs (fneg x)) -> (fabs x).
def fabs_fneg_fold: GICombineRule <
- (defs root:$root, build_fn_matchinfo:$matchinfo),
- (match (wip_match_opcode G_FABS):$root,
- [{ return Helper.matchCombineFAbsOfFNeg(*${root}, ${matchinfo}); }]),
- (apply [{ Helper.applyBuildFnNoErase(*${root}, ${matchinfo}); }])>;
+ (defs root:$dst),
+ (match (G_FNEG $tmp, $x),
+ (G_FABS $dst, $tmp)),
+ (apply (G_FABS $dst, $x))>;
// Fold (unmerge cst) -> cst1, cst2, ...
def unmerge_cst_matchinfo : GIDefMatchData<"SmallVector<APInt, 8>">;
@@ -1036,12 +1043,16 @@ def combine_minmax_nan: GICombineRule<
// Transform (add x, (sub y, x)) -> y
// Transform (add (sub y, x), x) -> y
+def add_sub_reg_frags : GICombinePatFrag<
+ (outs root:$dst), (ins $src),
+ [
+ (pattern (G_ADD $dst, $x, $tmp), (G_SUB $tmp, $src, $x)),
+ (pattern (G_ADD $dst, $tmp, $x), (G_SUB $tmp, $src, $x))
+ ]>;
def add_sub_reg: GICombineRule <
- (defs root:$root, register_matchinfo:$matchinfo),
- (match (wip_match_opcode G_ADD):$root,
- [{ return Helper.matchAddSubSameReg(*${root}, ${matchinfo}); }]),
- (apply [{ Helper.replaceSingleDefInstWithReg(*${root},
- ${matchinfo}); }])>;
+ (defs root:$dst),
+ (match (add_sub_reg_frags $dst, $src)),
+ (apply (COPY $dst, $src))>;
def buildvector_identity_fold : GICombineRule<
(defs root:$build_vector, register_matchinfo:$matchinfo),
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index cc7fb3ee110913..4d62c7d997b77e 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -2260,23 +2260,6 @@ void CombinerHelper::applyCombineMulByNegativeOne(MachineInstr &MI) {
MI.eraseFromParent();
}
-bool CombinerHelper::matchCombineFAbsOfFNeg(MachineInstr &MI,
- BuildFnTy &MatchInfo) {
- assert(MI.getOpcode() == TargetOpcode::G_FABS && "Expected a G_FABS");
- Register Src = MI.getOperand(1).getReg();
- Register NegSrc;
-
- if (!mi_match(Src, MRI, m_GFNeg(m_Reg(NegSrc))))
- return false;
-
- MatchInfo = [=, &MI](MachineIRBuilder &B) {
- Observer.changingInstr(MI);
- MI.getOperand(1).setReg(NegSrc);
- Observer.changedInstr(MI);
- };
- return true;
-}
-
bool CombinerHelper::matchCombineTruncOfExt(
MachineInstr &MI, std::pair<Register, unsigned> &MatchInfo) {
assert(MI.getOpcode() == TargetOpcode::G_TRUNC && "Expected a G_TRUNC");
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
index 0471da4e05a56b..81d38a5b080470 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
@@ -27,7 +27,7 @@ body: |
; CHECK-LABEL: name: test_combine_select_undef_res0_res1
; CHECK: liveins: $x0, $x1
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x1
; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
%0:_(s64) = COPY $x0
%1:_(s64) = COPY $x1
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir
index c07e25f716486c..ac0d561c99a1b3 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir
@@ -27,7 +27,7 @@ body: |
; CHECK-LABEL: name: test_combine_select_undef_res0_res1
; CHECK: liveins: $x0, $x1
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x1
; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
%0:_(s64) = COPY $x0
%1:_(s64) = COPY $x1
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-not-really-equiv-insts.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-not-really-equiv-insts.mir
index 76cfad48e16fe8..71eae18d4144ed 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-not-really-equiv-insts.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-not-really-equiv-insts.mir
@@ -46,11 +46,14 @@ body: |
bb.0:
; %load1 || %load2 == %load1 is fine here, because the loads are invariant.
+ ; TODO: Loads need to be CSE'd for this to work.
; CHECK-LABEL: name: invariant_loads
; CHECK: %ptr:_(p0) = G_GLOBAL_VALUE @g
+ ; CHECK-NEXT: %load1:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load (s32) from @g)
; CHECK-NEXT: %load2:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load (s32) from @g)
- ; CHECK-NEXT: G_STORE %load2(s32), %ptr(p0) :: (store (s32) into @g)
+ ; CHECK-NEXT: %or:_(s32) = G_OR %load2, %load1
+ ; CHECK-NEXT: G_STORE %or(s32), %ptr(p0) :: (store (s32) into @g)
; CHECK-NEXT: RET_ReallyLR
%ptr:_(p0) = G_GLOBAL_VALUE @g
%load1:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load (s32) from @g)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir
index 0681a3f33a6030..e665e8c841eceb 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir
@@ -63,7 +63,6 @@ body: |
...
-# FIXME: Probably should be able to replace this.
---
name: mul_0_cant_replace
tracksRegLiveness: true
@@ -75,9 +74,8 @@ body: |
; CHECK-LABEL: name: mul_0_cant_replace
; CHECK: liveins: $w0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $w0
; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
- ; CHECK-NEXT: %op:gpr(s32) = G_MUL %x, %cst
+ ; CHECK-NEXT: %op:gpr(s32) = COPY %cst(s32)
; CHECK-NEXT: $w0 = COPY %op(s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%x:_(s32) = COPY $w0
@@ -312,7 +310,9 @@ body: |
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: %zero:_(s8) = G_CONSTANT i8 0
; CHECK-NEXT: %zext_zero:_(s64) = G_ZEXT %zero(s8)
- ; CHECK-NEXT: $x0 = COPY %zext_zero(s64)
+ ; CHECK-NEXT: %c:_(s64) = G_CONSTANT i64 72340172838076673
+ ; CHECK-NEXT: %mul:_(s64) = G_MUL %zext_zero, %c
+ ; CHECK-NEXT: $x0 = COPY %mul(s64)
; CHECK-NEXT: RET_ReallyLR implicit $x0
%zero:_(s8) = G_CONSTANT i8 0
%zext_zero:_(s64) = G_ZEXT %zero(s8)
More information about the llvm-commits
mailing list