From: Yaxun Liu Date: Tue, 7 Feb 2017 00:43:21 +0000 (+0000) Subject: [AMDGPU] Lower null pointers in static variable initializer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d14a49a05f1100b06c1f25213ac366ee0578c7ca;p=llvm [AMDGPU] Lower null pointers in static variable initializer For amdgcn target Clang generates addrspacecast to represent null pointers in private and local address spaces. In LLVM codegen, the static variable initializer is lowered by virtual function AsmPrinter::lowerConstant which is target generic. Since addrspacecast is target specific, AsmPrinter::lowerConst This patch overrides AsmPrinter::lowerConstant with AMDGPUAsmPrinter::lowerConstant, which is able to lower the target-specific addrspacecast in the null pointer representation so that -1 is co Differential Revision: https://reviews.llvm.org/D29284 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294265 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AMDGPU/AMDGPUAsmPrinter.h b/lib/Target/AMDGPU/AMDGPUAsmPrinter.h index 99fa157a3ec..3dfc9ee66c2 100644 --- a/lib/Target/AMDGPU/AMDGPUAsmPrinter.h +++ b/lib/Target/AMDGPU/AMDGPUAsmPrinter.h @@ -111,6 +111,11 @@ public: /// 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, diff --git a/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp b/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp index 140fd4fc988..9823fe4ff02 100644 --- a/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp +++ b/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp @@ -151,6 +151,28 @@ bool AMDGPUAsmPrinter::lowerOperand(const MachineOperand &MO, return MCInstLowering.lowerOperand(MO, MCOp); } +const MCExpr *AMDGPUAsmPrinter::lowerConstant(const Constant *CV) { + // TargetMachine does not support llvm-style cast. Use C++-style cast. + // This is safe since TM is always of type AMDGPUTargetMachine or its + // derived class. + auto *AT = static_cast(&TM); + 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); + auto SrcAddr = Op->getType()->getPointerAddressSpace(); + if (Op->isNullValue() && AT->getNullPointerValue(SrcAddr) == 0) { + auto DstAddr = CE->getType()->getPointerAddressSpace(); + return MCConstantExpr::create(AT->getNullPointerValue(DstAddr), + OutContext); + } + } + return AsmPrinter::lowerConstant(CV); +} + void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) { if (emitPseudoExpansionLowering(*OutStreamer, MI)) return; diff --git a/lib/Target/AMDGPU/AMDGPUTargetMachine.h b/lib/Target/AMDGPU/AMDGPUTargetMachine.h index e6981943f49..bf0b9543b89 100644 --- a/lib/Target/AMDGPU/AMDGPUTargetMachine.h +++ b/lib/Target/AMDGPU/AMDGPUTargetMachine.h @@ -59,6 +59,18 @@ public: } void adjustPassManager(PassManagerBuilder &) override; + /// Get the integer value of a null pointer in the given address space. + uint64_t getNullPointerValue(unsigned AddrSpace) const { + switch(AddrSpace) { + case AMDGPUAS::PRIVATE_ADDRESS: + case AMDGPUAS::LOCAL_ADDRESS: + case AMDGPUAS::REGION_ADDRESS: + return -1; + default: + return 0; + } + } + }; //===----------------------------------------------------------------------===// diff --git a/test/CodeGen/AMDGPU/nullptr.ll b/test/CodeGen/AMDGPU/nullptr.ll new file mode 100644 index 00000000000..b4bdf71fa90 --- /dev/null +++ b/test/CodeGen/AMDGPU/nullptr.ll @@ -0,0 +1,113 @@ +;RUN: llc < %s -march=amdgcn -verify-machineinstrs | FileCheck %s + +%struct.S = type { i32*, i32 addrspace(1)*, i32 addrspace(2)*, i32 addrspace(3)*, i32 addrspace(4)*, i32 addrspace(5)*} + +; CHECK-LABEL: nullptr_priv: +; CHECK-NEXT: .long -1 +@nullptr_priv = global i32* addrspacecast (i32 addrspace(4)* null to i32*) + +; CHECK-LABEL: nullptr_glob: +; CHECK-NEXT: .quad 0 +@nullptr_glob = global i32 addrspace(1)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(1)*) + +; CHECK-LABEL: nullptr_const: +; CHECK-NEXT: .quad 0 +@nullptr_const = global i32 addrspace(2)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(2)*) + +; 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: nullptr_region: +; CHECK-NEXT: .long -1 +@nullptr_region = global i32 addrspace(5)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(5)*) + +; CHECK-LABEL: nullptr6: +; CHECK-NEXT: .long 0 +@nullptr6 = global i32 addrspace(6)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(6)*) + +; CHECK-LABEL: nullptr7: +; CHECK-NEXT: .long 0 +@nullptr7 = global i32 addrspace(7)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(7)*) + +; CHECK-LABEL: nullptr8: +; CHECK-NEXT: .long 0 +@nullptr8 = global i32 addrspace(8)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(8)*) + +; CHECK-LABEL: nullptr9: +; CHECK-NEXT: .long 0 +@nullptr9 = global i32 addrspace(9)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(9)*) + +; CHECK-LABEL: nullptr10: +; CHECK-NEXT: .long 0 +@nullptr10 = global i32 addrspace(10)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(10)*) + +; CHECK-LABEL: nullptr11: +; CHECK-NEXT: .long 0 +@nullptr11 = global i32 addrspace(11)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(11)*) + +; CHECK-LABEL: nullptr12: +; CHECK-NEXT: .long 0 +@nullptr12 = global i32 addrspace(12)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(12)*) + +; CHECK-LABEL: nullptr13: +; CHECK-NEXT: .long 0 +@nullptr13 = global i32 addrspace(13)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(13)*) + +; CHECK-LABEL: nullptr14: +; CHECK-NEXT: .long 0 +@nullptr14 = global i32 addrspace(14)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(14)*) + +; CHECK-LABEL: nullptr15: +; CHECK-NEXT: .long 0 +@nullptr15 = global i32 addrspace(15)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(15)*) + +; CHECK-LABEL: nullptr16: +; CHECK-NEXT: .long 0 +@nullptr16 = global i32 addrspace(16)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(16)*) + +; CHECK-LABEL: nullptr17: +; CHECK-NEXT: .long 0 +@nullptr17 = global i32 addrspace(17)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(17)*) + +; CHECK-LABEL: nullptr18: +; CHECK-NEXT: .long 0 +@nullptr18 = global i32 addrspace(18)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(18)*) + +; CHECK-LABEL: nullptr19: +; CHECK-NEXT: .long 0 +@nullptr19 = global i32 addrspace(19)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(19)*) + +; CHECK-LABEL: nullptr20: +; CHECK-NEXT: .long 0 +@nullptr20 = global i32 addrspace(20)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(20)*) + +; CHECK-LABEL: nullptr21: +; CHECK-NEXT: .long 0 +@nullptr21 = global i32 addrspace(21)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(21)*) + +; CHECK-LABEL: nullptr22: +; CHECK-NEXT: .long 0 +@nullptr22 = global i32 addrspace(22)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(22)*) + +; CHECK-LABEL: nullptr23: +; CHECK-NEXT: .long 0 +@nullptr23 = global i32 addrspace(23)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(23)*) + +; CHECK-LABEL: structWithPointers: +; CHECK-NEXT: .long -1 +; CHECK-NEXT: .zero 4 +; CHECK-NEXT: .quad 0 +; CHECK-NEXT: .quad 0 +; CHECK-NEXT: .long -1 +; CHECK-NEXT: .zero 4 +; CHECK-NEXT: .quad 0 +; CHECK-NEXT: .long -1 +; CHECK-NEXT: .zero 4 +@structWithPointers = addrspace(1) global %struct.S { + i32* addrspacecast (i32 addrspace(4)* null to i32*), + i32 addrspace(1)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(1)*), + i32 addrspace(2)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(2)*), + i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*), + i32 addrspace(4)* null, + i32 addrspace(5)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(5)*)}, align 4