[llvm] 7047d79 - [TwoAddressInstructionPass] Relax assert in statepoint processing.

Denis Antrushin via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 1 07:36:13 PDT 2022


Author: Denis Antrushin
Date: 2022-06-01T21:34:52+07:00
New Revision: 7047d79fde88ed5f189101186f1267513a146eb9

URL: https://github.com/llvm/llvm-project/commit/7047d79fde88ed5f189101186f1267513a146eb9
DIFF: https://github.com/llvm/llvm-project/commit/7047d79fde88ed5f189101186f1267513a146eb9.diff

LOG: [TwoAddressInstructionPass] Relax assert in statepoint processing.

D124631 added special processing for STATEPOINT instructions.
It appears that assertion added there is too strong. We can get two
tied operands with the same register tied to different defs. If we
hit such case, do not process it in statepoint-specific code and
delegate it to common case.

Added: 
    

Modified: 
    llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
    llvm/test/CodeGen/X86/statepoint-vreg-twoaddr.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
index 0ba2abaf76fd..c44fd9f97383 100644
--- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -161,7 +161,7 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
   bool collectTiedOperands(MachineInstr *MI, TiedOperandMap&);
   void processTiedPairs(MachineInstr *MI, TiedPairList&, unsigned &Dist);
   void eliminateRegSequence(MachineBasicBlock::iterator&);
-  void processStatepoint(MachineInstr *MI, TiedOperandMap &TiedOperands);
+  bool processStatepoint(MachineInstr *MI, TiedOperandMap &TiedOperands);
 
 public:
   static char ID; // Pass identification, replacement for typeid
@@ -1635,12 +1635,16 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
 // and replaces all uses of RegA with RegB.
 // No extra COPY instruction is necessary because tied use is killed at
 // STATEPOINT.
-void TwoAddressInstructionPass::processStatepoint(
+bool TwoAddressInstructionPass::processStatepoint(
     MachineInstr *MI, TiedOperandMap &TiedOperands) {
 
+  bool NeedCopy = false;
   for (auto &TO : TiedOperands) {
     Register RegB = TO.first;
-    assert(TO.second.size() == 1 && "statepoints has single tied use");
+    if (TO.second.size() != 1) {
+      NeedCopy = true;
+      continue;
+    }
 
     unsigned SrcIdx = TO.second[0].first;
     unsigned DstIdx = TO.second[0].second;
@@ -1676,6 +1680,7 @@ void TwoAddressInstructionPass::processStatepoint(
         LV->addVirtualRegisterKilled(RegB, *KillMI, false);
     }
   }
+  return !NeedCopy;
 }
 
 /// Reduce two-address instructions to two operands.
@@ -1771,8 +1776,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) {
         }
       }
 
-      if (mi->getOpcode() == TargetOpcode::STATEPOINT) {
-        processStatepoint(&*mi, TiedOperands);
+      if (mi->getOpcode() == TargetOpcode::STATEPOINT &&
+          processStatepoint(&*mi, TiedOperands)) {
         TiedOperands.clear();
         LLVM_DEBUG(dbgs() << "\t\trewrite to:\t" << *mi);
         mi = nmi;

diff  --git a/llvm/test/CodeGen/X86/statepoint-vreg-twoaddr.mir b/llvm/test/CodeGen/X86/statepoint-vreg-twoaddr.mir
index 0246ff57bc23..5a487d366254 100644
--- a/llvm/test/CodeGen/X86/statepoint-vreg-twoaddr.mir
+++ b/llvm/test/CodeGen/X86/statepoint-vreg-twoaddr.mir
@@ -12,6 +12,7 @@
   declare i1 @return_i1()
 
   declare void @consume(i32 addrspace(1)*)
+  declare void @consume1(i8 addrspace(1)*, i64 addrspace(1)*)
 
   define i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" {
   entry:
@@ -22,6 +23,10 @@
     ret i1 %res1
   }
 
+  define void @test_duplicate_gcregs(i8 addrspace(1)* %a) gc "statepoint-example" {
+    ret void
+  }
+
   ; Function Attrs: nounwind readnone
   declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32 immarg, i32 immarg) #0
 
@@ -62,3 +67,28 @@ body:             |
     RET 0, killed $al
 
 ...
+---
+name:            test_duplicate_gcregs
+alignment:       16
+tracksRegLiveness: true
+liveins:
+  - { reg: '$rdi', virtual-reg: '%0' }
+body:             |
+  bb.0 (%ir-block.0):
+    liveins: $rdi
+
+    ; CHECK-LABEL: name: test_duplicate_gcregs
+    ; CHECK:   %1:gr64 = COPY %0
+    ; CHECK:   %2:gr64 = COPY %0
+    ; CHECK:   %1:gr64, %2:gr64 = STATEPOINT 0, 0, 0, target-flags(x86-plt) @return_i1, 2, 0, 2, 0, 2, 0, 2, 2, %1(tied-def 0), %2(tied-def 1), 2, 0, 2, 2, 0, 0, 1, 1, csr_64
+    ; CHECK:   $rdi = COPY killed %1
+    ; CHECK:   $rsi = COPY killed %2
+    ; CHECK:   CALL64pcrel32 target-flags(x86-plt) @consume1, csr_64, implicit $rsp, implicit $ssp, implicit killed $rdi, implicit killed $rsi, implicit-def $rsp, implicit-def $ssp
+    ; CHECK:   RET 0
+    %0:gr64 = COPY killed $rdi
+    %1:gr64, %2:gr64 = STATEPOINT 0, 0, 0, target-flags(x86-plt) @return_i1, 2, 0, 2, 0, 2, 0, 2, 2, killed %0(tied-def 0), killed %0(tied-def 1), 2, 0, 2, 2, 0, 0, 1, 1, csr_64, implicit-def $rsp, implicit-def $ssp, implicit-def dead $al
+    $rdi = COPY killed %1
+    $rsi = COPY killed %2
+    CALL64pcrel32 target-flags(x86-plt) @consume1, csr_64, implicit $rsp, implicit $ssp, implicit killed $rdi, implicit killed $rsi, implicit-def $rsp, implicit-def $ssp
+    RET 0
+...


        


More information about the llvm-commits mailing list