From 586272d67ca0cd91e49aa0f03298cc1294128385 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Thu, 11 Aug 2011 01:48:05 +0000 Subject: [PATCH] Fix X86TargetLowering::LowerExternalSymbol so that it actually works in non-trivial cases. This hasn't been an issue before because the function isn't normally called (but apparently is used to generate a tail-call to sin() on ELF x86-32 with PIC and SSE2). Fixes PR9693. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137292 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 21 ++++++++++++++++----- test/CodeGen/X86/tail-call-got.ll | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/X86/tail-call-got.ll diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index d709bc09da9..217a7bcf530 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -6758,12 +6758,17 @@ X86TargetLowering::LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const { CodeModel::Model M = getTargetMachine().getCodeModel(); if (Subtarget->isPICStyleRIPRel() && - (M == CodeModel::Small || M == CodeModel::Kernel)) + (M == CodeModel::Small || M == CodeModel::Kernel)) { + if (Subtarget->isTargetDarwin() || Subtarget->isTargetELF()) + OpFlag = X86II::MO_GOTPCREL; WrapperKind = X86ISD::WrapperRIP; - else if (Subtarget->isPICStyleGOT()) - OpFlag = X86II::MO_GOTOFF; - else if (Subtarget->isPICStyleStubPIC()) - OpFlag = X86II::MO_PIC_BASE_OFFSET; + } else if (Subtarget->isPICStyleGOT()) { + OpFlag = X86II::MO_GOT; + } else if (Subtarget->isPICStyleStubPIC()) { + OpFlag = X86II::MO_DARWIN_NONLAZY_PIC_BASE; + } else if (Subtarget->isPICStyleStubNoDynamic()) { + OpFlag = X86II::MO_DARWIN_NONLAZY; + } SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy(), OpFlag); @@ -6780,6 +6785,12 @@ X86TargetLowering::LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const { Result); } + // For symbols that require a load from a stub to get the address, emit the + // load. + if (isGlobalStubReference(OpFlag)) + Result = DAG.getLoad(getPointerTy(), DL, DAG.getEntryNode(), Result, + MachinePointerInfo::getGOT(), false, false, 0); + return Result; } diff --git a/test/CodeGen/X86/tail-call-got.ll b/test/CodeGen/X86/tail-call-got.ll new file mode 100644 index 00000000000..8910ee272db --- /dev/null +++ b/test/CodeGen/X86/tail-call-got.ll @@ -0,0 +1,24 @@ +; RUN: llc < %s -relocation-model=pic | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" +target triple = "i386-unknown-freebsd9.0" + +define double @test1(double %x) nounwind readnone { +; CHECK: test1: +; CHECK: movl foo@GOT +; CHECK-NEXT: jmpl + %1 = tail call double @foo(double %x) nounwind readnone + ret double %1 +} + +declare double @foo(double) readnone + +define double @test2(double %x) nounwind readnone { +; CHECK: test2: +; CHECK: movl sin@GOT +; CHECK-NEXT: jmpl + %1 = tail call double @sin(double %x) nounwind readnone + ret double %1 +} + +declare double @sin(double) readnone