[llvm] 764676b - [fastregalloc] Fix bug when undef value is tied to def.

via llvm-commits llvm-commits at lists.llvm.org
Tue May 3 21:13:25 PDT 2022


Author: Luo, Yuanke
Date: 2022-05-04T12:12:55+08:00
New Revision: 764676b737db0f259ef018104edbc2aec9db7e7d

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

LOG: [fastregalloc] Fix bug when undef value is tied to def.

If the tied use is undef value, fastregalloc should free the def
register. There is no reload needed for the undef value.

Reviewed By: MatzeB

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

Added: 
    llvm/test/CodeGen/X86/fastregalloc-tied-undef.mir

Modified: 
    llvm/lib/CodeGen/RegAllocFast.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp
index dfe0876012a4b..bee811f1bba14 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -1112,6 +1112,12 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
   RegMasks.clear();
   BundleVirtRegsMap.clear();
 
+  auto TiedOpIsUndef = [&](const MachineOperand &MO, unsigned Idx) {
+    assert(MO.isTied());
+    unsigned TiedIdx = MI.findTiedOperandIdx(Idx);
+    const MachineOperand &TiedMO = MI.getOperand(TiedIdx);
+    return TiedMO.isUndef();
+  };
   // Scan for special cases; Apply pre-assigned register defs to state.
   bool HasPhysRegUse = false;
   bool HasRegMask = false;
@@ -1119,7 +1125,8 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
   bool HasDef = false;
   bool HasEarlyClobber = false;
   bool NeedToAssignLiveThroughs = false;
-  for (MachineOperand &MO : MI.operands()) {
+  for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
+    MachineOperand &MO = MI.getOperand(I);
     if (MO.isReg()) {
       Register Reg = MO.getReg();
       if (Reg.isVirtual()) {
@@ -1130,7 +1137,8 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
             HasEarlyClobber = true;
             NeedToAssignLiveThroughs = true;
           }
-          if (MO.isTied() || (MO.getSubReg() != 0 && !MO.isUndef()))
+          if ((MO.isTied() && !TiedOpIsUndef(MO, I)) ||
+              (MO.getSubReg() != 0 && !MO.isUndef()))
             NeedToAssignLiveThroughs = true;
         }
       } else if (Reg.isPhysical()) {
@@ -1230,7 +1238,8 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
           MachineOperand &MO = MI.getOperand(OpIdx);
           LLVM_DEBUG(dbgs() << "Allocating " << MO << '\n');
           unsigned Reg = MO.getReg();
-          if (MO.isEarlyClobber() || MO.isTied() ||
+          if (MO.isEarlyClobber() ||
+              (MO.isTied() && !TiedOpIsUndef(MO, OpIdx)) ||
               (MO.getSubReg() && !MO.isUndef())) {
             defineLiveThroughVirtReg(MI, OpIdx, Reg);
           } else {
@@ -1253,7 +1262,8 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
     // Free registers occupied by defs.
     // Iterate operands in reverse order, so we see the implicit super register
     // defs first (we added them earlier in case of <def,read-undef>).
-    for (MachineOperand &MO : llvm::reverse(MI.operands())) {
+    for (signed I = MI.getNumOperands() - 1; I >= 0; --I) {
+      MachineOperand &MO = MI.getOperand(I);
       if (!MO.isReg() || !MO.isDef())
         continue;
 
@@ -1268,7 +1278,7 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
              "tied def assigned to clobbered register");
 
       // Do not free tied operands and early clobbers.
-      if (MO.isTied() || MO.isEarlyClobber())
+      if ((MO.isTied() && !TiedOpIsUndef(MO, I)) || MO.isEarlyClobber())
         continue;
       Register Reg = MO.getReg();
       if (!Reg)

diff  --git a/llvm/test/CodeGen/X86/fastregalloc-tied-undef.mir b/llvm/test/CodeGen/X86/fastregalloc-tied-undef.mir
new file mode 100644
index 0000000000000..8a6311eabacad
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fastregalloc-tied-undef.mir
@@ -0,0 +1,36 @@
+# RUN: llc -mtriple=x86_64-- -run-pass=regallocfast -o - %s | FileCheck %s
+
+# If the tied use is undef value, fastregalloc should free the def register.
+# There is no reload needed for the undef value.
+...
+---
+name:            foo
+alignment:       16
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: vr128 }
+frameInfo:
+  maxAlignment:    16
+stack:
+  - { id: 0, size: 64, alignment: 16 }
+  - { id: 1, size: 16, alignment: 16 }
+machineFunctionInfo: {}
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: bb.0.entry
+    ; CHECK-NEXT: renamable $xmm0 = PXORrr undef renamable $xmm0, undef renamable $xmm0
+    ; CHECK-NEXT: MOVAPSmr %stack.1, 1, $noreg, 0, $noreg, renamable $xmm0
+    ; CHECK-NEXT: MOVAPSmr %stack.0, 1, $noreg, 0, $noreg, renamable $xmm0
+    ; CHECK-NEXT: MOVAPSmr %stack.0, 1, $noreg, 16, $noreg, renamable $xmm0
+    ; CHECK-NEXT: MOVAPSmr %stack.0, 1, $noreg, 32, $noreg, renamable $xmm0
+    ; CHECK-NEXT: MOVAPSmr %stack.0, 1, $noreg, 48, $noreg, killed renamable $xmm0
+
+    %0:vr128 = PXORrr undef %0, undef %0
+    MOVAPSmr %stack.1, 1, $noreg, 0, $noreg, %0
+    MOVAPSmr %stack.0, 1, $noreg, 0, $noreg, %0
+    MOVAPSmr %stack.0, 1, $noreg, 16, $noreg, %0
+    MOVAPSmr %stack.0, 1, $noreg, 32, $noreg, %0
+    MOVAPSmr %stack.0, 1, $noreg, 48, $noreg, killed %0
+    RET 0
+
+...


        


More information about the llvm-commits mailing list