pscoro updated this revision to Diff 449299. pscoro marked 3 inline comments as done. pscoro added a comment.
Fixed test cases and AIX implementation 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,142 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix -ppc-vsr-nums-as-vr \ +; RUN: -mcpu=pwr7 --ppc-asm-full-reg-names < %s | FileCheck %s -check-prefix=CHECK-AIX +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -ppc-vsr-nums-as-vr \ +; RUN: -mcpu=pwr7 --ppc-asm-full-reg-names < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix -ppc-vsr-nums-as-vr \ +; RUN: -mcpu=pwr7 --ppc-asm-full-reg-names < %s | FileCheck %s -check-prefix=CHECK-AIX64 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -ppc-vsr-nums-as-vr \ +; RUN: -mcpu=pwr7 --ppc-asm-full-reg-names < %s | FileCheck %s -check-prefix=CHECK-LINUX-LE + +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix -ppc-vsr-nums-as-vr \ +; RUN: -mcpu=pwr8 --ppc-asm-full-reg-names < %s | FileCheck %s -check-prefix=CHECK-AIX +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -ppc-vsr-nums-as-vr \ +; RUN: -mcpu=pwr8 --ppc-asm-full-reg-names < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix -ppc-vsr-nums-as-vr \ +; RUN: -mcpu=pwr8 --ppc-asm-full-reg-names < %s | FileCheck %s -check-prefix=CHECK-AIX64 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -ppc-vsr-nums-as-vr \ +; RUN: -mcpu=pwr8 --ppc-asm-full-reg-names < %s | FileCheck %s -check-prefix=CHECK-LINUX-LE + +attributes #1 = { nounwind } +declare void @llvm.ppc.kill.canary() +define dso_local void @test_kill_canary() #1 { +; CHECK-AIX-LABEL: test_kill_canary: +; CHECK-AIX: # %bb.0: # %entry +; CHECK-AIX-NEXT: blr +; +; CHECK-LABEL: test_kill_canary: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: blr +; +; CHECK-AIX64-LABEL: test_kill_canary: +; CHECK-AIX64: # %bb.0: # %entry +; CHECK-AIX64-NEXT: blr +; +; CHECK-LINUX-LE-LABEL: test_kill_canary: +; CHECK-LINUX-LE: # %bb.0: # %entry +; CHECK-LINUX-LE-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 #1 { +; CHECK-AIX-LABEL: test_kill_canary_ssp: +; CHECK-AIX: # %bb.0: # %entry +; CHECK-AIX-NEXT: mflr r0 +; CHECK-AIX-NEXT: stw r0, 8(r1) +; CHECK-AIX-NEXT: stwu r1, -64(r1) +; CHECK-AIX-NEXT: lwz r3, L..C0(r2) # @__ssp_canary_word +; CHECK-AIX-NEXT: lwz r4, 0(r3) +; CHECK-AIX-NEXT: stw r4, 60(r1) +; CHECK-AIX-NEXT: lwz r4, 0(r3) +; CHECK-AIX-NEXT: not r4, r4 +; CHECK-AIX-NEXT: stw r4, 60(r1) +; CHECK-AIX-NEXT: lwz r3, 0(r3) +; CHECK-AIX-NEXT: lwz r4, 60(r1) +; CHECK-AIX-NEXT: cmplw r3, r4 +; CHECK-AIX-NEXT: bne cr0, L..BB1_2 +; CHECK-AIX-NEXT: # %bb.1: # %entry +; CHECK-AIX-NEXT: addi r1, r1, 64 +; CHECK-AIX-NEXT: lwz r0, 8(r1) +; CHECK-AIX-NEXT: mtlr r0 +; CHECK-AIX-NEXT: blr +; CHECK-AIX-NEXT: L..BB1_2: # %entry +; CHECK-AIX-NEXT: bl .__stack_chk_fail[PR] +; CHECK-AIX-NEXT: nop +; +; CHECK-LABEL: test_kill_canary_ssp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mflr r0 +; CHECK-NEXT: std r0, 16(r1) +; CHECK-NEXT: stdu r1, -128(r1) +; CHECK-NEXT: ld r3, -28688(r13) +; CHECK-NEXT: std r3, 120(r1) +; CHECK-NEXT: ld r3, -28688(r13) +; CHECK-NEXT: not r3, r3 +; CHECK-NEXT: std r3, 120(r1) +; CHECK-NEXT: ld r3, 120(r1) +; CHECK-NEXT: ld r4, -28688(r13) +; CHECK-NEXT: cmpld r4, r3 +; CHECK-NEXT: bne cr0, .LBB1_2 +; CHECK-NEXT: # %bb.1: # %entry +; CHECK-NEXT: addi r1, r1, 128 +; CHECK-NEXT: ld r0, 16(r1) +; CHECK-NEXT: mtlr r0 +; CHECK-NEXT: blr +; CHECK-NEXT: .LBB1_2: # %entry +; CHECK-NEXT: bl __stack_chk_fail +; CHECK-NEXT: nop +; +; CHECK-AIX64-LABEL: test_kill_canary_ssp: +; CHECK-AIX64: # %bb.0: # %entry +; CHECK-AIX64-NEXT: mflr r0 +; CHECK-AIX64-NEXT: std r0, 16(r1) +; CHECK-AIX64-NEXT: stdu r1, -128(r1) +; CHECK-AIX64-NEXT: ld r3, L..C0(r2) # @__ssp_canary_word +; CHECK-AIX64-NEXT: ld r4, 0(r3) +; CHECK-AIX64-NEXT: std r4, 120(r1) +; CHECK-AIX64-NEXT: ld r4, 0(r3) +; CHECK-AIX64-NEXT: not r4, r4 +; CHECK-AIX64-NEXT: std r4, 120(r1) +; CHECK-AIX64-NEXT: ld r3, 0(r3) +; CHECK-AIX64-NEXT: ld r4, 120(r1) +; CHECK-AIX64-NEXT: cmpld r3, r4 +; CHECK-AIX64-NEXT: bne cr0, L..BB1_2 +; CHECK-AIX64-NEXT: # %bb.1: # %entry +; CHECK-AIX64-NEXT: addi r1, r1, 128 +; CHECK-AIX64-NEXT: ld r0, 16(r1) +; CHECK-AIX64-NEXT: mtlr r0 +; CHECK-AIX64-NEXT: blr +; CHECK-AIX64-NEXT: L..BB1_2: # %entry +; CHECK-AIX64-NEXT: bl .__stack_chk_fail[PR] +; CHECK-AIX64-NEXT: nop +; +; CHECK-LINUX-LE-LABEL: test_kill_canary_ssp: +; CHECK-LINUX-LE: # %bb.0: # %entry +; CHECK-LINUX-LE-NEXT: mflr r0 +; CHECK-LINUX-LE-NEXT: std r0, 16(r1) +; CHECK-LINUX-LE-NEXT: stdu r1, -48(r1) +; CHECK-LINUX-LE-NEXT: ld r3, -28688(r13) +; CHECK-LINUX-LE-NEXT: std r3, 40(r1) +; CHECK-LINUX-LE-NEXT: ld r3, -28688(r13) +; CHECK-LINUX-LE-NEXT: not r3, r3 +; CHECK-LINUX-LE-NEXT: std r3, 40(r1) +; CHECK-LINUX-LE-NEXT: ld r3, 40(r1) +; CHECK-LINUX-LE-NEXT: ld r4, -28688(r13) +; CHECK-LINUX-LE-NEXT: cmpld r4, r3 +; CHECK-LINUX-LE-NEXT: bne cr0, .LBB1_2 +; CHECK-LINUX-LE-NEXT: # %bb.1: # %entry +; CHECK-LINUX-LE-NEXT: addi r1, r1, 48 +; CHECK-LINUX-LE-NEXT: ld r0, 16(r1) +; CHECK-LINUX-LE-NEXT: mtlr r0 +; CHECK-LINUX-LE-NEXT: blr +; CHECK-LINUX-LE-NEXT: .LBB1_2: # %entry +; CHECK-LINUX-LE-NEXT: bl __stack_chk_fail +; CHECK-LINUX-LE-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 @@ -10695,6 +10695,68 @@ Op.getOperand(0)), 0); } + case Intrinsic::ppc_kill_canary: { + MachineFunction &MF = DAG.getMachineFunction(); + const Module *M = MF.getMMI().getModule(); + + // If SafeStack or !StackProtector, kill_canary is not supported. + if (MF.getFunction().hasFnAttribute(Attribute::SafeStack) || + !MF.getFunction().hasStackProtectorFnAttr()) { + DAG.ReplaceAllUsesOfValueWith( + SDValue(Op.getNode(), 0), + Op->getOperand(0)); + break; + } + + EVT VT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout()); + + SDValue Load; + SDValue Store; + + // The new stored canary word should never be the same as the canary word + // before corruption, so we XOR the canary word with all 1 bits. + // const uint64_t XORWord = 0xFFFFFFFFFFFFFFFF; + + MachineFrameInfo &MFI = MF.getFrameInfo(); + int SPI = MFI.getStackProtectorIndex(); + PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); + SDValue FIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), VT); + + // Linux uses LOAD_STACK_GUARD node instead of a canary global value. + if (useLoadStackGuardNode()) { + 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. + Store = DAG.getStore( + Op->getOperand(0), DL, + DAG.getNode(ISD::XOR, DL, VT, Load, DAG.getAllOnesConstant(DL, VT)/*DAG.getConstant(XORWord, DL, VT)*/), + DAG.getNode(ISD::ADD, DL, VT, FIN, DAG.getConstant(SPI, DL, VT)), + MachinePointerInfo()); + + } else if (Value *GV = getSDagStackGuard(*M)) { + // 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 = DAG.getLoad(VT, DL, Op->getOperand(0), CanaryLoc, + MachinePointerInfo()); + + Store = DAG.getStore( + Op->getOperand(0), DL, + DAG.getNode(ISD::XOR, DL, VT, Load, DAG.getAllOnesConstant(DL, VT)/*DAG.getConstant(XORWord, DL, VT)*/), + DAG.getNode(ISD::ADD, DL, VT, FIN, DAG.getConstant(SPI, 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 @@ -194,6 +194,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 -triple powerpc64-unknown-linux-gnu \ +// RUN: -emit-llvm %s -o - -target-cpu pwr7 | \ +// RUN: FileCheck %s +// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu \ +// RUN: -emit-llvm %s -o - -target-cpu pwr8 | \ +// RUN: FileCheck %s +// RUN: %clang_cc1 -triple powerpc-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr7 | \ +// RUN: FileCheck %s +// RUN: %clang_cc1 -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 @@ -72,6 +72,7 @@ BUILTIN(__builtin_ppc_fetch_and_orlp, "ULiULiD*ULi", "") BUILTIN(__builtin_ppc_fetch_and_swap, "UiUiD*Ui", "") BUILTIN(__builtin_ppc_fetch_and_swaplp, "ULiULiD*ULi", "") +BUILTIN(__builtin_ppc_kill_canary, "v", "") BUILTIN(__builtin_ppc_ldarx, "LiLiD*", "") BUILTIN(__builtin_ppc_lwarx, "iiD*", "") BUILTIN(__builtin_ppc_lharx, "ssD*", "")
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits