[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