Index: llvm/lib/Target/X86/X86FastISel.cpp =================================================================== --- llvm/lib/Target/X86/X86FastISel.cpp +++ llvm/lib/Target/X86/X86FastISel.cpp @@ -745,6 +745,12 @@ AM.Base.Reg = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF); } + bool NeedLoad = GVFlags == X86II::MO_GOTPCREL; + if (NeedLoad) { + assert(AM.Base.Reg == 0 && AM.IndexReg == 0); + AM.Base.Reg = X86::RIP; + } + // Unless the ABI requires an extra load, return a direct reference to // the global. if (!isGlobalStubReference(GVFlags)) { Index: llvm/test/CodeGen/X86/pr39252.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/pr39252.ll @@ -0,0 +1,27 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -fast-isel=1 | FileCheck %s -check-prefix=FASTISEL + +%"g1" = type { i8 } + +@g2 = internal global %"g1" zeroinitializer, align 1 +@__dso_handle = external hidden global i8 + +define internal void @foobar() #0 { +entry: + call void @foo(%"g1"* @g2) + %0 = call i32 @func(void (i8*)* bitcast (void (%"g1"*)* @bar to void (i8*)*), i8* getelementptr inbounds (%"g1", %"g1"* @g2, i32 0, i32 0), i8* @__dso_handle) #3 + ret void +; FASTISEL: movq bar@GOTPCREL(%rip), %rdi +} + +declare void @foo(%"g1"*) unnamed_addr #1 + +declare void @bar(%"g1"*) unnamed_addr #2 + +declare i32 @func(void (i8*)*, i8*, i8*) #3 + +attributes #0 = { noinline uwtable } +attributes #1 = { nonlazybind } +attributes #2 = { nounwind nonlazybind } +attributes #3 = { nounwind } + +