[llvm] [X86] Skip unused VRegs traverse (PR #78229)

Evgenii Kudriashov via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 18 18:52:36 PST 2024


https://github.com/e-kud updated https://github.com/llvm/llvm-project/pull/78229

>From 2bb421797e1a35c8ff1cdd962fdff43ae4fdd164 Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Mon, 15 Jan 2024 17:15:02 -0800
Subject: [PATCH 1/2] [X86] Do not traverse unused VRegs

GlobalISel may leave dead VRegs without a register class. It shouldn't
be a problem if instructions or VRegs are traversed correctly.

Closes #64452 #71926
---
 llvm/lib/Target/X86/X86DomainReassignment.cpp |  4 ++
 llvm/lib/Target/X86/X86FastPreTileConfig.cpp  |  3 +-
 .../CodeGen/X86/AMX/amx-fastpreconfig.mir     | 45 +++++++++++++
 llvm/test/CodeGen/X86/domain-reassignment.mir | 64 +++++++++++++++++++
 4 files changed, 115 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/X86DomainReassignment.cpp b/llvm/lib/Target/X86/X86DomainReassignment.cpp
index 20dbaf797e3272..53c0486c8697fd 100644
--- a/llvm/lib/Target/X86/X86DomainReassignment.cpp
+++ b/llvm/lib/Target/X86/X86DomainReassignment.cpp
@@ -754,6 +754,10 @@ bool X86DomainReassignment::runOnMachineFunction(MachineFunction &MF) {
   for (unsigned Idx = 0; Idx < MRI->getNumVirtRegs(); ++Idx) {
     Register Reg = Register::index2VirtReg(Idx);
 
+    // Skip unused VRegs.
+    if (MRI->reg_nodbg_empty(Reg))
+      continue;
+
     // GPR only current source domain supported.
     if (!isGPR(MRI->getRegClass(Reg)))
       continue;
diff --git a/llvm/lib/Target/X86/X86FastPreTileConfig.cpp b/llvm/lib/Target/X86/X86FastPreTileConfig.cpp
index ea942445a18193..7708089074c0a3 100644
--- a/llvm/lib/Target/X86/X86FastPreTileConfig.cpp
+++ b/llvm/lib/Target/X86/X86FastPreTileConfig.cpp
@@ -667,7 +667,8 @@ bool X86FastPreTileConfig::runOnMachineFunction(MachineFunction &MFunc) {
   bool HasVirtTileReg = false;
   for (unsigned I = 0, E = NumVirtRegs; I != E; ++I) {
     Register VirtReg = Register::index2VirtReg(I);
-    if (MRI->getRegClass(VirtReg)->getID() == X86::TILERegClassID) {
+    if (!MRI->reg_nodbg_empty(VirtReg) &&
+        MRI->getRegClass(VirtReg)->getID() == X86::TILERegClassID) {
       HasVirtTileReg = true;
       break;
     }
diff --git a/llvm/test/CodeGen/X86/AMX/amx-fastpreconfig.mir b/llvm/test/CodeGen/X86/AMX/amx-fastpreconfig.mir
index dcc8d542c70704..40566520b79f01 100644
--- a/llvm/test/CodeGen/X86/AMX/amx-fastpreconfig.mir
+++ b/llvm/test/CodeGen/X86/AMX/amx-fastpreconfig.mir
@@ -59,3 +59,48 @@ body:             |
     RET 0, killed $eax
 
 ...
+# GlobalIsel doesn't use all virtual registers and there may be virtual
+# registers without a class.
+# Note that %3 doesn't have a class: gpr instead of gr64.
+---
+name:            test_unused
+legalized:       true
+regBankSelected: true
+selected:        true
+failedISel:      false
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gr64, preferred-register: '' }
+  - { id: 1, class: gr64_with_sub_8bit, preferred-register: '' }
+  - { id: 2, class: gr64, preferred-register: '' }
+  - { id: 3, class: gpr, preferred-register: '' }
+  - { id: 4, class: gr64, preferred-register: '' }
+  - { id: 5, class: gr8, preferred-register: '' }
+liveins:
+  - { reg: '$rdi', virtual-reg: '' }
+  - { reg: '$rsi', virtual-reg: '' }
+body:             |
+  bb.1.entry:
+    liveins: $rdi, $rsi
+
+    ; CHECK-LABEL: name: test_unused
+    ; CHECK: liveins: $rdi, $rsi
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64_with_sub_8bit = COPY $rsi
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr8 = COPY [[COPY1]].sub_8bit
+    ; CHECK-NEXT: $cl = COPY [[COPY2]]
+    ; CHECK-NEXT: [[SHR64rCL:%[0-9]+]]:gr64 = SHR64rCL [[COPY]], implicit-def $eflags, implicit $cl
+    ; CHECK-NEXT: [[ADD64ri32_:%[0-9]+]]:gr64 = ADD64ri32 [[SHR64rCL]], 123456789, implicit-def $eflags
+    ; CHECK-NEXT: $rax = COPY [[ADD64ri32_]]
+    ; CHECK-NEXT: RET 0, implicit $rax
+    %0:gr64 = COPY $rdi
+    %1:gr64_with_sub_8bit = COPY $rsi
+    %5:gr8 = COPY %1.sub_8bit
+    $cl = COPY %5
+    %2:gr64 = SHR64rCL %0, implicit-def $eflags, implicit $cl
+    %4:gr64 = ADD64ri32 %2, 123456789, implicit-def $eflags
+    $rax = COPY %4
+    RET 0, implicit $rax
+
+...
diff --git a/llvm/test/CodeGen/X86/domain-reassignment.mir b/llvm/test/CodeGen/X86/domain-reassignment.mir
index f4e454e3fa4974..29df0f70d6d75e 100644
--- a/llvm/test/CodeGen/X86/domain-reassignment.mir
+++ b/llvm/test/CodeGen/X86/domain-reassignment.mir
@@ -46,6 +46,10 @@
   define void @test_64bitext() #0 {
     ret void
   }
+  define void @test_globalisel_unused(i64 %0) #0 {
+    %unused = lshr i64 %0, 7
+    ret void
+  }
 ...
 ---
 name:            test_fcmp_storefloat
@@ -860,3 +864,63 @@ body:             |
     RET 0
 
 ...
+---
+name:            test_globalisel_unused
+alignment:       16
+exposesReturnsTwice: false
+legalized:       true
+regBankSelected: true
+selected:        true
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   false
+failsVerification: false
+tracksDebugUserValues: false
+registers:
+  - { id: 0, class: _, preferred-register: '' }
+  - { id: 1, class: _, preferred-register: '' }
+  - { id: 2, class: _, preferred-register: '' }
+liveins:
+  - { reg: '$rdi', virtual-reg: '' }
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    1
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  functionContext: ''
+  maxCallFrameSize: 4294967295
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  localFrameSize:  0
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:           []
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo: {}
+body:             |
+  bb.1 (%ir-block.1):
+    liveins: $rdi
+
+    RET 0
+
+...

>From 6e2bc7ce867a55877d3225d64eb1f8f2c882aa53 Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Thu, 18 Jan 2024 18:52:11 -0800
Subject: [PATCH 2/2] Add detailed comments

---
 llvm/test/CodeGen/X86/domain-reassignment.mir | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/llvm/test/CodeGen/X86/domain-reassignment.mir b/llvm/test/CodeGen/X86/domain-reassignment.mir
index 29df0f70d6d75e..8b2fbe04d14afb 100644
--- a/llvm/test/CodeGen/X86/domain-reassignment.mir
+++ b/llvm/test/CodeGen/X86/domain-reassignment.mir
@@ -46,7 +46,9 @@
   define void @test_64bitext() #0 {
     ret void
   }
-  define void @test_globalisel_unused(i64 %0) #0 {
+  ; Note that this function need to be compiled with -global-isel
+  ; to obtain testable MIR
+  define void @test_unused(i64 %0) #0 {
     %unused = lshr i64 %0, 7
     ret void
   }
@@ -865,7 +867,7 @@ body:             |
 
 ...
 ---
-name:            test_globalisel_unused
+name:            test_unused
 alignment:       16
 exposesReturnsTwice: false
 legalized:       true
@@ -884,6 +886,7 @@ debugInstrRef:   false
 failsVerification: false
 tracksDebugUserValues: false
 registers:
+# Note that this test is supposed to have registers without classes
   - { id: 0, class: _, preferred-register: '' }
   - { id: 1, class: _, preferred-register: '' }
   - { id: 2, class: _, preferred-register: '' }



More information about the llvm-commits mailing list