danielkiss updated this revision to Diff 266595.
danielkiss marked an inline comment as done.
danielkiss retitled this revision from "[AArch64] __builtin_extract_return_addr 
 for PAuth." to "[AArch64] __builtin_return_address for PAuth.".
danielkiss edited the summary of this revision.
danielkiss added a comment.

Changing the implementation from __builtin_extract_return_addr to 
__builtin_return_address.
Stripping PAC in __builtin_return_address is a better solution,  because:

- we should not expose PAC bits to the user because it could be passed around 
and that would be an ABI break.
- __builtin_extract_return_addr has a pair, the __builtin_frob_return_addr 
which won't be supported with PAC.

I'm thinking of adding a warning if __builtin_frob_return_addr is used with PAC 
on.
Same change will be proposed from gcc too.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75044/new/

https://reviews.llvm.org/D75044

Files:
  llvm/include/llvm/CodeGen/ISDOpcodes.h
  llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
  llvm/test/CodeGen/AArch64/aarch64-signedreturnaddress.ll

Index: llvm/test/CodeGen/AArch64/aarch64-signedreturnaddress.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/AArch64/aarch64-signedreturnaddress.ll
@@ -0,0 +1,28 @@
+; RUN: llc < %s -mtriple=arm64-eabi -asm-verbose=false -mattr=v8.2a | FileCheck %s
+; RUN: llc < %s -mtriple=arm64-eabi -asm-verbose=false -mattr=v8.3a | FileCheck %s --check-prefix=CHECKV83
+
+; Armv8.3-A Pointer Authetication requires a special intsruction to strip the
+; pointer authentication code from the pointer.
+; The XPACLRI instruction assembles to a hint-space instruction before Armv8.3-A
+; therefore this instruction can be safely used for any pre Armv8.3-A architectures.
+; On Armv8.3-A and onwards XPACI is available so use that instead.
+
+define i8* @era0() nounwind readnone #0 {
+entry:
+; CHECK-LABEL: era0:
+; CHECK:          hint #25
+; CHECK-NEXT:     str     x30, [sp, #-16]!
+; CHECK-NEXT:     hint #7
+; CHECK-NEXT:     mov     x0, x30
+; CHECK-NEXT:     ldr     x30, [sp], #16
+; CHECK-NEXT:     hint #29
+; CHECK-NEXT:     ret
+; CHECKV83:       paciasp
+; CHECKV83-NEXT:  xpaci   x0
+; CHECKV83-NEXT:  retaa
+  %0 = tail call i8* @llvm.returnaddress(i32 0)
+  ret i8* %0
+}
+attributes #0 = { "sign-return-address"="all" }
+
+declare i8* @llvm.returnaddress(i32) nounwind readnone
Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -6093,17 +6093,39 @@
   EVT VT = Op.getValueType();
   SDLoc DL(Op);
   unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
+  SDValue ReturnAddress;
   if (Depth) {
     SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
     SDValue Offset = DAG.getConstant(8, DL, getPointerTy(DAG.getDataLayout()));
-    return DAG.getLoad(VT, DL, DAG.getEntryNode(),
-                       DAG.getNode(ISD::ADD, DL, VT, FrameAddr, Offset),
-                       MachinePointerInfo());
+    ReturnAddress = DAG.getLoad(
+        VT, DL, DAG.getEntryNode(),
+        DAG.getNode(ISD::ADD, DL, VT, FrameAddr, Offset), MachinePointerInfo());
+  } else {
+    // Return LR, which contains the return address. Mark it an implicit
+    // live-in.
+    unsigned Reg = MF.addLiveIn(AArch64::LR, &AArch64::GPR64RegClass);
+    ReturnAddress = DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, VT);
+  }
+
+  if (!MF.getFunction().hasFnAttribute("sign-return-address"))
+    return ReturnAddress;
+
+  // The XPACLRI instruction assembles to a hint-space instruction before
+  // Armv8.3-A therefore this instruction can be safely used for any pre
+  // Armv8.3-A architectures. On Armv8.3-A and onwards XPACI is available so use
+  // that instead.
+  if (Subtarget->hasV8_3aOps()) {
+    SDValue Reg =
+        DAG.getCopyToReg(DAG.getEntryNode(), DL, AArch64::X0, ReturnAddress);
+    SDNode *St = DAG.getMachineNode(AArch64::XPACI, DL, VT, Reg);
+    return SDValue(St, 0);
+  } else {
+    // XPACLRI operates on LR therefore we must move the operand accordingly.
+    SDValue Reg =
+        DAG.getCopyToReg(DAG.getEntryNode(), DL, AArch64::LR, ReturnAddress);
+    SDNode *St = DAG.getMachineNode(AArch64::XPACLRI, DL, VT, Reg);
+    return SDValue(St, 0);
   }
-
-  // Return LR, which contains the return address. Mark it an implicit live-in.
-  unsigned Reg = MF.addLiveIn(AArch64::LR, &AArch64::GPR64RegClass);
-  return DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, VT);
 }
 
 /// LowerShiftRightParts - Lower SRA_PARTS, which returns two
Index: llvm/include/llvm/CodeGen/ISDOpcodes.h
===================================================================
--- llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -85,7 +85,16 @@
   /// the parent's frame or return address, and so on.
   FRAMEADDR,
   RETURNADDR,
+
+  /// ADDROFRETURNADDR - Represents the llvm.addressofreturnaddress intrinsic.
+  /// This node takes no operand, returns a target-specific pointer to the
+  /// place in the stack frame where the return address of the current
+  /// function is stored.
   ADDROFRETURNADDR,
+
+  /// SPONENTRY - Represents the llvm.sponentry intrinsic. Takes no argument
+  /// and returns the stack pointer value at the entry of the current
+  /// function calling this intrinsic.
   SPONENTRY,
 
   /// LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to