[llvm] 8903dbe - [StatepointLowering] Properly handle local and non-local relocates of the same value.

Denis Antrushin via llvm-commits llvm-commits at lists.llvm.org
Mon May 16 03:04:57 PDT 2022


Author: Denis Antrushin
Date: 2022-05-16T17:02:34+07:00
New Revision: 8903dbef8ff675e0529ee83ab8c5191ba466e380

URL: https://github.com/llvm/llvm-project/commit/8903dbef8ff675e0529ee83ab8c5191ba466e380
DIFF: https://github.com/llvm/llvm-project/commit/8903dbef8ff675e0529ee83ab8c5191ba466e380.diff

LOG: [StatepointLowering] Properly handle local and non-local relocates of the same value.

FunctionLoweringInfo::StatepointRelocationMaps map is used to pass GC pointer
lowering information from statepoint to gc.relocate  which may appear ini
different block.
D124444 introduced different lowering for local and non-local relocates.
Local relocates use SDValue and non-local relocates use value exported to VReg.
But I overlooked the fact that StatepointRelocationMap is indexed not by
GCRelocate instruction, but by derived pointer. This works incorrectly when
we have two relocates (one local and another non-local) of the same value,
because they need different relocation records.

This patch fixes the problem by recording relocation information per relocate
instruction, not per derived pointer. This way, each gc.relocate can be lowered
differently.

Reviewed By: skatkov

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

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
    llvm/test/CodeGen/X86/statepoint-vreg-details.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
index 3bf8935a2bd6a..aa1595414c10a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
@@ -172,7 +172,7 @@ static Optional<int> findPreviousSpillSlot(const Value *Val,
     const auto &RelocationMap =
         Builder.FuncInfo.StatepointRelocationMaps[Relocate->getStatepoint()];
 
-    auto It = RelocationMap.find(Relocate->getDerivedPtr());
+    auto It = RelocationMap.find(Relocate);
     if (It == RelocationMap.end())
       return None;
 
@@ -953,7 +953,7 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
       if (Relocate->getParent() != StatepointInstr->getParent())
         ExportFromCurrentBlock(V);
     }
-    RelocationMap[V] = Record;
+    RelocationMap[Relocate] = Record;
   }
 
   
@@ -1231,7 +1231,7 @@ void SelectionDAGBuilder::visitGCRelocate(const GCRelocateInst &Relocate) {
   const Value *DerivedPtr = Relocate.getDerivedPtr();
   auto &RelocationMap =
     FuncInfo.StatepointRelocationMaps[Relocate.getStatepoint()];
-  auto SlotIt = RelocationMap.find(DerivedPtr);
+  auto SlotIt = RelocationMap.find(&Relocate);
   assert(SlotIt != RelocationMap.end() && "Relocating not lowered gc value");
   const RecordType &Record = SlotIt->second;
 

diff  --git a/llvm/test/CodeGen/X86/statepoint-vreg-details.ll b/llvm/test/CodeGen/X86/statepoint-vreg-details.ll
index eb099400107d3..ea8824a599328 100644
--- a/llvm/test/CodeGen/X86/statepoint-vreg-details.ll
+++ b/llvm/test/CodeGen/X86/statepoint-vreg-details.ll
@@ -17,6 +17,7 @@ declare dso_local void @consume2(i32 addrspace(1)*, i32 addrspace(1)*)
 declare dso_local void @consume5(i32 addrspace(1)*, i32 addrspace(1)*, i32 addrspace(1)*, i32 addrspace(1)*, i32 addrspace(1)*)
 declare dso_local void @use1(i32 addrspace(1)*, i8 addrspace(1)*)
 declare dso_local void @bar(i8 addrspace(1)*, i8 addrspace(1)*)
+declare i8 addrspace(1)* @dummy(i32)
 
 ; test most simple relocate
 define i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" {
@@ -244,6 +245,43 @@ right:
   ret i1 true
 }
 
+; Local and non-local relocates of the same value
+; CHECK-VREG-LABEL: name:            test_local_non_local_reloc
+; CHECK-VREG:  bb.0.entry:
+; CHECK-VREG:    %2:gr64 = COPY $rsi
+; CHECK-VREG:    %1:gr32 = COPY $edi
+; CHECK-VREG:    %4:gr8 = COPY %1.sub_8bit
+; CHECK-VREG:    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+; CHECK-VREG:    %5:gr32 = MOV32r0 implicit-def dead $eflags
+; CHECK-VREG:    $edi = COPY %5
+; CHECK-VREG:    %6:gr64 = IMPLICIT_DEF
+; CHECK-VREG:    %0:gr64 = STATEPOINT 2, 5, 1, killed %6, $edi, 2, 0, 2, 0, 2, 0, 2, 1, %2(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
+; CHECK-VREG:    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+; CHECK-VREG:    %7:gr64 = COPY $rax
+; CHECK-VREG:    %3:gr64 = COPY %0
+; CHECK-VREG:    TEST8ri killed %4, 1, implicit-def $eflags
+; CHECK-VREG:    JCC_1 %bb.2, 5, implicit $eflags
+; CHECK-VREG:    JMP_1 %bb.1
+; CHECK-VREG:  bb.1.left:
+; CHECK-VREG:    $rax = COPY %3
+; CHECK-VREG:    RET 0, $rax
+; CHECK-VREG:  bb.2.right:
+; CHECK-VREG:    $rax = COPY %0
+; CHECK-VREG:    RET 0, $rax
+define i8 addrspace(1)* @test_local_non_local_reloc(i1 %c, i8 addrspace(1)* %p) gc "statepoint-example" {
+entry:
+  %statepoint = call token (i64, i32, i8 addrspace(1)* (i32)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i8i32f(i64 2, i32 5, i8 addrspace(1)* (i32)* nonnull elementtype(i8 addrspace(1)* (i32)) @dummy, i32 1, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i8 addrspace(1)* %p) ]
+  %p.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint, i32 0, i32 0) ; (%p, %p)
+  br i1 %c, label %right, label %left
+
+left:
+  %p.relocated.2 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint, i32 0, i32 0) ; (%p, %p)
+  ret i8 addrspace(1)* %p.relocated.2
+
+right:
+  ret i8 addrspace(1)* %p.relocated
+}
+
 ; No need to check post-regalloc output as it is the same
 define i1 @duplicate_reloc() gc "statepoint-example" {
 ; CHECK-VREG-LABEL: name:            duplicate_reloc
@@ -375,4 +413,5 @@ declare dso_local i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i3
 declare <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token, i32, i32)
 declare dso_local i1 @llvm.experimental.gc.result.i1(token)
 declare token @llvm.experimental.gc.statepoint.p0f_isVoidp1i8p1i8f(i64 immarg, i32 immarg, void (i8 addrspace(1)*, i8 addrspace(1)*)*, i32 immarg, i32 immarg, ...)
+declare token @llvm.experimental.gc.statepoint.p0f_p1i8i32f(i64, i32, i8 addrspace(1)* (i32)*, i32, i32, ...)
 


        


More information about the llvm-commits mailing list