diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h --- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h +++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h @@ -61,9 +61,9 @@ bool legalizeSinCos(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B) const; - bool buildPCRelGlobalAddress( - Register DstReg, LLT PtrTy, MachineIRBuilder &B, const GlobalValue *GV, - unsigned Offset, unsigned GAFlags = SIInstrInfo::MO_NONE) const; + bool buildPCRelGlobalAddress(Register DstReg, LLT PtrTy, MachineIRBuilder &B, + const GlobalValue *GV, int64_t Offset, + unsigned GAFlags = SIInstrInfo::MO_NONE) const; bool legalizeGlobalValue(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B) const; diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp @@ -2003,10 +2003,12 @@ return true; } -bool AMDGPULegalizerInfo::buildPCRelGlobalAddress( - Register DstReg, LLT PtrTy, - MachineIRBuilder &B, const GlobalValue *GV, - unsigned Offset, unsigned GAFlags) const { +bool AMDGPULegalizerInfo::buildPCRelGlobalAddress(Register DstReg, LLT PtrTy, + MachineIRBuilder &B, + const GlobalValue *GV, + int64_t Offset, + unsigned GAFlags) const { + assert(isInt<32>(Offset + 4) && "32-bit offset is expected!"); // In order to support pc-relative addressing, SI_PC_ADD_REL_OFFSET is lowered // to the following code sequence: // diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -5461,8 +5461,9 @@ static SDValue buildPCRelGlobalAddress(SelectionDAG &DAG, const GlobalValue *GV, - const SDLoc &DL, unsigned Offset, EVT PtrVT, + const SDLoc &DL, int64_t Offset, EVT PtrVT, unsigned GAFlags = SIInstrInfo::MO_NONE) { + assert(isInt<32>(Offset + 4) && "32-bit offset is expected!"); // In order to support pc-relative addressing, the PC_ADD_REL_OFFSET SDNode is // lowered to the following code sequence: // diff --git a/llvm/test/CodeGen/AMDGPU/rel32.ll b/llvm/test/CodeGen/AMDGPU/rel32.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/rel32.ll @@ -0,0 +1,12 @@ +; RUN: llc -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck %s + +@g = protected local_unnamed_addr addrspace(4) externally_initialized global i32 0, align 4 + +; CHECK-LABEL: rel32_neg_offset: +; CHECK: s_getpc_b64 s{{\[}}[[LO:[0-9]+]]:[[HI:[0-9]+]]{{]}} +; CHECK: s_add_u32 s[[LO]], s[[LO]], g@rel32@lo-4 +; CHECK: s_addc_u32 s[[HI]], s[[HI]], g@rel32@hi-4 +define i32 addrspace(4)* @rel32_neg_offset() { + %r = getelementptr i32, i32 addrspace(4)* @g, i64 -2 + ret i32 addrspace(4)* %r +}