[PATCH] D46745: [AArch64] Support "S" inline assembler constraint

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 11 03:35:50 PDT 2018


peter.smith created this revision.
peter.smith added reviewers: t.p.northover, niravd, manojgupta.
Herald added subscribers: kristof.beyls, eraman, dschuff, rengolin.
Herald added a reviewer: javed.absar.

This patch re-introduces the "S" inline assembler constraint. This matches an absolute symbolic address or a label reference [3]. My understanding is that its primary use case is in a code sequence like:

  asm("adrp %0, %1\n\t"
          "add %0, %0, :lo12:%1" : "=r"(addr) : "S"(&var));

I say re-introduces because it seems like "S" was implemented by Tim in the original AArch64 backend, but looks like it wasn't carried forward to the merge with the ARM64 backend. I couldn't find any commit message or mail thread mentioning why, I'm hoping that it wasn't for a fundamental flaw. I've put links to an old git repository that happens to have the old files there.

The implementation is heavily based on the original implementation. I haven't implemented the A and L modifiers that were in the original implementation as these don't appear to be supported by GCC, or at least the version of GCC that I was using. For reference the A is ignored for an ADRP, but the L generates the ":lo12:" string. I think the expectation is that users will write the ":lo12:" in the inline asm string as in the example above.

The "S" modifier is already supported in Clang. I haven't needed to change that, there is a test case in aarch64-inline-asm.c that should be updated to not use the A and L modifiers. For reference it looks like:

  asm("adrp %0, %A1\n\t"
          "add %0, %0, %L1" : "=r"(addr) : "S"(&var));

I can submit a follow up patch to do that.

My understanding is that "S" modifier is used in the Linux kernel and there isn't a clang/gcc compatible alternative.

Fixes PR37180

References: 
[1] PR37180 https://bugs.llvm.org/show_bug.cgi?id=37180
[2]  Linux kernel commit containing use of "S" https://github.com/torvalds/linux/commit/44a497abd621a71c645f06d3d545ae2f46448830
[3] GCC documentation for machine specific constraints https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints
[4] Links to old AArch64 backend. 
https://chromium.googlesource.com/native_client/pnacl-llvm/+/upstream/master/test/CodeGen/AArch64/inline-asm-constraints.ll
https://chromium.googlesource.com/native_client/pnacl-llvm/+/upstream/master/lib/Target/AArch64/AArch64AsmPrinter.cpp
https://chromium.googlesource.com/native_client/pnacl-llvm/+/upstream/master/lib/Target/AArch64/AArch64ISelLowering.cpp


https://reviews.llvm.org/D46745

Files:
  lib/Target/AArch64/AArch64AsmPrinter.cpp
  lib/Target/AArch64/AArch64ISelLowering.cpp
  test/CodeGen/AArch64/inlineasm-S-constraint.ll


Index: test/CodeGen/AArch64/inlineasm-S-constraint.ll
===================================================================
--- /dev/null
+++ test/CodeGen/AArch64/inlineasm-S-constraint.ll
@@ -0,0 +1,20 @@
+;RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+neon < %s | FileCheck %s
+ at var = global i32 0
+define void @test_inline_constraint_S() {
+; CHECK-LABEL: test_inline_constraint_S:
+  call void asm sideeffect "adrp x0, $0", "S"(i32* @var)
+  call void asm sideeffect "add x0, x0, :lo12:$0", "S"(i32* @var)
+; CHECK: adrp x0, var
+; CHECK: add x0, x0, :lo12:var
+  ret void
+}
+define i32 @test_inline_constraint_S_label(i1 %in) {
+; CHECK-LABEL: test_inline_constraint_S_label:
+  call void asm sideeffect "adr x0, $0", "S"(i8* blockaddress(@test_inline_constraint_S_label, %loc))
+; CHECK: adr x0, .Ltmp{{[0-9]+}}
+br i1 %in, label %loc, label %loc2
+loc:
+  ret i32 0
+loc2:
+  ret i32 42
+}
Index: lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- lib/Target/AArch64/AArch64ISelLowering.cpp
+++ lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -5207,7 +5207,7 @@
 
 // Table of Constraints
 // TODO: This is the current set of constraints supported by ARM for the
-// compiler, not all of them may make sense, e.g. S may be difficult to support.
+// compiler, not all of them may make sense.
 //
 // r - A general register
 // w - An FP/SIMD register of some size in the range v0-v31
@@ -5267,6 +5267,8 @@
     // currently handle addresses it is the same as 'r'.
     case 'Q':
       return C_Memory;
+    case 'S': // A symbolic address
+      return C_Other;
     }
   }
   return TargetLowering::getConstraintType(Constraint);
@@ -5391,6 +5393,23 @@
       Result = DAG.getRegister(AArch64::WZR, MVT::i32);
     break;
   }
+  case 'S': {
+    // An absolute symbolic address or label reference.
+    if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) {
+      Result = DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(Op),
+                                          GA->getValueType(0));
+    } else if (const BlockAddressSDNode *BA =
+                   dyn_cast<BlockAddressSDNode>(Op)) {
+      Result =
+          DAG.getTargetBlockAddress(BA->getBlockAddress(), BA->getValueType(0));
+    } else if (const ExternalSymbolSDNode *ES =
+                   dyn_cast<ExternalSymbolSDNode>(Op)) {
+      Result =
+          DAG.getTargetExternalSymbol(ES->getSymbol(), ES->getValueType(0));
+    } else
+      return;
+    break;
+  }
 
   case 'I':
   case 'J':
Index: lib/Target/AArch64/AArch64AsmPrinter.cpp
===================================================================
--- lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -276,6 +276,11 @@
     printOffset(MO.getOffset(), O);
     break;
   }
+  case MachineOperand::MO_BlockAddress: {
+    MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
+    Sym->print(O, MAI);
+    break;
+  }
   }
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46745.146293.patch
Type: text/x-patch
Size: 3001 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180511/f37ac557/attachment.bin>


More information about the llvm-commits mailing list