From e2c1a2bfce3d9608493bac6ee5a5e0f9b516c7b2 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Sat, 22 Jun 2019 03:03:25 +0000 Subject: [PATCH] AArch64: Add support for reading pc using llvm.read_register. 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 | 8 ++++++++ test/CodeGen/AArch64/read-pc.ll | 11 +++++++++++ 2 files changed, 19 insertions(+) create mode 100644 test/CodeGen/AArch64/read-pc.ll diff --git a/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 3b27b9f5b02..2a911c43908 100644 --- a/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -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 index 00000000000..626eaacefb6 --- /dev/null +++ b/test/CodeGen/AArch64/read-pc.ll @@ -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"} -- 2.40.0