[PATCH] D34999: [CodeGen] InstrEmitter should constrain register class for inline ASM
Yi Kong via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 5 01:23:47 PDT 2017
kongyi created this revision.
Herald added subscribers: javed.absar, aemerson.
For inline ASM, memory constraints should restrict register class to the target specific pointer register class, otherwise LLVM may emit instructions with a memory operand using a non-memory register, producing illegal assembly.
Also fix the pointer register class for AArch64 from GPR64 to GPR64sp, since XZR cannot hold a memory pointer while SP is.
Fixes PR33134.
Repository:
rL LLVM
https://reviews.llvm.org/D34999
Files:
include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/InstrEmitter.cpp
lib/Target/AArch64/AArch64RegisterInfo.cpp
test/CodeGen/AArch64/asm-zero-address.ll
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
+}
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: 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: 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34999.105226.patch
Type: text/x-patch
Size: 3473 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170705/9df1339c/attachment-0001.bin>
More information about the llvm-commits
mailing list