[llvm-branch-commits] [llvm] f744390 - [Statepoint] Handle `undef` operands in statepoint.

2021-01-18 Thread Denis Antrushin via llvm-branch-commits

Author: Denis Antrushin
Date: 2021-01-18T15:20:54+03:00
New Revision: f7443905af1e06eaacda1e437fff8d54dc89c487

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

LOG: [Statepoint] Handle `undef` operands in statepoint.

Currently when spilling statepoint register operands in FixupStatepoints
we do not pay attention that it might be `undef`. We just generate a
spill, which may lead to verifier error because we have a use without def.

To handle it, let FixupStateponts ignore `undef` register operands
completely and change them to some constant value when generating
stack map. Use same value as used by ISel for this purpose (0xFEFEFEFE).

Reviewed By: reames

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

Added: 
llvm/test/CodeGen/X86/statepoint-fixup-undef.mir

Modified: 
llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp
llvm/lib/CodeGen/StackMaps.cpp

Removed: 




diff  --git a/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp 
b/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp
index 662bd1a3646f..f8f99b7e87f2 100644
--- a/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp
+++ b/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp
@@ -380,7 +380,9 @@ class StatepointState {
   EndIdx = MI.getNumOperands();
  Idx < EndIdx; ++Idx) {
   MachineOperand &MO = MI.getOperand(Idx);
-  if (!MO.isReg() || MO.isImplicit())
+  // Leave `undef` operands as is, StackMaps will rewrite them
+  // into a constant.
+  if (!MO.isReg() || MO.isImplicit() || MO.isUndef())
 continue;
   Register Reg = MO.getReg();
   assert(Reg.isPhysical() && "Only physical regs are expected");

diff  --git a/llvm/lib/CodeGen/StackMaps.cpp b/llvm/lib/CodeGen/StackMaps.cpp
index 220e85fe90dc..faf07e90c39c 100644
--- a/llvm/lib/CodeGen/StackMaps.cpp
+++ b/llvm/lib/CodeGen/StackMaps.cpp
@@ -234,6 +234,12 @@ StackMaps::parseOperand(MachineInstr::const_mop_iterator 
MOI,
 if (MOI->isImplicit())
   return ++MOI;
 
+if (MOI->isUndef()) {
+  // Record `undef` register as constant. Use same value as ISel uses.
+  Locs.emplace_back(Location::Constant, sizeof(int64_t), 0, 0xFEFEFEFE);
+  return ++MOI;
+}
+
 assert(Register::isPhysicalRegister(MOI->getReg()) &&
"Virtreg operands should have been rewritten before now.");
 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(MOI->getReg());

diff  --git a/llvm/test/CodeGen/X86/statepoint-fixup-undef.mir 
b/llvm/test/CodeGen/X86/statepoint-fixup-undef.mir
new file mode 100644
index ..434c8400316d
--- /dev/null
+++ b/llvm/test/CodeGen/X86/statepoint-fixup-undef.mir
@@ -0,0 +1,234 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -x mir -run-pass fixup-statepoint-caller-saved 
-verify-machineinstrs < %s | FileCheck %s
+# RUN: llc -x mir -start-before fixup-statepoint-caller-saved 
-verify-machineinstrs < %s | FileCheck %s -check-prefix=STACKMAP
+
+--- |
+  ; ModuleID = 'undef.ll'
+  source_filename = "test_undef.ll"
+  target datalayout = 
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-unknown-linux-gnu"
+
+  define void @test_undef(i8 addrspace(1)* %arg1, i8 addrspace(1)* %arg2, i8 
addrspace(1)* %arg3, i8 addrspace(1)* %arg4) #0 gc "statepoint-example" {
+  bb:
+%tmp1 = lshr i32 0, undef
+%tmp2 = load atomic i32, i32 addrspace(1)* undef unordered, align 8
+%tmp3 = load atomic i32, i32 addrspace(1)* undef unordered, align 8
+br label %bb7
+
+  bb7:  ; preds = %bb
+%tmp4 = icmp slt i32 %tmp3, undef
+%tmp5 = select i1 %tmp4, i32 6, i32 undef
+%tmp6 = add i32 %tmp5, %tmp2
+%tmp7 = call i8 addrspace(1)* @wombat()
+%tmp20 = call token (i64, i32, void (i8 addrspace(1)*, i32, i32, i8 
addrspace(1)*, i32)*, i32, i32, ...) 
@llvm.experimental.gc.statepoint.p0f_isVoidp1i8i32i32p1i8i32f(i64 2, i32 5, 
void (i8 addrspace(1)*, i32, i32, i8 addrspace(1)*, i32)* nonnull @hoge, i32 5, 
i32 0, i8 addrspace(1)* %arg3, i32 %tmp2, i32 %tmp6, i8 addrspace(1)* %tmp7, 
i32 0, i32 0, i32 0) [ "deopt"(i8 addrspace(1)* %arg2, i8 addrspace(1)* %arg1, 
i8 addrspace(1)* %arg3, i8 addrspace(1)* %arg4, i32 %tmp2, i32 %tmp1, i32 
%tmp5), "gc-live"() ]
+ret void
+  }
+
+  declare void @hoge(i8 addrspace(1)*, i32, i32, i8 addrspace(1)*, i32) #0
+
+  declare i8 addrspace(1)* @wombat() #0
+
+  ; Function Attrs: nounwind readonly
+  declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32 
immarg, i32 immarg) #1
+
+  declare token 
@llvm.experimental.gc.statepoint.p0f_isVoidp1i8i32i32p1i8i32f(i64 immarg, i32 
immarg, void (i8 addrspace(1)*, i32, i32, i8 addrspace(1)*, i32)*, i32 immarg, 
i32 immarg, 

[llvm-branch-commits] [llvm] c5771a2 - [Statepoints] Extract invoke tests into separate file. NFC.

2020-12-16 Thread Denis Antrushin via llvm-branch-commits

Author: Denis Antrushin
Date: 2020-12-16T20:53:28+07:00
New Revision: c5771a2f2df995b312a7d5dfc899d7869d6f26d1

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

LOG: [Statepoints] Extract invoke tests into separate file. NFC.

Extract VReg lowering tests with invokes into separate file
for easier maintenance/modification.
Check MIR after register allocation - at this point all
transformations we're interested in has been applied and verifying
of MIR is simpler than that of assembly.

Added: 
llvm/test/CodeGen/X86/statepoint-vreg-invoke.ll

Modified: 
llvm/test/CodeGen/X86/statepoint-vreg-details.ll
llvm/test/CodeGen/X86/statepoint-vreg.ll

Removed: 




diff  --git a/llvm/test/CodeGen/X86/statepoint-vreg-details.ll 
b/llvm/test/CodeGen/X86/statepoint-vreg-details.ll
index 5f6f9c7091e4..39ee1506a39e 100644
--- a/llvm/test/CodeGen/X86/statepoint-vreg-details.ll
+++ b/llvm/test/CodeGen/X86/statepoint-vreg-details.ll
@@ -16,8 +16,6 @@ declare dso_local void @consume(i32 addrspace(1)*)
 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 i32* @fake_personality_function()
-declare dso_local i32 @foo(i32, i8 addrspace(1)*, i32, i32, i32)
 declare dso_local void @bar(i8 addrspace(1)*, i8 addrspace(1)*)
 
 ; test most simple relocate
@@ -317,46 +315,6 @@ entry:
   ret void
 }
 
