Index: lib/Target/AMDGPU/AMDGPUAsmPrinter.h =================================================================== --- lib/Target/AMDGPU/AMDGPUAsmPrinter.h +++ lib/Target/AMDGPU/AMDGPUAsmPrinter.h @@ -111,6 +111,11 @@ /// pseudo lowering. bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const; + /// \brief Lower the specified LLVM Constant to an MCExpr. + /// The AsmPrinter::lowerConstantof does not know how to lower + /// addrspacecast, therefore they should be lowered by this function. + const MCExpr *lowerConstant(const Constant *CV) override; + /// \brief tblgen'erated driver function for lowering simple MI->MC pseudo /// instructions. bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, Index: lib/Target/AMDGPU/AMDGPUMCInstLower.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUMCInstLower.cpp +++ lib/Target/AMDGPU/AMDGPUMCInstLower.cpp @@ -151,6 +151,27 @@ return MCInstLowering.lowerOperand(MO, MCOp); } +const MCExpr *AMDGPUAsmPrinter::lowerConstant(const Constant *CV) { + auto CE = dyn_cast(CV); + + // Lower null pointers in private and local address space. + // Clang generates addrspacecast for null pointers in private and local + // address space, which needs to be lowered. + if (CE && CE->getOpcode() == Instruction::AddrSpaceCast) { + auto Op = CE->getOperand(0); + if (Op->isNullValue()) { + auto SrcAddr = Op->getType()->getPointerAddressSpace(); + auto DstAddr = CE->getType()->getPointerAddressSpace(); + if (SrcAddr == AMDGPUAS::FLAT_ADDRESS && + (DstAddr == AMDGPUAS::PRIVATE_ADDRESS || + DstAddr == AMDGPUAS::LOCAL_ADDRESS)) { + return MCConstantExpr::create(-1, OutContext); + } + } + } + return AsmPrinter::lowerConstant(CV); +} + void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) { if (emitPseudoExpansionLowering(*OutStreamer, MI)) return; Index: test/CodeGen/AMDGPU/nullptr.ll =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/nullptr.ll @@ -0,0 +1,20 @@ +;RUN: llc < %s -march=amdgcn -verify-machineinstrs | FileCheck %s + +%struct.S = type { i32 addrspace(1)*, i32 addrspace(3)*, i32* } + +; CHECK-LABEL: nullptr_priv: +; CHECK-NEXT: .long -1 +@nullptr_priv = global i32* addrspacecast (i32 addrspace(4)* null to i32*) + +; CHECK-LABEL: nullptr_local: +; CHECK-NEXT: .long -1 +@nullptr_local = global i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*) + +; CHECK-LABEL: structWithPointers: +; CHECK-NEXT: .quad 0 +; CHECK-NEXT: .long -1 +; CHECK-NEXT: .long -1 +@structWithPointers = addrspace(1) global %struct.S { + i32 addrspace(1)* null, + i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*), + i32* addrspacecast (i32 addrspace(4)* null to i32*) }, align 4