[PATCH] D63471: AArch64: Add support for reading pc using llvm.read_register.

Peter Collingbourne via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 17 20:39:02 PDT 2019


pcc created this revision.
pcc added reviewers: eugenis, t.p.northover.
Herald added subscribers: hiraditya, kristof.beyls, javed.absar, aprantl.
Herald added a project: LLVM.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D63471

Files:
  llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
  llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
  llvm/lib/Target/AArch64/AArch64InstrInfo.td
  llvm/test/CodeGen/AArch64/read-pc.ll


Index: llvm/test/CodeGen/AArch64/read-pc.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/AArch64/read-pc.ll
@@ -0,0 +1,12 @@
+; RUN: llc < %s -mtriple=arm64-linux-gnu | FileCheck %s
+
+define i64 @read_pc() {
+  ; CHECK: .Ltmp0:
+  ; CHECK-NEXT: adr x0, .Ltmp0
+  %pc = call i64 @llvm.read_register.i64(metadata !0)
+  ret i64 %pc
+}
+
+declare i64 @llvm.read_register.i64(metadata) nounwind
+
+!0 = !{!"pc"}
Index: llvm/lib/Target/AArch64/AArch64InstrInfo.td
===================================================================
--- llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1619,6 +1619,10 @@
 def : Pat<(AArch64adrp tblockaddress:$cp), (ADRP tblockaddress:$cp)>;
 def : Pat<(AArch64adrp texternalsym:$sym), (ADRP texternalsym:$sym)>;
 
+// An ADR pseudo-instruction that returns the address of itself.
+// Used to implement read_register("pc").
+def ADR_PC : Pseudo<(outs GPR64:$addr), (ins), []>, Sched<[WriteI]>;
+
 //===----------------------------------------------------------------------===//
 // Unconditional branch (register) instructions.
 //===----------------------------------------------------------------------===//
Index: llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -2678,6 +2678,13 @@
     return true;
   }
 
+  if (RegString->getString() == "pc") {
+    ReplaceNode(N, CurDAG->getMachineNode(AArch64::ADR_PC, DL,
+                                          N->getSimpleValueType(0), MVT::Other,
+                                          N->getOperand(0)));
+    return true;
+  }
+
   return false;
 }
 
Index: llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -1027,6 +1027,16 @@
     LowerHWASAN_CHECK_MEMACCESS(*MI);
     return;
 
+  case AArch64::ADR_PC: {
+    auto Sym = OutContext.createTempSymbol();
+    OutStreamer->EmitLabel(Sym);
+    EmitToStreamer(*OutStreamer,
+                   MCInstBuilder(AArch64::ADR)
+                       .addReg(MI->getOperand(0).getReg())
+                       .addExpr(MCSymbolRefExpr::create(Sym, OutContext)));
+    return;
+  }
+
   case AArch64::SEH_StackAlloc:
     TS->EmitARM64WinCFIAllocStack(MI->getOperand(0).getImm());
     return;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63471.205240.patch
Type: text/x-patch
Size: 2571 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190618/be16219f/attachment.bin>


More information about the llvm-commits mailing list