[llvm] dec3410 - [GlobalISel] Add combine for merge(unmerge) and use AArch64 postlegal-combiner.

Amara Emerson via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 26 10:37:39 PDT 2021


Author: Amara Emerson
Date: 2021-07-26T10:37:31-07:00
New Revision: dec34104bfa505f39bb81d24c9ca064a4a03c88a

URL: https://github.com/llvm/llvm-project/commit/dec34104bfa505f39bb81d24c9ca064a4a03c88a
DIFF: https://github.com/llvm/llvm-project/commit/dec34104bfa505f39bb81d24c9ca064a4a03c88a.diff

LOG: [GlobalISel] Add combine for merge(unmerge) and use AArch64 postlegal-combiner.

Differential Revision: https://reviews.llvm.org/D106761

Added: 
    llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir

Modified: 
    llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
    llvm/include/llvm/Target/GlobalISel/Combine.td
    llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
    llvm/lib/Target/AArch64/AArch64Combine.td

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 775563ab2d47f..9005a6eb62ab2 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -264,6 +264,9 @@ class CombinerHelper {
   void applyCombineShlOfExtend(MachineInstr &MI,
                                const RegisterImmPair &MatchData);
 
+  /// Fold away a merge of an unmerge of the corresponding values.
+  bool matchCombineMergeUnmerge(MachineInstr &MI, Register &MatchInfo);
+
   /// Reduce a shift by a constant to an unmerge and a shift on a half sized
   /// type. This will not produce a shift smaller than \p TargetShiftSize.
   bool matchCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftSize,

diff  --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 842a382e4c902..9704091701497 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -490,6 +490,14 @@ def unmerge_merge : GICombineRule<
   (apply [{ Helper.applyCombineUnmergeMergeToPlainValues(*${d}, ${info}); }])
 >;
 
+// Fold merge(unmerge).
+def merge_unmerge : GICombineRule<
+  (defs root:$d, register_matchinfo:$matchinfo),
+  (match (wip_match_opcode G_MERGE_VALUES):$d,
+  [{ return Helper.matchCombineMergeUnmerge(*${d}, ${matchinfo}); }]),
+  (apply [{ Helper.replaceSingleDefInstWithReg(*${d}, ${matchinfo}); }])
+>;
+
 // Fold (fabs (fabs x)) -> (fabs x).
 def fabs_fabs_fold: GICombineRule<
   (defs root:$root, register_matchinfo:$matchinfo),
@@ -694,7 +702,7 @@ def all_combines : GICombineGroup<[trivial_combines, insert_vec_elt_combines,
     known_bits_simplifications, ext_ext_fold,
     not_cmp_fold, opt_brcond_by_inverting_cond,
     unmerge_merge, fabs_fabs_fold, unmerge_cst, unmerge_dead_to_trunc,
-    unmerge_zext_to_zext, trunc_ext_fold, trunc_shl,
+    unmerge_zext_to_zext, merge_unmerge, trunc_ext_fold, trunc_shl,
     const_combines, xor_of_and_with_same_reg, ptr_add_with_zero,
     shift_immed_chain, shift_of_shifted_logic_chain, load_or_combine,
     div_rem_to_divrem, funnel_shift_combines, form_bitfield_extract]>;

diff  --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 590a65aa14fc7..0e07bc43ebd4c 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -2014,6 +2014,25 @@ void CombinerHelper::applyCombineShlOfExtend(MachineInstr &MI,
   MI.eraseFromParent();
 }
 
+bool CombinerHelper::matchCombineMergeUnmerge(MachineInstr &MI,
+                                              Register &MatchInfo) {
+  GMerge &Merge = cast<GMerge>(MI);
+  SmallVector<Register, 16> MergedValues;
+  for (unsigned I = 0; I < Merge.getNumSources(); ++I)
+    MergedValues.emplace_back(Merge.getSourceReg(I));
+
+  auto *Unmerge = getOpcodeDef<GUnmerge>(MergedValues[0], MRI);
+  if (!Unmerge || Unmerge->getNumDefs() != Merge.getNumSources())
+    return false;
+
+  for (unsigned I = 0; I < MergedValues.size(); ++I)
+    if (MergedValues[I] != Unmerge->getReg(I))
+      return false;
+
+  MatchInfo = Unmerge->getSourceReg();
+  return true;
+}
+
 static Register peekThroughBitcast(Register Reg,
                                    const MachineRegisterInfo &MRI) {
   while (mi_match(Reg, MRI, m_GBitcast(m_Reg(Reg))))

diff  --git a/llvm/lib/Target/AArch64/AArch64Combine.td b/llvm/lib/Target/AArch64/AArch64Combine.td
index 62493ae4c0568..5e2b5b66a95bc 100644
--- a/llvm/lib/Target/AArch64/AArch64Combine.td
+++ b/llvm/lib/Target/AArch64/AArch64Combine.td
@@ -203,6 +203,6 @@ def AArch64PostLegalizerCombinerHelper
                         extractvecelt_pairwise_add, redundant_or,
                         mul_const, redundant_sext_inreg,
                         form_bitfield_extract, rotate_out_of_range,
-                        icmp_to_true_false_known_bits]> {
+                        icmp_to_true_false_known_bits, merge_unmerge]> {
   let DisableRuleOption = "aarch64postlegalizercombiner-disable-rule";
 }

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir
new file mode 100644
index 0000000000000..83b6d02e3a505
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir
@@ -0,0 +1,70 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple aarch64 -run-pass=aarch64-postlegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name:            merge_unmerge
+alignment:       4
+legalized:       true
+liveins:
+  - { reg: '$w0' }
+body:             |
+  bb.1.entry:
+    liveins: $x0
+
+    ; CHECK-LABEL: name: merge_unmerge
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+    ; CHECK: $x0 = COPY [[COPY]](s64)
+    ; CHECK: RET_ReallyLR implicit $x0
+    %0:_(s64) = COPY $x0
+    %a:_(s32), %b:_(s32) = G_UNMERGE_VALUES %0
+    %merge:_(s64) = G_MERGE_VALUES %a, %b
+    $x0 = COPY %merge(s64)
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:            merge_unmerge_mismatched_order
+alignment:       4
+legalized:       true
+liveins:
+  - { reg: '$w0' }
+body:             |
+  bb.1.entry:
+    liveins: $x0
+
+    ; CHECK-LABEL: name: merge_unmerge_mismatched_order
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+    ; CHECK: %b:_(s32), %a:_(s32) = G_UNMERGE_VALUES [[COPY]](s64)
+    ; CHECK: %merge:_(s64) = G_MERGE_VALUES %a(s32), %b(s32)
+    ; CHECK: $x0 = COPY %merge(s64)
+    ; CHECK: RET_ReallyLR implicit $x0
+    %0:_(s64) = COPY $x0
+    %b:_(s32), %a:_(s32) = G_UNMERGE_VALUES %0
+    %merge:_(s64) = G_MERGE_VALUES %a, %b
+    $x0 = COPY %merge(s64)
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:            merge_unmerge_mismatched_num_defs
+alignment:       4
+legalized:       true
+liveins:
+  - { reg: '$w0' }
+body:             |
+  bb.1.entry:
+    liveins: $q0
+
+    ; CHECK-LABEL: name: merge_unmerge_mismatched_num_defs
+    ; CHECK: [[COPY:%[0-9]+]]:_(s128) = COPY $q0
+    ; CHECK: %a:_(s32), %b:_(s32), %c:_(s32), %d:_(s32) = G_UNMERGE_VALUES [[COPY]](s128)
+    ; CHECK: %merge:_(s64) = G_MERGE_VALUES %a(s32), %b(s32)
+    ; CHECK: $x0 = COPY %merge(s64)
+    ; CHECK: RET_ReallyLR implicit $x0
+    %0:_(s128) = COPY $q0
+    %a:_(s32), %b:_(s32), %c:_(s32), %d:_(s32) = G_UNMERGE_VALUES %0
+    %merge:_(s64) = G_MERGE_VALUES %a, %b
+    $x0 = COPY %merge(s64)
+    RET_ReallyLR implicit $x0
+
+...


        


More information about the llvm-commits mailing list