Index: include/llvm/CodeGen/SelectionDAGNodes.h =================================================================== --- include/llvm/CodeGen/SelectionDAGNodes.h +++ include/llvm/CodeGen/SelectionDAGNodes.h @@ -650,6 +650,9 @@ /// corresponding to a MachineInstr opcode. bool isMachineOpcode() const { return NodeType < 0; } + /// Test if this node is an inline ASM. + bool isInlineAsm() const { return NodeType == ISD::INLINEASM; } + /// This may only be called if isMachineOpcode returns /// true. It returns the MachineInstr opcode value that the node's opcode /// corresponds to. Index: lib/CodeGen/SelectionDAG/InstrEmitter.cpp =================================================================== --- lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -129,12 +129,35 @@ if (VT == MVT::Other || VT == MVT::Glue) continue; Match = false; - if (User->isMachineOpcode()) { - const MCInstrDesc &II = TII->get(User->getMachineOpcode()); + { const TargetRegisterClass *RC = nullptr; - if (i+II.getNumDefs() < II.getNumOperands()) { - RC = TRI->getAllocatableClass( - TII->getRegClass(II, i+II.getNumDefs(), TRI, *MF)); + + if (User->isMachineOpcode()) { + const MCInstrDesc &II = TII->get(User->getMachineOpcode()); + if (i + II.getNumDefs() < II.getNumOperands()) { + RC = TRI->getAllocatableClass( + TII->getRegClass(II, i + II.getNumDefs(), TRI, *MF)); + } + } + + // Constrain register class to target pointer class if it's a memory + // register in inline asm. + if (User->isInlineAsm()) { + unsigned FlagIdx; + unsigned Flags; + unsigned NumOps; + // Look up the flags for the register. See InlineAsm.h. + for (FlagIdx = InlineAsm::Op_FirstOperand; FlagIdx < e; + FlagIdx += NumOps) { + Flags = User->getConstantOperandVal(FlagIdx); + NumOps = 1 + InlineAsm::getNumOperandRegisters(Flags); + if (FlagIdx + NumOps > i) + break; + } + Flags = User->getConstantOperandVal(FlagIdx); + if (InlineAsm::isMemKind(Flags)) { + RC = TRI->getPointerRegClass(*MF); + } } if (!UseRC) UseRC = RC; Index: lib/Target/AArch64/AArch64RegisterInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64RegisterInfo.cpp +++ lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -167,7 +167,7 @@ const TargetRegisterClass * AArch64RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind) const { - return &AArch64::GPR64RegClass; + return &AArch64::GPR64spRegClass; } const TargetRegisterClass * Index: test/CodeGen/AArch64/asm-zero-address.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/asm-zero-address.ll @@ -0,0 +1,9 @@ +; RUN: llc < %s -mtriple=aarch64-eabi | FileCheck %s + +define void @test() { +entry: +; CHECK: mov {{x[0-9]+}}, xzr +; CHECK: ldr {{x[0-9]+}}, {{[x[0-9]+]}} + tail call i32 asm sideeffect "ldr $0, $1 \0A", "=r,*Q"(i32* null) + ret void +}