[PATCH] D107362: GlobalISel: Fix CombinerHelper::matchEqualDefs() for unmerge

Petar Avramovic via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 3 08:46:22 PDT 2021


Petar.Avramovic created this revision.
Petar.Avramovic added reviewers: foad, arsenm, aemerson, paquette.
Herald added subscribers: kerbowa, hiraditya, rovka, nhaehnle, jvesely.
Petar.Avramovic requested review of this revision.
Herald added subscribers: llvm-commits, wdng.
Herald added a project: LLVM.

Different unmerge instructions with same source produce same values for
operands with same index. matchEqualDefs used to return true for any two
values. Fix this by checking if values from unmerges with same source
are defined by operands with the same index.


https://reviews.llvm.org/D107362

Files:
  llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
  llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir


Index: llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir
===================================================================
--- llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir
+++ llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir
@@ -50,3 +50,49 @@
     SI_RETURN_TO_EPILOG $vgpr0
 
 ...
+
+---
+name: select_different_result_from_different_unmerge_values_with_the_same_source
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $vgpr0_vgpr1_vgpr2_vgpr3, $vgpr4
+
+    ; GCN-LABEL: name: select_different_result_from_different_unmerge_values_with_the_same_source
+    ; GCN: liveins: $vgpr0_vgpr1_vgpr2_vgpr3, $vgpr4
+    ; GCN: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $vgpr0_vgpr1_vgpr2_vgpr3
+    ; GCN: [[COPY1:%[0-9]+]]:_(s32) = COPY $vgpr4
+    ; GCN: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[COPY1]](s32)
+    ; GCN: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32), [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](<4 x s32>)
+    ; GCN: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32), [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](<4 x s32>)
+    ; GCN: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[TRUNC]](s1), [[UV1]], [[UV7]]
+    ; GCN: $vgpr0 = COPY [[SELECT]](s32)
+    %0:_(<4 x s32>) = COPY $vgpr0_vgpr1_vgpr2_vgpr3
+    %1:_(s32) = COPY $vgpr4
+    %2:_(s1) = G_TRUNC %1:_(s32)
+    %3:_(s32), %4:_(s32), %5:_(s32), %6:_(s32) = G_UNMERGE_VALUES %0:_(<4 x s32>)
+    %7:_(s32), %8:_(s32), %9:_(s32), %10:_(s32) = G_UNMERGE_VALUES %0:_(<4 x s32>)
+    %11:_(s32) = G_SELECT %2:_(s1), %4:_, %10:_
+    $vgpr0 = COPY %11
+...
+
+---
+name: select_same_result_from_different_unmerge_values_with_the_same_source
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $vgpr0_vgpr1_vgpr2_vgpr3, $vgpr4
+
+    ; GCN-LABEL: name: select_same_result_from_different_unmerge_values_with_the_same_source
+    ; GCN: liveins: $vgpr0_vgpr1_vgpr2_vgpr3, $vgpr4
+    ; GCN: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $vgpr0_vgpr1_vgpr2_vgpr3
+    ; GCN: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32), [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](<4 x s32>)
+    ; GCN: $vgpr0 = COPY [[UV1]](s32)
+    %0:_(<4 x s32>) = COPY $vgpr0_vgpr1_vgpr2_vgpr3
+    %1:_(s32) = COPY $vgpr4
+    %2:_(s1) = G_TRUNC %1:_(s32)
+    %3:_(s32), %4:_(s32), %5:_(s32), %6:_(s32) = G_UNMERGE_VALUES %0:_(<4 x s32>)
+    %7:_(s32), %8:_(s32), %9:_(s32), %10:_(s32) = G_UNMERGE_VALUES %0:_(<4 x s32>)
+    %11:_(s32) = G_SELECT %2:_(s1), %4:_, %8:_
+    $vgpr0 = COPY %11
+...
Index: llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
===================================================================
--- llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -2659,12 +2659,14 @@
                                     const MachineOperand &MOP2) {
   if (!MOP1.isReg() || !MOP2.isReg())
     return false;
-  MachineInstr *I1 = getDefIgnoringCopies(MOP1.getReg(), MRI);
-  if (!I1)
+  auto InstAndDef1 = getDefSrcRegIgnoringCopies(MOP1.getReg(), MRI);
+  if (!InstAndDef1)
     return false;
-  MachineInstr *I2 = getDefIgnoringCopies(MOP2.getReg(), MRI);
-  if (!I2)
+  auto InstAndDef2 = getDefSrcRegIgnoringCopies(MOP2.getReg(), MRI);
+  if (!InstAndDef2)
     return false;
+  MachineInstr *I1 = InstAndDef1->MI;
+  MachineInstr *I2 = InstAndDef2->MI;
 
   // Handle a case like this:
   //
@@ -2675,6 +2677,21 @@
   if (I1 == I2)
     return MOP1.getReg() == MOP2.getReg();
 
+  // %0:_(s8), %1:_(s8), %2:_(s8), %3:_(s8) = G_UNMERGE_VALUES %4:_(<4 x s8>)
+  // %5:_(s8), %6:_(s8), %7:_(s8), %8:_(s8) = G_UNMERGE_VALUES %4:_(<4 x s8>)
+  //
+  // I1 and I2 are different instructions but produce same values,
+  // %1 and %6 are same, %1 and %7 are not the same value.
+  if (isa<GUnmerge>(I1) && isa<GUnmerge>(I2)) {
+    auto Unmerge1 = cast<GUnmerge>(I1);
+    auto Unmerge2 = cast<GUnmerge>(I2);
+    if (Unmerge1->getSourceReg() == Unmerge2->getSourceReg()) {
+      return Unmerge1->findRegisterDefOperandIdx(InstAndDef1->Reg) ==
+             Unmerge2->findRegisterDefOperandIdx(InstAndDef2->Reg);
+    }
+    return false;
+  }
+
   // If we have an instruction which loads or stores, we can't guarantee that
   // it is identical.
   //


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D107362.363758.patch
Type: text/x-patch
Size: 4300 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210803/b2791971/attachment.bin>


More information about the llvm-commits mailing list