From bb3883dfbab9a48176497066ed40911431e0fda8 Mon Sep 17 00:00:00 2001 From: Swaroop Sridhar Date: Thu, 4 Jun 2015 23:03:21 +0000 Subject: [PATCH] Statepoint: Fix handling of Far Immediate calls gc.statepoint intrinsics with a far immediate call target were lowered incorrectly as pc-rel32 calls. This change fixes the problem, and generates an indirect call via a scratch register. For example: Intrinsic: %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* inttoptr (i64 140727162896504 to void ()*), i32 0, i32 0, i32 0, i32 0) Old Incorrect Lowering: callq 140727162896504 New Correct Lowering: movabsq $140727162896504, %rax callq *%rax In lowerCallFromStatepoint(), the callee-target was modified and represented as a "TargetConstant" node, rather than a "Constant" node. Undoing this modification enabled LowerCall() to generate the correct CALL instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239114 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../SelectionDAG/StatepointLowering.cpp | 11 ---------- test/CodeGen/X86/statepoint-far-call.ll | 22 +++++++++++++++++++ 2 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 test/CodeGen/X86/statepoint-far-call.ll diff --git a/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/lib/CodeGen/SelectionDAG/StatepointLowering.cpp index 2d4ab6c5077..8bbfa01e759 100644 --- a/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ b/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -238,17 +238,6 @@ lowerCallFromStatepoint(ImmutableStatepoint ISP, MachineBasicBlock *LandingPad, SDValue ActualCallee = Builder.getValue(ISP.getActualCallee()); - // Handle immediate and symbolic callees. - if (auto *ConstCallee = dyn_cast(ActualCallee.getNode())) - ActualCallee = Builder.DAG.getIntPtrConstant(ConstCallee->getZExtValue(), - Builder.getCurSDLoc(), - /*isTarget=*/true); - else if (auto *SymbolicCallee = - dyn_cast(ActualCallee.getNode())) - ActualCallee = Builder.DAG.getTargetGlobalAddress( - SymbolicCallee->getGlobal(), SDLoc(SymbolicCallee), - SymbolicCallee->getValueType(0)); - assert(CS.getCallingConv() != CallingConv::AnyReg && "anyregcc is not supported on statepoints!"); diff --git a/test/CodeGen/X86/statepoint-far-call.ll b/test/CodeGen/X86/statepoint-far-call.ll new file mode 100644 index 00000000000..cd8dd0f35a2 --- /dev/null +++ b/test/CodeGen/X86/statepoint-far-call.ll @@ -0,0 +1,22 @@ +; RUN: llc < %s | FileCheck %s +; Test to check that Statepoints with X64 far-immediate targets +; are lowered correctly to an indirect call via a scratch register. + +target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-win64" + +define void @test_far_call() gc "statepoint-example" { +; CHECK-LABEL: test_far_call +; CHECK: pushq %rax +; CHECK: movabsq $140727162896504, %rax +; CHECK: callq *%rax +; CHECK: popq %rax +; CHECK: retq + +entry: + %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* inttoptr (i64 140727162896504 to void ()*), i32 0, i32 0, i32 0, i32 0) + ret void +} + +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) + -- 2.34.1