mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 23:20:54 +00:00
[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
This commit is contained in:
parent
85df5176ce
commit
d14a49a05f
@ -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,
|
||||
|
@ -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<AMDGPUTargetMachine*>(&TM);
|
||||
auto *CE = dyn_cast<ConstantExpr>(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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
113
test/CodeGen/AMDGPU/nullptr.ll
Normal file
113
test/CodeGen/AMDGPU/nullptr.ll
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user