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