[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