-; Different IR Values which maps to the same SDValue must be assigned to the 
same VReg.
-; This is test is similar to test_gcptr_uniqueing but explicitly uses invokes 
for which this is important
-; Otherwise we may get a copy of statepoint result, inserted at the end ot 
statepoint block and used at landing pad
-define void @test_duplicate_ir_values() gc "statepoint-example" personality 
i32* ()* @fake_personality_function{
-;CHECK-VREG-LABEL: name:test_duplicate_ir_values
-;CHECK-VREG:   bb.0.entry:
-;CHECK-VREG: %0:gr64 = STATEPOINT 1, 16, 5, %8, $edi, $rsi, $edx, $ecx, 
$r8d, 2, 0, 2, 0, 2, 0, 2, 1, killed %1(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64, 
implicit-def $rsp, implicit-def $ssp, implicit-def $eax
-;CHECK-VREG: JMP_1 %bb.1
-;CHECK-VREG:   bb.1.normal_continue:
-;CHECK-VREG: MOV64mr %stack.0, 1, $noreg, 0, $noreg, %0 :: (store 8 into 
%stack.0)
-;CHECK-VREG: %13:gr32 = MOV32ri 10
-;CHECK-VREG: $edi = COPY %13
-;CHECK-VREG: STATEPOINT 288240, 0, 1, @__llvm_deoptimize, $edi, 2, 0, 
2, 2, 2, 2, 1, 8, %stack.0, 0, 1, 8, %stack.0, 0, 2, 0, 2, 0, 2, 0, csr_64, 
implicit-def $rsp, implicit-def $ssp :: (volatile load store 8 on %stack.0)
-;CHECK-VREG:   bb.2.exceptional_return (landing-pad):
-;CHECK-VREG: EH_LABEL 
-;CHECK-VREG: MOV64mr %stack.0, 1, $noreg, 0, $noreg, %0 :: (store 8 into 
%stack.0)
-;CHECK-VREG: %12:gr32 = MOV32ri -271
-;CHECK-VREG: $edi = COPY %12
-;CHECK-VREG: STATEPOINT 288240, 0, 1, @__llvm_deoptimize, $edi, 2, 0, 
2, 0, 2, 1, 1, 8, %stack.0, 0, 2, 0, 2, 0, 2, 0, csr_64, implicit-def $rsp, 
implicit-def $ssp :: (volatile load store 8 on %stack.0)
-
-entry:
-  %local.0 = load i8 addrspace(1)*, i8 addrspace(1)* addrspace(1)* undef, 
align 8
-  %local.9 = load i8 addrspace(1)*, i8 addrspace(1)* addrspace(1)* undef, 
align 8
-  %statepoint_token1 = invoke token (i64, i32, i32 (i32, i8 addrspace(1)*, 
i32, i32, i32)*, i32, i32, ...) 
@llvm.experimental.gc.statepoint.p0f_i32i32p1i8i32i32i32f(i64 1, i32 16, i32 
(i32, i8 addrspace(1)*, i32, i32, i32)* nonnull @foo, i32 5, i32 0, i32 undef, 
i8 addrspace(1)* undef, i32 undef, i32 undef, i32 undef, i32 0, i32 0) [ 
"deopt"(), "gc-live"(i8 addrspace(1)* %local.0, i8 addrspace(1)* %local.9) ]
-  to label %normal_continue unwind label %exceptional_return
-
-normal_continue: ; preds = %entry
-  %local.0.relocated1 = call coldcc i8 addrspace(1)* 
@llvm.experimental.gc.relocate.p1i8(token %statepoint_token1, i32 0, i32 0) ; 
(%local.0, %local.0)
-  %local.9.relocated1 = call coldcc i8 addrspace(1)* 
@llvm.experimental.gc.relocate.p1i8(token %statepoint_token1, i32 1, i32 1) ; 
(%local.9, %local.9)
-  %safepoint_token2 = call token (i64, i32, void (i32)*, i32, i32, ...) 
@llvm.experimental.gc.statepoint.p0f_isVoidi32f(i64 288240, i32 0, void 
(i32)* nonnull @__llvm_deoptimize, i32 1, i32 2, i32 10, i32 0, i32 0) [ 
"deopt"(i8 addrspace(1)* %local.0.relocated1, i8 addrspace(1)* 
%local.9.relocated1), "gc-live"() ]
-  unreachable
-
-exceptional_return: ; preds = %entry
-  %lpad_token11090 = landingpad token
-  cleanup
-  %local.9.relocated2 = call coldcc i8 addrspace(1)* 
@llvm.experimental.gc.relocate.p1i8(token %lp

[llvm-branch-commits] [llvm] 6f45049 - [Statepoints] Disable VReg lowering for values used on exception path of invoke.

2020-12-21 Thread Denis Antrushin via llvm-branch-commits

Author: Denis Antrushin
Date: 2020-12-21T20:27:05+07:00
New Revision: 6f45049fb6e5c6d573ef5bae338da822f6cbaa53

URL: 
https://github.com/llvm/llvm-project/commit/6f45049fb6e5c6d573ef5bae338da822f6cbaa53
DIFF: 
https://github.com/llvm/llvm-project/commit/6f45049fb6e5c6d573ef5bae338da822f6cbaa53.diff

LOG: [Statepoints] Disable VReg lowering for values used on exception path of 
invoke.

Currently we lower invokes the same way as usual calls, e.g.:

V1 = STATEPOINT ... V (tied-def 0)

But this is incorrect is V1 is used on exceptional path.
By LLVM rules V1 neither dominates its uses in landing pad, nor
its live range is live on entry to landing pad. So compiler is
allowed to do various weird transformations like splitting live
range after statepoint and use split LR in catch block.

Until (and if) we find better solution to this problem, let's
use old lowering (spilling) for those values which are used on
exceptional path and allow VReg lowering for values used only
on normal path.

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

Added: 


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

Removed: 




diff  --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp 
b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
index 2d2eb252e4e2..65ad5b0b5d8f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
@@ -546,6 +546,18 @@ lowerStatepointMetaArgs(SmallVectorImpl &Ops,
   // Decide which deriver pointers will go on VRegs
   unsigned MaxVRegPtrs = MaxRegistersForGCPointers.getValue();
 
+  // Pointers used on exceptional path of invoke statepoint.
+  // We cannot assing them to VRegs.
+  SmallSet LPadPointers;
+  if (auto *StInvoke = dyn_cast_or_null(SI.StatepointInstr)) {
+LandingPadInst *LPI = StInvoke->getLandingPadInst();
+for (auto *Relocate : SI.GCRelocates)
+  if (Relocate->getOperand(0) == LPI) {
+LPadPointers.insert(Builder.getValue(Relocate->getBasePtr()));
+LPadPointers.insert(Builder.getValue(Relocate->getDerivedPtr()));
+  }
+  }
+
   LLVM_DEBUG(dbgs() << "Deciding how to lower GC Pointers:\n");
 
   // List of unique lowered GC Pointer values.
@@ -555,6 +567,14 @@ lowerStatepointMetaArgs(SmallVectorImpl &Ops,
 
   unsigned CurNumVRegs = 0;
 
+  auto canPassGCPtrOnVReg = [&](SDValue SD) {
+if (SD.getValueType().isVector())
+  return false;
+if (LPadPointers.count(SD))
+  return false;
+return !willLowerDirectly(SD);
+  };
+
   auto processGCPtr = [&](const Value *V) {
 SDValue PtrSD = Builder.getValue(V);
 if (!LoweredGCPtrs.insert(PtrSD))
@@ -564,7 +584,9 @@ lowerStatepointMetaArgs(SmallVectorImpl &Ops,
 assert(!LowerAsVReg.count(PtrSD) && "must not have been seen");
 if (LowerAsVReg.size() == MaxVRegPtrs)
   return;
-if (willLowerDirectly(PtrSD) || V->getType()->isVectorTy()) {
+assert(V->getType()->isVectorTy() == PtrSD.getValueType().isVector() &&
+   "IR and SD types disagree");
+if (!canPassGCPtrOnVReg(PtrSD)) {
   LLVM_DEBUG(dbgs() << "direct/spill "; PtrSD.dump(&Builder.DAG));
   return;
 }

diff  --git a/llvm/test/CodeGen/X86/statepoint-vreg-invoke.ll 
b/llvm/test/CodeGen/X86/statepoint-vreg-invoke.ll
index b734dca622ae..7c5a734acd6a 100644
--- a/llvm/test/CodeGen/X86/statepoint-vreg-invoke.ll
+++ b/llvm/test/CodeGen/X86/statepoint-vreg-invoke.ll
@@ -10,14 +10,16 @@ declare dso_local i32* @personality_function()
 define i64 addrspace(1)* @test_basic_invoke(i64 addrspace(1)* %obj, i64 
addrspace(1)* %obj1)
 ; CHECK-LABEL:name: test_basic_invoke
 ; CHECK:  bb.0.entry:
-; CHECK:  renamable $r14, renamable $rbx = STATEPOINT 0, 0, 1, 
@some_call, $rdi, 2, 0, 2, 0, 2, 5, 2, 0, 2, -1, 2, 0, 2, 0, 2, 0, 2, 2, killed 
renamable $r14(tied-def 0), killed renamable $rbx(tied-def 1), 2, 0, 2, 2, 0, 
0, 1, 1, csr_64, implicit-def $rsp, implicit-def $ssp
+; CHECK:  MOV64mr %stack.1, 1, $noreg, 0, $noreg, renamable $rdi :: 
(store 8 into %stack.1)
+; CHECK:  MOV64mr %stack.0, 1, $noreg, 0, $noreg, killed renamable 
$rsi :: (store 8 into %stack.0)
+; CHECK:  STATEPOINT 0, 0, 1, @some_call, $rdi, 2, 0, 2, 0, 2, 5, 2, 
0, 2, -1, 2, 0, 2, 0, 2, 0, 2, 2, 1, 8, %stack.0, 0, 1, 8, %stack.1, 0, 2, 0, 
2, 2, 0, 0, 1, 1, csr_64, implicit-def $rsp, implicit-def $ssp :: (volatile 
load store 8 on %stack.0), (volatile load store 8 on %stack.1)
 ; CHECK:  JMP_1 %bb.1
 ; CHECK:  bb.1.safepoint_normal_dest:
+; CHECK:  renamable $rax = MOV64rm %stack.1, 1, $noreg, 0, $noreg :: 
(load 8 from %stack.1)
 ; CHECK:  bb.2.normal_return:
-; CHECK:  $rax = COPY killed renamable $rbx
 ; CHECK:  RET 0, $rax
 ; CHECK:  bb.3.exceptional_return (landing-pad):
-; CHECK:  $rax = COPY ki