[PATCH] D38616: [RegisterCoalescer] Don't set read-undef if there is a previous def

Mikael Holmén via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 6 04:33:26 PDT 2017


uabelho created this revision.

If coalescing so that we remove an earlier IMPLICIT_DEF we sometimes need
to set the undef field on a sub register write. E.g. if we had something
like

%vreg1<def> = IMPLICIT_DEF
 %vreg2:subreg1<def> = op %vreg3, %vreg4

and we merge %vreg1 and %vreg2, we should sometimes rewrite the subreg
def to

%vreg2:subreg1<def, read-undef> = op %vreg3, %vreg4

However, if there is another subreg definition, we should not add the undef
to both of them. E.g. if we have

%vreg1<def> = IMPLICIT_DEF
%vreg2:subreg1<def> = op %vreg3, %vreg4
%vreg2:subreg2<def> = op %vreg6, %vreg7

then we should only set undef on the first subreg def.

Now we try to do this, by checking if there is a reaching def before
setting read-undef on the subreg definition.


https://reviews.llvm.org/D38616

Files:
  lib/CodeGen/RegisterCoalescer.cpp
  test/CodeGen/MIR/X86/simple-register-allocation-read-undef.mir


Index: test/CodeGen/MIR/X86/simple-register-allocation-read-undef.mir
===================================================================
--- /dev/null
+++ test/CodeGen/MIR/X86/simple-register-allocation-read-undef.mir
@@ -0,0 +1,40 @@
+# RUN: llc -mtriple=x86_64-- %s -o - -run-pass=simple-register-coalescing | FileCheck %s
+---
+name:            f
+registers:
+  - { id: 0, class: gr64 }
+  - { id: 1, class: gr64_with_sub_8bit }
+  - { id: 2, class: vr128 }
+  - { id: 3, class: vr128 }
+  - { id: 4, class: vr128 }
+body:             |
+  bb.0:
+    JB_1 %bb.2, undef implicit killed %eflags
+    JMP_1 %bb.1
+
+  bb.1:
+
+    %0 = IMPLICIT_DEF
+    undef %1.sub_32bit = MOV32r0 implicit-def %eflags
+    %1.sub_16bit = MOV16ri 3
+    JMP_1 %bb.3
+
+  bb.2:
+
+    %0 = MOVPQIto64rr undef %2
+    %1 = COPY %0
+
+  bb.3:
+
+    %3 = MOV64toPQIrr killed %0
+    %4 = MOV64toPQIrr killed %1
+
+...
+
+# We should have a setting of both sub_32bit and sub_16bit. The first one
+# should be undef and not dead, and the second should not be undef.
+
+# CHECK-NOT: dead
+# CHECK:     undef [[TMP:%[0-1]+]].sub_32bit = MOV32r0
+# CHECK-NOT: undef
+# CHECK:     [[TMP]].sub_16bit = MOV16ri
Index: lib/CodeGen/RegisterCoalescer.cpp
===================================================================
--- lib/CodeGen/RegisterCoalescer.cpp
+++ lib/CodeGen/RegisterCoalescer.cpp
@@ -2686,7 +2686,10 @@
                Indexes->getInstructionFromIndex(Def)->operands()) {
             if (MO.isReg() && MO.isDef() && MO.getReg() == Reg) {
               if (MO.getSubReg() != 0)
-                MO.setIsUndef(EraseImpDef);
+                // Only set undef on the MO if we can't find any reaching
+                // definition of the value. If it does exist and we set undef on
+                // the MO we will effectively kill the reaching definition.
+                MO.setIsUndef(EraseImpDef && !LR.getVNInfoBefore(Def));
               MO.setIsDead(false);
             }
           }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D38616.117980.patch
Type: text/x-patch
Size: 1986 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171006/65faf660/attachment.bin>


More information about the llvm-commits mailing list