From: Amara Emerson Date: Tue, 31 Jul 2018 00:08:50 +0000 (+0000) Subject: [GlobalISel] Add a G_BLOCK_ADDR opcode to handle IR blockaddress constants. X-Git-Tag: llvmorg-7.0.0-rc1~224 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6aff5a78101aef500fa6c797ad00db204f1e83bc;p=platform%2Fupstream%2Fllvm.git [GlobalISel] Add a G_BLOCK_ADDR opcode to handle IR blockaddress constants. Differential Revision: https://reviews.llvm.org/D49900 llvm-svn: 338335 --- diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index 983a4e6..ac1673d 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -942,6 +942,16 @@ public: /// \return a MachineInstrBuilder for the newly created instruction. MachineInstrBuilder buildAtomicRMWUmin(unsigned OldValRes, unsigned Addr, unsigned Val, MachineMemOperand &MMO); + + /// Build and insert \p Res = G_BLOCK_ADDR \p BA + /// + /// G_BLOCK_ADDR computes the address of a basic block. + /// + /// \pre setBasicBlock or setMI must have been called. + /// \pre \p Res must be a generic virtual register of a pointer type. + /// + /// \return The newly created instruction. + MachineInstrBuilder buildBlockAddress(unsigned Res, const BlockAddress *BA); }; /// A CRTP class that contains methods for building instructions that can diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def index 21f5c7e..63491a5 100644 --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -470,12 +470,15 @@ HANDLE_TARGET_OPCODE(G_BSWAP) /// Generic AddressSpaceCast. HANDLE_TARGET_OPCODE(G_ADDRSPACE_CAST) +/// Generic block address +HANDLE_TARGET_OPCODE(G_BLOCK_ADDR) + // TODO: Add more generic opcodes as we move along. /// Marker for the end of the generic opcode. /// This is used to check if an opcode is in the range of the /// generic opcodes. -HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_ADDRSPACE_CAST) +HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_BLOCK_ADDR) /// BUILTIN_OP_END - This must be the last enum value in this list. /// The target-specific post-isel opcode values start here. diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index d72746a..79cc1e4 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -131,6 +131,13 @@ def G_ADDRSPACE_CAST : GenericInstruction { let InOperandList = (ins type1:$src); let hasSideEffects = 0; } + +def G_BLOCK_ADDR : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins unknown:$ba); + let hasSideEffects = 0; +} + //------------------------------------------------------------------------------ // Binary ops. //------------------------------------------------------------------------------ diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index bafb7a0..e76c40f 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1503,6 +1503,8 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) { Ops.push_back(getOrCreateVReg(*CV->getOperand(i))); } EntryBuilder.buildMerge(Reg, Ops); + } else if (auto *BA = dyn_cast(&C)) { + EntryBuilder.buildBlockAddress(Reg, BA); } else return false; diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 9df931e..3271b54 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -809,6 +809,15 @@ MachineIRBuilderBase::buildAtomicRMWUmin(unsigned OldValRes, unsigned Addr, MMO); } +MachineInstrBuilder +MachineIRBuilderBase::buildBlockAddress(unsigned Res, const BlockAddress *BA) { +#ifndef NDEBUG + assert(getMRI()->getType(Res).isPointer() && "invalid res type"); +#endif + + return buildInstr(TargetOpcode::G_BLOCK_ADDR).addDef(Res).addBlockAddress(BA); +} + void MachineIRBuilderBase::validateTruncExt(unsigned Dst, unsigned Src, bool IsExtend) { #ifndef NDEBUG diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 65c6a4f..89c1f0d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -2147,3 +2147,15 @@ define i32 @test_atomicrmw_umax(i256* %addr) { %oldval.trunc = trunc i256 %oldval to i32 ret i32 %oldval.trunc } + +@addr = global i8* null + +define void @test_blockaddress() { +; CHECK-LABEL: name: test_blockaddress +; CHECK: [[BADDR:%[0-9]+]]:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block) +; CHECK: G_STORE [[BADDR]](p0) + store i8* blockaddress(@test_blockaddress, %block), i8** @addr + indirectbr i8* blockaddress(@test_blockaddress, %block), [label %block] +block: + ret void +}