diff options
author | Petar Avramovic <Petar.Avramovic@amd.com> | 2021-08-05 13:59:37 +0200 |
---|---|---|
committer | Petar Avramovic <Petar.Avramovic@amd.com> | 2021-08-05 15:05:45 +0200 |
commit | 66de26b1f9ecf22193aea2edfac03db03f138feb (patch) | |
tree | 9a5b0d6391f7a0eec663d2e50cfdce2871b89006 | |
parent | 7b73ca3043fecfc5fa6bbf5b28edfee61a83ff9f (diff) | |
download | llvm-66de26b1f9ecf22193aea2edfac03db03f138feb.tar.gz |
GlobalISel: Fix matchEqualDefs for instructions with multiple defs
Instructions that produceSameValue produce same values for operands with
same index. matchEqualDefs used to return true for any two values from
different instructions that produce same values. Fix this by checking if
values are defined by operands with the same index.
Differential Revision: https://reviews.llvm.org/D107362
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp | 22 | ||||
-rw-r--r-- | llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir | 46 |
2 files changed, 63 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index c816f5b71b3d..f0d97e573645 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -2659,12 +2659,14 @@ bool CombinerHelper::matchEqualDefs(const MachineOperand &MOP1, 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: // @@ -2724,7 +2726,17 @@ bool CombinerHelper::matchEqualDefs(const MachineOperand &MOP1, // // On the off-chance that there's some target instruction feeding into the // instruction, let's use produceSameValue instead of isIdenticalTo. - return Builder.getTII().produceSameValue(*I1, *I2, &MRI); + if (Builder.getTII().produceSameValue(*I1, *I2, &MRI)) { + // Handle instructions with multiple defs that produce same values. Values + // are same for operands with same index. + // %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. + return I1->findRegisterDefOperandIdx(InstAndDef1->Reg) == + I2->findRegisterDefOperandIdx(InstAndDef2->Reg); + } + return false; } bool CombinerHelper::matchConstantOp(const MachineOperand &MOP, int64_t C) { diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir index 1941ad593f96..75840bfda563 100644 --- a/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir +++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir @@ -50,3 +50,49 @@ body: | 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 +... |