]> granicus.if.org Git - llvm/commitdiff
AArch64: Add support for reading pc using llvm.read_register.
authorPeter Collingbourne <peter@pcc.me.uk>
Sat, 22 Jun 2019 03:03:25 +0000 (03:03 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Sat, 22 Jun 2019 03:03:25 +0000 (03:03 +0000)
This is useful for allowing code to efficiently take an address
that can be later mapped onto debug info. Currently the hwasan
pass achieves this by taking the address of the current function:
http://llvm-cs.pcc.me.uk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp#921

but this costs two instructions (plus a GOT entry in PIC code) per function
with stack variables. This will allow the cost to be reduced to a single
instruction.

Differential Revision: https://reviews.llvm.org/D63471

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364126 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
test/CodeGen/AArch64/read-pc.ll [new file with mode: 0644]

index 3b27b9f5b02342ff335abd6c962a6376c44ba2e9..2a911c439083efa3ac90f906260e674da8a0c7d9 100644 (file)
@@ -2678,6 +2678,14 @@ bool AArch64DAGToDAGISel::tryReadRegister(SDNode *N) {
     return true;
   }
 
+  if (RegString->getString() == "pc") {
+    ReplaceNode(N, CurDAG->getMachineNode(
+                       AArch64::ADR, DL, N->getSimpleValueType(0), MVT::Other,
+                       CurDAG->getTargetConstant(0, DL, MVT::i32),
+                       N->getOperand(0)));
+    return true;
+  }
+
   return false;
 }
 
diff --git a/test/CodeGen/AArch64/read-pc.ll b/test/CodeGen/AArch64/read-pc.ll
new file mode 100644 (file)
index 0000000..626eaac
--- /dev/null
@@ -0,0 +1,11 @@
+; RUN: llc < %s -mtriple=arm64-linux-gnu | FileCheck %s
+
+define i64 @read_pc() {
+  ; CHECK: adr x0, #0
+  %pc = call i64 @llvm.read_register.i64(metadata !0)
+  ret i64 %pc
+}
+
+declare i64 @llvm.read_register.i64(metadata) nounwind
+
+!0 = !{!"pc"}