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 @@ -17,6 +17,7 @@ #include "AMDGPUAsmPrinter.h" #include "AMDGPUSubtarget.h" #include "AMDGPUTargetMachine.h" +#include "Utils/AMDGPUConstantFoldUtils.h" #include "InstPrinter/AMDGPUInstPrinter.h" #include "SIInstrInfo.h" #include "llvm/CodeGen/MachineBasicBlock.h" @@ -151,6 +152,13 @@ return MCInstLowering.lowerOperand(MO, MCOp); } +const MCExpr *AMDGPUAsmPrinter::lowerConstant(const Constant *CV) { + if (AMDGPU::isNonZeroNullPointer(CV)) { + return MCConstantExpr::create(-1, OutContext); + } + return AsmPrinter::lowerConstant(CV); +} + void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) { if (emitPseudoExpansionLowering(*OutStreamer, MI)) return; Index: lib/Target/AMDGPU/Utils/AMDGPUConstantFoldUtils.h =================================================================== --- /dev/null +++ lib/Target/AMDGPU/Utils/AMDGPUConstantFoldUtils.h @@ -0,0 +1,25 @@ +//===-- AMDGPUConstantFoldUtils.h - Constant fold utilities -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_AMDGPU_UTILS_AMDGPUCONSTANTFOLDUTILS_H +#define LLVM_LIB_TARGET_AMDGPU_UTILS_AMDGPUCONSTANTFOLDUTILS_H + +namespace llvm { + +class Constant; + +namespace AMDGPU { + +bool isNonZeroNullPointer(const Constant *C); + + +} // namespace AMDGPU +} // namespace llvm + +#endif Index: lib/Target/AMDGPU/Utils/AMDGPUConstantFoldUtils.cpp =================================================================== --- /dev/null +++ lib/Target/AMDGPU/Utils/AMDGPUConstantFoldUtils.cpp @@ -0,0 +1,39 @@ +//===-- AMDGPUConstantFoldUtils.cpp - Constant fold utilities -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "AMDGPUConstantFoldUtils.h" +#include "AMDGPU.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Instructions.h" + +namespace llvm { +namespace AMDGPU { + +bool isNonZeroNullPointer(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 true; + } + } + } + return false; +} + +} // namespace AMDGPU +} // namespace llvm Index: lib/Target/AMDGPU/Utils/CMakeLists.txt =================================================================== --- lib/Target/AMDGPU/Utils/CMakeLists.txt +++ lib/Target/AMDGPU/Utils/CMakeLists.txt @@ -1,5 +1,6 @@ add_llvm_library(LLVMAMDGPUUtils AMDGPUBaseInfo.cpp + AMDGPUConstantFoldUtils.cpp AMDKernelCodeTUtils.cpp AMDGPUAsmUtils.cpp ) 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