pscoro updated this revision to Diff 442643.
pscoro added a comment.
patch application
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D129016/new/
https://reviews.llvm.org/D129016
Files:
clang/include/clang/Basic/BuiltinsPPC.def
clang/lib/Basic/Targets/PPC.cpp
clang/test/CodeGen/PowerPC/builtins-ppc-stackprotect.c
llvm/include/llvm/IR/IntrinsicsPowerPC.td
llvm/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/test/CodeGen/PowerPC/kill-canary-intrinsic.ll
Index: llvm/test/CodeGen/PowerPC/kill-canary-intrinsic.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/kill-canary-intrinsic.ll
@@ -0,0 +1,77 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
+; RUN: --ppc-asm-full-reg-names < %s | FileCheck %s -check-prefix=AIX
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux \
+; RUN: --ppc-asm-full-reg-names < %s | FileCheck %s -check-prefix=LINUX
+
+declare void @llvm.ppc.kill.canary()
+define dso_local void @test_kill_canary() {
+; AIX-LABEL: test_kill_canary:
+; AIX: # %bb.0: # %entry
+; AIX-NEXT: blr
+;
+; LINUX-LABEL: test_kill_canary:
+; LINUX: # %bb.0: # %entry
+; LINUX-NEXT: blr
+entry:
+ call void @llvm.ppc.kill.canary()
+ ret void
+}
+
+attributes #0 = { sspreq }
+; Function Attrs: sspreq
+define dso_local void @test_kill_canary_ssp() #0 {
+; AIX-LABEL: test_kill_canary_ssp:
+; AIX: # %bb.0: # %entry
+; AIX-NEXT: mflr r0
+; AIX-NEXT: std r0, 16(r1)
+; AIX-NEXT: stdu r1, -128(r1)
+; AIX-NEXT: ld r3, L..C0(r2) # @__ssp_canary_word
+; AIX-NEXT: ld r4, 0(r3)
+; AIX-NEXT: std r4, 120(r1)
+; AIX-NEXT: ld r4, 0(r3)
+; AIX-NEXT: xori r4, r4, 65535
+; AIX-NEXT: xoris r4, r4, 65535
+; AIX-NEXT: std r4, 0(r3)
+; AIX-NEXT: ld r3, 0(r3)
+; AIX-NEXT: ld r4, 120(r1)
+; AIX-NEXT: cmpld r3, r4
+; AIX-NEXT: bne cr0, L..BB1_2
+; AIX-NEXT: # %bb.1: # %entry
+; AIX-NEXT: addi r1, r1, 128
+; AIX-NEXT: ld r0, 16(r1)
+; AIX-NEXT: mtlr r0
+; AIX-NEXT: blr
+; AIX-NEXT: L..BB1_2: # %entry
+; AIX-NEXT: bl .__stack_chk_fail[PR]
+; AIX-NEXT: nop
+;
+; LINUX-LABEL: test_kill_canary_ssp:
+; LINUX: # %bb.0: # %entry
+; LINUX-NEXT: mflr r0
+; LINUX-NEXT: std r0, 16(r1)
+; LINUX-NEXT: stdu r1, -128(r1)
+; LINUX-NEXT: .cfi_def_cfa_offset 128
+; LINUX-NEXT: .cfi_offset lr, 16
+; LINUX-NEXT: ld r3, -28688(r13)
+; LINUX-NEXT: std r3, 120(r1)
+; LINUX-NEXT: ld r3, -28688(r13)
+; LINUX-NEXT: xori r3, r3, 65535
+; LINUX-NEXT: xoris r3, r3, 65535
+; LINUX-NEXT: std r3, 120(r1)
+; LINUX-NEXT: ld r3, 120(r1)
+; LINUX-NEXT: ld r4, -28688(r13)
+; LINUX-NEXT: cmpld r4, r3
+; LINUX-NEXT: bne cr0, .LBB1_2
+; LINUX-NEXT: # %bb.1: # %entry
+; LINUX-NEXT: addi r1, r1, 128
+; LINUX-NEXT: ld r0, 16(r1)
+; LINUX-NEXT: mtlr r0
+; LINUX-NEXT: blr
+; LINUX-NEXT: .LBB1_2: # %entry
+; LINUX-NEXT: bl __stack_chk_fail
+; LINUX-NEXT: nop
+entry:
+ call void @llvm.ppc.kill.canary()
+ ret void
+}
Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -11143,6 +11143,72 @@
}
break;
}
+ case Intrinsic::ppc_kill_canary: {
+ MachineFunction &MF = DAG.getMachineFunction();
+ const Module *M = MF.getMMI().getModule();
+
+ /* If SafeStack or !StackProtector, kill_canary not supported */
+ if (MF.getFunction().hasFnAttribute(Attribute::SafeStack) ||
+ !MF.getFunction().hasStackProtectorFnAttr()) {
+ DAG.ReplaceAllUsesOfValueWith(
+ SDValue(Op.getNode(), 0),
+ Op->getOperand(0)); // prepare node for deletion
+ break;
+ }
+
+ EVT VT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
+
+ SDValue Load;
+ SDValue Store;
+
+ const uint64_t XORWord =
+ 0xFFFFFFFFFFFFFFFF; // XORing with 0b111...111 will never
+ // result in the original word
+
+ if (useLoadStackGuardNode()) { // linux uses LOAD_STACK_GUARD node instead
+ // of having a canary word global value
+ MachineSDNode *LSG =
+ DAG.getMachineNode(PPC::LOAD_STACK_GUARD, DL, VT, Op->getOperand(0));
+ Load = SDValue(LSG, 0);
+
+ /* frame index used to determine stack guard location if
+ * LOAD_STACK_GUARD is used */
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+ int SPI = MFI.getStackProtectorIndex(); // should return -1
+ PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
+ SDValue FIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), VT);
+
+ // XOR canary word and store back
+ Store = DAG.getStore(
+ Op->getOperand(0), DL,
+ DAG.getNode(ISD::XOR, DL, VT, Load, DAG.getConstant(XORWord, DL, VT)),
+ DAG.getNode( // add frame index, stack protector index, return node
+ // result
+ ISD::ADD, DL, VT, FIN, DAG.getConstant(SPI, DL, VT)),
+ MachinePointerInfo());
+
+ } else if (Value *GV =
+ getSDagStackGuard(*M)) { // on aix, load from global value
+ VT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
+ GV->getType(), true);
+ SDValue CanaryLoc =
+ DAG.getGlobalAddress(dyn_cast<GlobalValue>(GV), DL, VT);
+
+ // Load from global value
+ Load = DAG.getLoad(VT, DL, Op->getOperand(0), CanaryLoc,
+ MachinePointerInfo());
+
+ // XOR canary word and store back
+ Store = DAG.getStore(
+ Op->getOperand(0), DL,
+ DAG.getNode(ISD::XOR, DL, VT, Load, DAG.getConstant(XORWord, DL, VT)),
+ CanaryLoc, MachinePointerInfo());
+ } else {
+ llvm_unreachable("Unhandled stack guard case");
+ }
+
+ return Store;
+ }
default:
break;
}
Index: llvm/include/llvm/IR/IntrinsicsPowerPC.td
===================================================================
--- llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -217,6 +217,11 @@
: Intrinsic<[llvm_float_ty],
[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_vararg_ty],
[IntrNoMem]>;
+ def int_ppc_kill_canary
+ : ClangBuiltin<"__builtin_ppc_kill_canary">,
+ Intrinsic<[],
+ [],
+ [IntrWriteMem, IntrHasSideEffects]>;
}
let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
Index: clang/test/CodeGen/PowerPC/builtins-ppc-stackprotect.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/PowerPC/builtins-ppc-stackprotect.c
@@ -0,0 +1,23 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-linux-gnu \
+// RUN: -emit-llvm %s -o - -target-cpu pwr7 | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc64le-unknown-linux-gnu \
+// RUN: -emit-llvm %s -o - -target-cpu pwr8 | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc-unknown-aix \
+// RUN: -emit-llvm %s -o - -target-cpu pwr7 | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-aix \
+// RUN: -emit-llvm %s -o - -target-cpu pwr7 | \
+// RUN: FileCheck %s
+
+void test_builtin_ppc_kill_canary() {
+ // CHECK: call void @llvm.ppc.kill.canary()
+ __builtin_ppc_kill_canary();
+}
+
+void test_kill_canary() {
+ // CHECK: call void @llvm.ppc.kill.canary()
+ __kill_canary();
+}
Index: clang/lib/Basic/Targets/PPC.cpp
===================================================================
--- clang/lib/Basic/Targets/PPC.cpp
+++ clang/lib/Basic/Targets/PPC.cpp
@@ -122,6 +122,7 @@
Builder.defineMacro("__fetch_and_orlp", "__builtin_ppc_fetch_and_orlp");
Builder.defineMacro("__fetch_and_swap", "__builtin_ppc_fetch_and_swap");
Builder.defineMacro("__fetch_and_swaplp", "__builtin_ppc_fetch_and_swaplp");
+ Builder.defineMacro("__kill_canary", "__builtin_ppc_kill_canary");
Builder.defineMacro("__ldarx", "__builtin_ppc_ldarx");
Builder.defineMacro("__lwarx", "__builtin_ppc_lwarx");
Builder.defineMacro("__lharx", "__builtin_ppc_lharx");
Index: clang/include/clang/Basic/BuiltinsPPC.def
===================================================================
--- clang/include/clang/Basic/BuiltinsPPC.def
+++ clang/include/clang/Basic/BuiltinsPPC.def
@@ -165,6 +165,8 @@
BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
+BUILTIN(__builtin_ppc_kill_canary, "v", "")
+
// This is just a placeholder, the types and attributes are wrong.
BUILTIN(__builtin_altivec_vaddcuw, "V4UiV4UiV4Ui", "")
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits