Index: llvm/include/llvm/CodeGen/TargetLowering.h =================================================================== --- llvm/include/llvm/CodeGen/TargetLowering.h +++ llvm/include/llvm/CodeGen/TargetLowering.h @@ -3487,6 +3487,11 @@ return false; } + /// If this function returns true, stack protection checks should XOR the + /// frame pointer (or whichever pointer is used to address locals) into the + /// stack guard value before checking it. + virtual bool useStackGuardXorFP() const { return false; } + /// Lower TLS global address SDNode for target independent emulated TLS model. virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -822,6 +822,7 @@ void visitSPDescriptorParent(StackProtectorDescriptor &SPD, MachineBasicBlock *ParentBB); void visitSPDescriptorFailure(StackProtectorDescriptor &SPD); + SDValue emitStackGuardXorFP(SDValue Chain, SDLoc dl, SDValue Val); void visitBitTestHeader(BitTestBlock &B, MachineBasicBlock *SwitchBB); void visitBitTestCase(BitTestBlock &BB, MachineBasicBlock* NextMBB, Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2123,6 +2123,22 @@ return SDValue(Node, 0); } +/// XOR the frame pointer register for this function into Val. The actual chosen +/// register is irrelevant (SP or FP) so long as it remains the same across +/// the lifetime of the function. The only way for the frame, base, or +/// stack pointer to change is for there to be VLAs, which we know about up +/// front. Therefore this call to getFrameRegister before register +/// allocation is safe. +SDValue SelectionDAGBuilder::emitStackGuardXorFP(SDValue Chain, SDLoc dl, SDValue Val) { + MachineFunction &MF = DAG.getMachineFunction(); + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + const TargetRegisterInfo *TRI = DAG.getSubtarget().getRegisterInfo(); + unsigned FrameReg = TRI->getFrameRegister(MF); + MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout(), 0); + SDValue FP = DAG.getCopyFromReg(Chain, dl, FrameReg, PtrVT); + return DAG.getNode(ISD::XOR, dl, PtrVT, Val, FP); +} + /// Codegen a new tail for a stack protector check ParentMBB which has had its /// tail spliced into a stack protector check success bb. /// @@ -2146,11 +2162,14 @@ unsigned Align = DL->getPrefTypeAlignment(Type::getInt8PtrTy(M.getContext())); // Generate code to load the content of the guard slot. - SDValue StackSlot = DAG.getLoad( + SDValue GuardVal = DAG.getLoad( PtrTy, dl, DAG.getEntryNode(), StackSlotPtr, MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), Align, MachineMemOperand::MOVolatile); + if (TLI.useStackGuardXorFP()) + GuardVal = emitStackGuardXorFP(DAG.getEntryNode(), dl, GuardVal); + // Retrieve guard check function, nullptr if instrumentation is inlined. if (const Value *GuardCheck = TLI.getSSPStackGuardCheck(M)) { // The target provides a guard check function to validate the guard value. @@ -2162,7 +2181,7 @@ TargetLowering::ArgListTy Args; TargetLowering::ArgListEntry Entry; - Entry.Node = StackSlot; + Entry.Node = GuardVal; Entry.Ty = FnTy->getParamType(0); if (Fn->hasAttribute(1, Attribute::AttrKind::InReg)) Entry.IsInReg = true; @@ -2195,7 +2214,7 @@ // Perform the comparison via a subtract/getsetcc. EVT VT = Guard.getValueType(); - SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, Guard, StackSlot); + SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, Guard, GuardVal); SDValue Cmp = DAG.getSetCC(dl, TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), @@ -2205,7 +2224,7 @@ // If the sub is not 0, then we know the guard/stackslot do not equal, so // branch to failure MBB. SDValue BrCond = DAG.getNode(ISD::BRCOND, dl, - MVT::Other, StackSlot.getOperand(0), + MVT::Other, GuardVal.getOperand(0), Cmp, DAG.getBasicBlock(SPD.getFailureMBB())); // Otherwise branch to success MBB. SDValue Br = DAG.getNode(ISD::BR, dl, @@ -5644,6 +5663,8 @@ MachinePointerInfo(Global, 0), Align, MachineMemOperand::MOVolatile); } + if (TLI.useStackGuardXorFP()) + Res = emitStackGuardXorFP(Chain, sdl, Res); DAG.setRoot(Chain); setValue(&I, Res); return nullptr; Index: llvm/lib/Target/X86/X86ISelLowering.h =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.h +++ llvm/lib/Target/X86/X86ISelLowering.h @@ -1055,6 +1055,7 @@ Value *getIRStackGuard(IRBuilder<> &IRB) const override; bool useLoadStackGuardNode() const override; + bool useStackGuardXorFP() const override; void insertSSPDeclarations(Module &M) const override; Value *getSDagStackGuard(const Module &M) const override; Value *getSSPStackGuardCheck(const Module &M) const override; Index: llvm/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.cpp +++ llvm/lib/Target/X86/X86ISelLowering.cpp @@ -1687,6 +1687,11 @@ return Subtarget.isTargetMachO() && Subtarget.is64Bit(); } +bool X86TargetLowering::useStackGuardXorFP() const { + // Currently only MSVC CRTs XOR the frame pointer into the stack guard value. + return Subtarget.getTargetTriple().isOSMSVCRT(); +} + TargetLoweringBase::LegalizeTypeAction X86TargetLowering::getPreferredVectorAction(EVT VT) const { if (ExperimentalVectorWideningLegalization && Index: llvm/test/CodeGen/X86/stack-protector-msvc.ll =================================================================== --- llvm/test/CodeGen/X86/stack-protector-msvc.ll +++ llvm/test/CodeGen/X86/stack-protector-msvc.ll @@ -1,19 +1,5 @@ - -; RUN: llc -mtriple=i386-pc-windows-msvc < %s -o - | FileCheck -check-prefix=MSVC-I386 %s -; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s -o - | FileCheck -check-prefix=MSVC-64 %s - -; MSVC-I386: movl ___security_cookie, %[[REG1:[a-z]*]] -; MSVC-I386: movl %[[REG1]], [[SLOT:[0-9]*]](%esp) -; MSVC-I386: calll _strcpy -; MSVC-I386: movl [[SLOT]](%esp), %ecx -; MSVC-I386: calll @__security_check_cookie@4 -; MSVC-I386: retl - -; MSVC-64: movq __security_cookie(%rip), %[[REG1:[a-z]*]] -; MSVC-64: movq %[[REG1]], [[SLOT:[0-9]*]](%rsp) -; MSVC-64: callq strcpy -; MSVC-64: movq [[SLOT]](%rsp), %rcx -; MSVC-64: callq __security_check_cookie +; RUN: llc -mtriple=i386-pc-windows-msvc < %s -o - | FileCheck -check-prefix=MSVC-X86 %s +; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s -o - | FileCheck -check-prefix=MSVC-X64 %s @"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1] @@ -21,7 +7,6 @@ entry: %a_addr = alloca i8* ; [#uses=2] %buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] store i8* %a, i8** %a_addr %buf1 = bitcast [8 x i8]* %buf to i8* ; [#uses=1] %0 = load i8*, i8** %a_addr, align 4 ; [#uses=1] @@ -34,6 +19,115 @@ ret void } +; MSVC-X86-LABEL: _test: +; MSVC-X86: movl %esp, %[[REG1:[a-z]*]] +; MSVC-X86: xorl ___security_cookie, %[[REG1]] +; MSVC-X86: movl %[[REG1]], [[SLOT:[0-9]*]](%esp) +; MSVC-X86: calll _strcpy +; MSVC-X86: movl %esp, %ecx +; MSVC-X86: xorl [[SLOT]](%esp), %ecx +; MSVC-X86: calll @__security_check_cookie@4 +; MSVC-X86: retl + +; MSVC-X64-LABEL: test: +; MSVC-X64: movq %rsp, %[[REG1:[a-z]*]] +; MSVC-X64: xorq __security_cookie(%rip), %[[REG1]] +; MSVC-X64: movq %[[REG1]], [[SLOT:[0-9]*]](%rsp) +; MSVC-X64: callq strcpy +; MSVC-X64: movq %rsp, %rcx +; MSVC-X64: xorq [[SLOT]](%rsp), %rcx +; MSVC-X64: callq __security_check_cookie + +declare void @escape(i32*) + +define void @test_vla(i32 %n) nounwind ssp { + %vla = alloca i32, i32 %n + call void @escape(i32* %vla) + ret void +} + +; MSVC-X86-LABEL: _test_vla: +; MSVC-X86: pushl %ebp +; MSVC-X86: movl %esp, %ebp +; MSVC-X86: movl %ebp, %[[REG1:[a-z]*]] +; MSVC-X86: xorl ___security_cookie, %[[REG1]] +; MSVC-X86: movl %[[REG1]], [[SLOT:-[0-9]*]](%ebp) +; MSVC-X86: calll __chkstk +; MSVC-X86: pushl +; MSVC-X86: calll _escape +; MSVC-X86: movl %ebp, %ecx +; MSVC-X86: xorl [[SLOT]](%ebp), %ecx +; MSVC-X86: calll @__security_check_cookie@4 +; MSVC-X86: movl %ebp, %esp +; MSVC-X86: popl %ebp +; MSVC-X86: retl + +; MSVC-X64-LABEL: test_vla: +; MSVC-X64: pushq %rbp +; MSVC-X64: subq $16, %rsp +; MSVC-X64: leaq 16(%rsp), %rbp +; MSVC-X64: movq %rbp, %[[REG1:[a-z]*]] +; MSVC-X64: xorq __security_cookie(%rip), %[[REG1]] +; MSVC-X64: movq %[[REG1]], [[SLOT:-[0-9]*]](%rbp) +; MSVC-X64: callq __chkstk +; MSVC-X64: callq escape +; MSVC-X64: movq %rbp, %rcx +; MSVC-X64: xorq [[SLOT]](%rbp), %rcx +; MSVC-X64: callq __security_check_cookie +; MSVC-X64: retq + + +; This case is interesting because we address local variables with RBX but XOR +; the guard value with RBP. That's fine, either value will do, as long as they +; are the same across the life of the frame. + +define void @test_vla_realign(i32 %n) nounwind ssp { + %realign = alloca i32, align 32 + %vla = alloca i32, i32 %n + call void @escape(i32* %realign) + call void @escape(i32* %vla) + ret void +} + +; MSVC-X86-LABEL: _test_vla_realign: +; MSVC-X86: pushl %ebp +; MSVC-X86: movl %esp, %ebp +; MSVC-X86: pushl %esi +; MSVC-X86: andl $-32, %esp +; MSVC-X86: subl $32, %esp +; MSVC-X86: movl %esp, %esi +; MSVC-X86: movl %ebp, %[[REG1:[a-z]*]] +; MSVC-X86: xorl ___security_cookie, %[[REG1]] +; MSVC-X86: movl %[[REG1]], [[SLOT:[0-9]*]](%esi) +; MSVC-X86: calll __chkstk +; MSVC-X86: pushl +; MSVC-X86: calll _escape +; MSVC-X86: movl %ebp, %ecx +; MSVC-X86: xorl [[SLOT]](%esi), %ecx +; MSVC-X86: calll @__security_check_cookie@4 +; MSVC-X86: leal -8(%ebp), %esp +; MSVC-X86: popl %esi +; MSVC-X86: popl %ebp +; MSVC-X86: retl + +; MSVC-X64-LABEL: test_vla_realign: +; MSVC-X64: pushq %rbp +; MSVC-X64: pushq %rbx +; MSVC-X64: subq $32, %rsp +; MSVC-X64: leaq 32(%rsp), %rbp +; MSVC-X64: andq $-32, %rsp +; MSVC-X64: movq %rsp, %rbx +; MSVC-X64: movq %rbp, %[[REG1:[a-z]*]] +; MSVC-X64: xorq __security_cookie(%rip), %[[REG1]] +; MSVC-X64: movq %[[REG1]], [[SLOT:[0-9]*]](%rbx) +; MSVC-X64: callq __chkstk +; MSVC-X64: callq escape +; MSVC-X64: movq %rbp, %rcx +; MSVC-X64: xorq [[SLOT]](%rbx), %rcx +; MSVC-X64: callq __security_check_cookie +; MSVC-X64: retq + + declare i8* @strcpy(i8*, i8*) nounwind declare i32 @printf(i8*, ...) nounwind Index: llvm/test/CodeGen/X86/stack-protector.ll =================================================================== --- llvm/test/CodeGen/X86/stack-protector.ll +++ llvm/test/CodeGen/X86/stack-protector.ll @@ -83,7 +83,7 @@ ; OPENBSD-AMD64: callq __stack_smash_handler ; MSVC-I386-LABEL: test1b: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a.addr = alloca i8*, align 8 %buf = alloca [16 x i8], align 16 @@ -119,7 +119,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test1c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a.addr = alloca i8*, align 8 %buf = alloca [16 x i8], align 16 @@ -155,7 +155,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test1d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a.addr = alloca i8*, align 8 %buf = alloca [16 x i8], align 16 @@ -262,7 +262,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test2c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a.addr = alloca i8*, align 8 %b = alloca %struct.foo, align 1 @@ -300,7 +300,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test2d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a.addr = alloca i8*, align 8 %b = alloca %struct.foo, align 1 @@ -409,7 +409,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test3c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a.addr = alloca i8*, align 8 %buf = alloca [4 x i8], align 1 @@ -445,7 +445,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test3d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a.addr = alloca i8*, align 8 %buf = alloca [4 x i8], align 1 @@ -556,7 +556,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test4c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a.addr = alloca i8*, align 8 %b = alloca %struct.foo.0, align 1 @@ -594,7 +594,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test4d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a.addr = alloca i8*, align 8 %b = alloca %struct.foo.0, align 1 @@ -727,7 +727,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test5d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a.addr = alloca i8*, align 8 store i8* %a, i8** %a.addr, align 8 @@ -831,7 +831,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test6c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %retval = alloca i32, align 4 %a = alloca i32, align 4 @@ -867,7 +867,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test6d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %retval = alloca i32, align 4 %a = alloca i32, align 4 @@ -964,7 +964,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test7c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32, align 4 %0 = ptrtoint i32* %a to i64 @@ -995,7 +995,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test7d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32, align 4 %0 = ptrtoint i32* %a to i64 @@ -1085,7 +1085,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test8c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %b = alloca i32, align 4 call void @funcall(i32* %b) @@ -1115,7 +1115,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test8d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %b = alloca i32, align 4 call void @funcall(i32* %b) @@ -1212,7 +1212,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test9c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %x = alloca double, align 8 %call = call double @testi_aux() @@ -1246,7 +1246,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test9d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %x = alloca double, align 8 %call = call double @testi_aux() @@ -1377,7 +1377,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test10c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %x = alloca double, align 8 %call = call double @testi_aux() @@ -1426,7 +1426,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test10d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %x = alloca double, align 8 %call = call double @testi_aux() @@ -1542,7 +1542,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test11c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %c = alloca %struct.pair, align 4 %b = alloca i32*, align 8 @@ -1576,7 +1576,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test11d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %c = alloca %struct.pair, align 4 %b = alloca i32*, align 8 @@ -1674,7 +1674,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test12c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %c = alloca %struct.pair, align 4 %b = alloca i32*, align 8 @@ -1707,7 +1707,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test12d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %c = alloca %struct.pair, align 4 %b = alloca i32*, align 8 @@ -1801,7 +1801,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test13c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %c = alloca %struct.pair, align 4 %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i64 0, i32 1 @@ -1832,7 +1832,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test13d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %c = alloca %struct.pair, align 4 %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i64 0, i32 1 @@ -1924,7 +1924,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test14c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32, align 4 %add.ptr5 = getelementptr inbounds i32, i32* %a, i64 -12 @@ -1955,7 +1955,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test14d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32, align 4 %add.ptr5 = getelementptr inbounds i32, i32* %a, i64 -12 @@ -2058,7 +2058,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test15c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32, align 4 %b = alloca float*, align 8 @@ -2094,7 +2094,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test15d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32, align 4 %b = alloca float*, align 8 @@ -2195,7 +2195,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test16c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32, align 4 store i32 0, i32* %a, align 4 @@ -2228,7 +2228,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test16d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32, align 4 store i32 0, i32* %a, align 4 @@ -2323,7 +2323,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test17c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %c = alloca %struct.vec, align 16 %y = getelementptr inbounds %struct.vec, %struct.vec* %c, i64 0, i32 0 @@ -2355,7 +2355,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test17d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %c = alloca %struct.vec, align 16 %y = getelementptr inbounds %struct.vec, %struct.vec* %c, i64 0, i32 0 @@ -2468,7 +2468,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test18c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32, align 4 %exn.slot = alloca i8* @@ -2509,7 +2509,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test18d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32, align 4 %exn.slot = alloca i8* @@ -2637,7 +2637,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test19c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %c = alloca %struct.pair, align 4 %exn.slot = alloca i8* @@ -2685,7 +2685,7 @@ ; DARWIN-X64-NOT: callq ___stack_chk_fail ; MSVC-I386-LABEL: test19d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %c = alloca %struct.pair, align 4 %exn.slot = alloca i8* @@ -2797,7 +2797,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test20c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32*, align 8 %b = alloca i32**, align 8 @@ -2832,7 +2832,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test20d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32*, align 8 %b = alloca i32**, align 8 @@ -2938,7 +2938,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test21c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32*, align 8 %b = alloca float**, align 8 @@ -2974,7 +2974,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test21d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca i32*, align 8 %b = alloca float**, align 8 @@ -3073,7 +3073,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test22c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca %class.A, align 1 %array = getelementptr inbounds %class.A, %class.A* %a, i32 0, i32 0 @@ -3105,7 +3105,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test22d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca %class.A, align 1 %array = getelementptr inbounds %class.A, %class.A* %a, i32 0, i32 0 @@ -3208,7 +3208,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test23c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %x = alloca %struct.deep, align 1 %b = getelementptr inbounds %struct.deep, %struct.deep* %x, i32 0, i32 0 @@ -3244,7 +3244,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test23d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %x = alloca %struct.deep, align 1 %b = getelementptr inbounds %struct.deep, %struct.deep* %x, i32 0, i32 0 @@ -3315,7 +3315,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test24b: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %n.addr = alloca i32, align 4 %a = alloca i32*, align 8 @@ -3351,7 +3351,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test24c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %n.addr = alloca i32, align 4 %a = alloca i32*, align 8 @@ -3387,7 +3387,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test24d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %n.addr = alloca i32, align 4 %a = alloca i32*, align 8 @@ -3484,7 +3484,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test25c: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca [4 x i32], align 16 %arrayidx = getelementptr inbounds [4 x i32], [4 x i32]* %a, i32 0, i64 0 @@ -3515,7 +3515,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test25d: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %a = alloca [4 x i32], align 16 %arrayidx = getelementptr inbounds [4 x i32], [4 x i32]* %a, i32 0, i64 0 @@ -3584,7 +3584,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test27: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %tmp = alloca %struct.small*, align 8 %tmp1 = call i32 (...) @dummy(%struct.small** %tmp) @@ -3671,7 +3671,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test28b: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %test = alloca [33 x i8], align 16 %arraydecay = getelementptr inbounds [33 x i8], [33 x i8]* %test, i32 0, i32 0 @@ -3731,7 +3731,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test29b: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %test = alloca [5 x i8], align 1 %arraydecay = getelementptr inbounds [5 x i8], [5 x i8]* %test, i32 0, i32 0 @@ -3800,7 +3800,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test30b: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %test = alloca %struct.small_char, align 4 %test.coerce = alloca { i64, i8 } @@ -3870,7 +3870,7 @@ ; DARWIN-X64: callq ___stack_chk_fail ; MSVC-I386-LABEL: test31b: -; MSVC-I386: movl ___security_cookie, +; MSVC-I386: xorl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 %test = alloca i8*, align 8 %0 = alloca i8, i64 5 Index: llvm/test/DebugInfo/COFF/fpo-stack-protect.ll =================================================================== --- llvm/test/DebugInfo/COFF/fpo-stack-protect.ll +++ llvm/test/DebugInfo/COFF/fpo-stack-protect.ll @@ -15,9 +15,11 @@ ; CHECK: subl $20, %esp ; CHECK: .cv_fpo_stackalloc 20 ; CHECK: .cv_fpo_endprologue -; CHECK: ___security_cookie +; CHECK: movl %esp, %[[REG:[^ ]*]] +; CHECK-DAG: xorl ___security_cookie, %[[REG]] +; CHECK-DAG: movl %[[REG]], 16(%esp) -; CHECK: movl 28(%esp), %esi +; CHECK-DAG: movl 28(%esp), %esi ; CHECK: movl %esi, {{[0-9]*}}(%esp) ; CHECK: movl %esi, {{[0-9]*}}(%esp) ; CHECK: movl %esi, {{[0-9]*}}(%esp)