[llvm] r272053 - [stack-protection] Add support for MSVC buffer security check
Etienne Bergeron via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 7 13:15:36 PDT 2016
Author: etienneb
Date: Tue Jun 7 15:15:35 2016
New Revision: 272053
URL: http://llvm.org/viewvc/llvm-project?rev=272053&view=rev
Log:
[stack-protection] Add support for MSVC buffer security check
Summary:
This patch is adding support for the MSVC buffer security check implementation
The buffer security check is turned on with the '/GS' compiler switch.
* https://msdn.microsoft.com/en-us/library/8dbf701c.aspx
* To be added to clang here: http://reviews.llvm.org/D20347
Some overview of buffer security check feature and implementation:
* https://msdn.microsoft.com/en-us/library/aa290051(VS.71).aspx
* http://www.ksyash.com/2011/01/buffer-overflow-protection-3/
* http://blog.osom.info/2012/02/understanding-vs-c-compilers-buffer.html
For the following example:
```
int example(int offset, int index) {
char buffer[10];
memset(buffer, 0xCC, index);
return buffer[index];
}
```
The MSVC compiler is adding these instructions to perform stack integrity check:
```
push ebp
mov ebp,esp
sub esp,50h
[1] mov eax,dword ptr [__security_cookie (01068024h)]
[2] xor eax,ebp
[3] mov dword ptr [ebp-4],eax
push ebx
push esi
push edi
mov eax,dword ptr [index]
push eax
push 0CCh
lea ecx,[buffer]
push ecx
call _memset (010610B9h)
add esp,0Ch
mov eax,dword ptr [index]
movsx eax,byte ptr buffer[eax]
pop edi
pop esi
pop ebx
[4] mov ecx,dword ptr [ebp-4]
[5] xor ecx,ebp
[6] call @__security_check_cookie at 4 (01061276h)
mov esp,ebp
pop ebp
ret
```
The instrumentation above is:
* [1] is loading the global security canary,
* [3] is storing the local computed ([2]) canary to the guard slot,
* [4] is loading the guard slot and ([5]) re-compute the global canary,
* [6] is validating the resulting canary with the '__security_check_cookie' and performs error handling.
Overview of the current stack-protection implementation:
* lib/CodeGen/StackProtector.cpp
* There is a default stack-protection implementation applied on intermediate representation.
* The target can overload 'getIRStackGuard' method if it has a standard location for the stack protector cookie.
* An intrinsic 'Intrinsic::stackprotector' is added to the prologue. It will be expanded by the instruction selection pass (DAG or Fast).
* Basic Blocks are added to every instrumented function to receive the code for handling stack guard validation and errors handling.
* Guard manipulation and comparison are added directly to the intermediate representation.
* lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
* lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
* There is an implementation that adds instrumentation during instruction selection (for better handling of sibbling calls).
* see long comment above 'class StackProtectorDescriptor' declaration.
* The target needs to override 'getSDagStackGuard' to activate SDAG stack protection generation. (note: getIRStackGuard MUST be nullptr).
* 'getSDagStackGuard' returns the appropriate stack guard (security cookie)
* The code is generated by 'SelectionDAGBuilder.cpp' and 'SelectionDAGISel.cpp'.
* include/llvm/Target/TargetLowering.h
* Contains function to retrieve the default Guard 'Value'; should be overriden by each target to select which implementation is used and provide Guard 'Value'.
* lib/Target/X86/X86ISelLowering.cpp
* Contains the x86 specialisation; Guard 'Value' used by the SelectionDAG algorithm.
Function-based Instrumentation:
* The MSVC doesn't inline the stack guard comparison in every function. Instead, a call to '__security_check_cookie' is added to the epilogue before every return instructions.
* To support function-based instrumentation, this patch is
* adding a function to get the function-based check (llvm 'Value', see include/llvm/Target/TargetLowering.h),
* If provided, the stack protection instrumentation won't be inlined and a call to that function will be added to the prologue.
* modifying (SelectionDAGISel.cpp) do avoid producing basic blocks used for inline instrumentation,
* generating the function-based instrumentation during the ISEL pass (SelectionDAGBuilder.cpp),
* if FastISEL (not SelectionDAG), using the fallback which rely on the same function-based implemented over intermediate representation (StackProtector.cpp).
Modifications
* adding support for MSVC (lib/Target/X86/X86ISelLowering.cpp)
* adding support function-based instrumentation (lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp, .h)
Results
* IR generated instrumentation:
```
clang-cl /GS test.cc /Od /c -mllvm -print-isel-input
```
```
*** Final LLVM Code input to ISel ***
; Function Attrs: nounwind sspstrong
define i32 @"\01?example@@YAHHH at Z"(i32 %offset, i32 %index) #0 {
entry:
%StackGuardSlot = alloca i8* <<<-- Allocated guard slot
%0 = call i8* @llvm.stackguard() <<<-- Loading Stack Guard value
call void @llvm.stackprotector(i8* %0, i8** %StackGuardSlot) <<<-- Prologue intrinsic call (store to Guard slot)
%index.addr = alloca i32, align 4
%offset.addr = alloca i32, align 4
%buffer = alloca [10 x i8], align 1
store i32 %index, i32* %index.addr, align 4
store i32 %offset, i32* %offset.addr, align 4
%arraydecay = getelementptr inbounds [10 x i8], [10 x i8]* %buffer, i32 0, i32 0
%1 = load i32, i32* %index.addr, align 4
call void @llvm.memset.p0i8.i32(i8* %arraydecay, i8 -52, i32 %1, i32 1, i1 false)
%2 = load i32, i32* %index.addr, align 4
%arrayidx = getelementptr inbounds [10 x i8], [10 x i8]* %buffer, i32 0, i32 %2
%3 = load i8, i8* %arrayidx, align 1
%conv = sext i8 %3 to i32
%4 = load volatile i8*, i8** %StackGuardSlot <<<-- Loading Guard slot
call void @__security_check_cookie(i8* %4) <<<-- Epilogue function-based check
ret i32 %conv
}
```
* SelectionDAG generated instrumentation:
```
clang-cl /GS test.cc /O1 /c /FA
```
```
"?example@@YAHHH at Z": # @"\01?example@@YAHHH at Z"
# BB#0: # %entry
pushl %esi
subl $16, %esp
movl ___security_cookie, %eax <<<-- Loading Stack Guard value
movl 28(%esp), %esi
movl %eax, 12(%esp) <<<-- Store to Guard slot
leal 2(%esp), %eax
pushl %esi
pushl $204
pushl %eax
calll _memset
addl $12, %esp
movsbl 2(%esp,%esi), %esi
movl 12(%esp), %ecx <<<-- Loading Guard slot
calll @__security_check_cookie at 4 <<<-- Epilogue function-based check
movl %esi, %eax
addl $16, %esp
popl %esi
retl
```
Reviewers: kcc, pcc, eugenis, rnk
Subscribers: majnemer, llvm-commits, hans, thakis, rnk
Differential Revision: http://reviews.llvm.org/D20346
Added:
llvm/trunk/test/CodeGen/X86/stack-protector-msvc.ll
Modified:
llvm/trunk/include/llvm/Target/TargetLowering.h
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
llvm/trunk/lib/CodeGen/StackProtector.cpp
llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.h
llvm/trunk/test/CodeGen/X86/stack-protector-weight.ll
llvm/trunk/test/CodeGen/X86/stack-protector.ll
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=272053&r1=272052&r2=272053&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Tue Jun 7 15:15:35 2016
@@ -1078,8 +1078,8 @@ public:
/// LOAD_STACK_GUARD, or customize @llvm.stackguard().
virtual Value *getIRStackGuard(IRBuilder<> &IRB) const;
- /// Inserts necessary declarations for SSP purpose. Should be used only when
- /// getIRStackGuard returns nullptr.
+ /// Inserts necessary declarations for SSP (stack protection) purpose.
+ /// Should be used only when getIRStackGuard returns nullptr.
virtual void insertSSPDeclarations(Module &M) const;
/// Return the variable that's previously inserted by insertSSPDeclarations,
@@ -1087,6 +1087,12 @@ public:
/// getIRStackGuard returns nullptr.
virtual Value *getSDagStackGuard(const Module &M) const;
+ /// If the target has a standard stack protection check function that
+ /// performs validation and error handling, returns the function. Otherwise,
+ /// returns nullptr. Must be previously inserted by insertSSPDeclarations.
+ /// Should be used only when getIRStackGuard returns nullptr.
+ virtual Value *getSSPStackGuardCheck(const Module &M) const;
+
/// If the target has a standard location for the unsafe stack pointer,
/// returns the address of that location. Otherwise, returns nullptr.
virtual Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const;
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=272053&r1=272052&r2=272053&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Tue Jun 7 15:15:35 2016
@@ -2040,6 +2040,40 @@ void SelectionDAGBuilder::visitSPDescrip
const Module &M = *ParentBB->getParent()->getFunction()->getParent();
unsigned Align = DL->getPrefTypeAlignment(Type::getInt8PtrTy(M.getContext()));
+ // Generate code to load the content of the guard slot.
+ SDValue StackSlot = DAG.getLoad(
+ PtrTy, dl, DAG.getEntryNode(), StackSlotPtr,
+ MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), true,
+ false, false, Align);
+
+ // 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.
+ // Generate a call to that function with the content of the guard slot as
+ // argument.
+ auto *Fn = cast<Function>(GuardCheck);
+ FunctionType *FnTy = Fn->getFunctionType();
+ assert(FnTy->getNumParams() == 1 && "Invalid function signature");
+
+ TargetLowering::ArgListTy Args;
+ TargetLowering::ArgListEntry Entry;
+ Entry.Node = StackSlot;
+ Entry.Ty = FnTy->getParamType(0);
+ if (Fn->hasAttribute(1, Attribute::AttrKind::InReg))
+ Entry.isInReg = true;
+ Args.push_back(Entry);
+
+ TargetLowering::CallLoweringInfo CLI(DAG);
+ CLI.setDebugLoc(getCurSDLoc())
+ .setChain(DAG.getEntryNode())
+ .setCallee(Fn->getCallingConv(), FnTy->getReturnType(),
+ getValue(GuardCheck), std::move(Args));
+
+ std::pair<SDValue, SDValue> Result = TLI.LowerCallTo(CLI);
+ DAG.setRoot(Result.second);
+ return;
+ }
+
// If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
// Otherwise, emit a volatile load to retrieve the stack guard value.
SDValue Chain = DAG.getEntryNode();
@@ -2054,11 +2088,6 @@ void SelectionDAGBuilder::visitSPDescrip
true, false, false, Align);
}
- SDValue StackSlot = DAG.getLoad(
- PtrTy, dl, DAG.getEntryNode(), StackSlotPtr,
- MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), true,
- false, false, Align);
-
// Perform the comparison via a subtract/getsetcc.
EVT VT = Guard.getValueType();
SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, Guard, StackSlot);
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=272053&r1=272052&r2=272053&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Tue Jun 7 15:15:35 2016
@@ -456,7 +456,14 @@ private:
///
/// c. After we finish selecting the basic block, in FinishBasicBlock if
/// the StackProtectorDescriptor attached to the SelectionDAGBuilder is
- /// initialized, we first find a splice point in the parent basic block
+ /// initialized, we produce the validation code with one of these
+ /// techniques:
+ /// 1) with a call to a guard check function
+ /// 2) with inlined instrumentation
+ ///
+ /// 1) We insert a call to the check function before the terminator.
+ ///
+ /// 2) We first find a splice point in the parent basic block
/// before the terminator and then splice the terminator of said basic
/// block into the success basic block. Then we code-gen a new tail for
/// the parent basic block consisting of the two loads, the comparison,
@@ -475,15 +482,22 @@ private:
return ParentMBB && SuccessMBB && FailureMBB;
}
+ bool shouldEmitFunctionBasedCheckStackProtector() const {
+ return ParentMBB && !SuccessMBB && !FailureMBB;
+ }
+
/// Initialize the stack protector descriptor structure for a new basic
/// block.
- void initialize(const BasicBlock *BB, MachineBasicBlock *MBB) {
+ void initialize(const BasicBlock *BB, MachineBasicBlock *MBB,
+ bool FunctionBasedInstrumentation) {
// Make sure we are not initialized yet.
assert(!shouldEmitStackProtector() && "Stack Protector Descriptor is "
"already initialized!");
ParentMBB = MBB;
- SuccessMBB = AddSuccessorMBB(BB, MBB, /* IsLikely */ true);
- FailureMBB = AddSuccessorMBB(BB, MBB, /* IsLikely */ false, FailureMBB);
+ if (!FunctionBasedInstrumentation) {
+ SuccessMBB = AddSuccessorMBB(BB, MBB, /* IsLikely */ true);
+ FailureMBB = AddSuccessorMBB(BB, MBB, /* IsLikely */ false, FailureMBB);
+ }
}
/// Reset state that changes when we handle different basic blocks.
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=272053&r1=272052&r2=272053&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Jun 7 15:15:35 2016
@@ -1463,8 +1463,12 @@ void SelectionDAGISel::SelectAllBasicBlo
LowerArguments(Fn);
}
}
- if (getAnalysis<StackProtector>().shouldEmitSDCheck(*LLVMBB))
- SDB->SPDescriptor.initialize(LLVMBB, FuncInfo->MBBMap[LLVMBB]);
+ if (getAnalysis<StackProtector>().shouldEmitSDCheck(*LLVMBB)) {
+ bool FunctionBasedInstrumentation =
+ TLI->getSSPStackGuardCheck(*Fn.getParent());
+ SDB->SPDescriptor.initialize(LLVMBB, FuncInfo->MBBMap[LLVMBB],
+ FunctionBasedInstrumentation);
+ }
if (Begin != BI)
++NumDAGBlocks;
@@ -1552,7 +1556,7 @@ static bool MIIsInTerminatorSequence(con
/// terminator, but additionally the copies that move the vregs into the
/// physical registers.
static MachineBasicBlock::iterator
-FindSplitPointForStackProtector(MachineBasicBlock *BB, DebugLoc DL) {
+FindSplitPointForStackProtector(MachineBasicBlock *BB) {
MachineBasicBlock::iterator SplitPoint = BB->getFirstTerminator();
//
if (SplitPoint == BB->begin())
@@ -1593,7 +1597,23 @@ SelectionDAGISel::FinishBasicBlock() {
}
// Handle stack protector.
- if (SDB->SPDescriptor.shouldEmitStackProtector()) {
+ if (SDB->SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
+ // The target provides a guard check function. There is no need to
+ // generate error handling code or to split current basic block.
+ MachineBasicBlock *ParentMBB = SDB->SPDescriptor.getParentMBB();
+
+ // Add load and check to the basicblock.
+ FuncInfo->MBB = ParentMBB;
+ FuncInfo->InsertPt =
+ FindSplitPointForStackProtector(ParentMBB);
+ SDB->visitSPDescriptorParent(SDB->SPDescriptor, ParentMBB);
+ CurDAG->setRoot(SDB->getRoot());
+ SDB->clear();
+ CodeGenAndEmitDAG();
+
+ // Clear the Per-BB State.
+ SDB->SPDescriptor.resetPerBBState();
+ } else if (SDB->SPDescriptor.shouldEmitStackProtector()) {
MachineBasicBlock *ParentMBB = SDB->SPDescriptor.getParentMBB();
MachineBasicBlock *SuccessMBB = SDB->SPDescriptor.getSuccessMBB();
@@ -1604,7 +1624,7 @@ SelectionDAGISel::FinishBasicBlock() {
// register allocation issues caused by us splitting the parent mbb. The
// register allocator will clean up said virtual copies later on.
MachineBasicBlock::iterator SplitPoint =
- FindSplitPointForStackProtector(ParentMBB, SDB->getCurDebugLoc());
+ FindSplitPointForStackProtector(ParentMBB);
// Splice the terminator of ParentMBB into SuccessMBB.
SuccessMBB->splice(SuccessMBB->end(), ParentMBB,
Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=272053&r1=272052&r2=272053&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/StackProtector.cpp (original)
+++ llvm/trunk/lib/CodeGen/StackProtector.cpp Tue Jun 7 15:15:35 2016
@@ -18,6 +18,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
+#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/Passes.h"
@@ -95,11 +96,19 @@ bool StackProtector::runOnFunction(Funct
Attribute Attr = Fn.getFnAttribute("stack-protector-buffer-size");
if (Attr.isStringAttribute() &&
Attr.getValueAsString().getAsInteger(10, SSPBufferSize))
- return false; // Invalid integer string
+ return false; // Invalid integer string
if (!RequiresStackProtector())
return false;
+ // TODO(etienneb): Functions with funclets are not correctly supported now.
+ // Do nothing if this is funclet-based personality.
+ if (Fn.hasPersonalityFn()) {
+ EHPersonality Personality = classifyEHPersonality(Fn.getPersonalityFn());
+ if (isFuncletEHPersonality(Personality))
+ return false;
+ }
+
++NumFunProtected;
return InsertStackProtectors();
}
@@ -313,9 +322,9 @@ static bool CreatePrologue(Function *F,
PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext());
AI = B.CreateAlloca(PtrTy, nullptr, "StackGuardSlot");
- Value *Guard = getStackGuard(TLI, M, B, &SupportsSelectionDAGSP);
+ Value *GuardSlot = getStackGuard(TLI, M, B, &SupportsSelectionDAGSP);
B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackprotector),
- {Guard, AI});
+ {GuardSlot, AI});
return SupportsSelectionDAGSP;
}
@@ -336,12 +345,36 @@ bool StackProtector::InsertStackProtecto
if (!RI)
continue;
+ // Generate prologue instrumentation if not already generated.
if (!HasPrologue) {
HasPrologue = true;
SupportsSelectionDAGSP &= CreatePrologue(F, M, RI, TLI, AI);
}
- if (!SupportsSelectionDAGSP) {
+ // SelectionDAG based code generation. Nothing else needs to be done here.
+ // The epilogue instrumentation is postponed to SelectionDAG.
+ if (SupportsSelectionDAGSP)
+ break;
+
+ // Set HasIRCheck to true, so that SelectionDAG will not generate its own
+ // version. SelectionDAG called 'shouldEmitSDCheck' to check whether
+ // instrumentation has already been generated.
+ HasIRCheck = true;
+
+ // Generate epilogue instrumentation. The epilogue intrumentation can be
+ // function-based or inlined depending on which mechanism the target is
+ // providing.
+ if (Value* GuardCheck = TLI->getSSPStackGuardCheck(*M)) {
+ // Generate the function-based epilogue instrumentation.
+ // The target provides a guard check function, generate a call to it.
+ IRBuilder<> B(RI);
+ LoadInst *Guard = B.CreateLoad(AI, true, "Guard");
+ CallInst *Call = B.CreateCall(GuardCheck, {Guard});
+ llvm::Function *Function = cast<llvm::Function>(GuardCheck);
+ Call->setAttributes(Function->getAttributes());
+ Call->setCallingConv(Function->getCallingConv());
+ } else {
+ // Generate the epilogue with inline instrumentation.
// If we do not support SelectionDAG based tail calls, generate IR level
// tail calls.
//
@@ -372,10 +405,6 @@ bool StackProtector::InsertStackProtecto
// fail BB generated by the stack protector pseudo instruction.
BasicBlock *FailBB = CreateFailBB();
- // Set HasIRCheck to true, so that SelectionDAG will not generate its own
- // version.
- HasIRCheck = true;
-
// Split the basic block before the return instruction.
BasicBlock *NewBB = BB->splitBasicBlock(RI->getIterator(), "SP_return");
Modified: llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp?rev=272053&r1=272052&r2=272053&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp Tue Jun 7 15:15:35 2016
@@ -898,7 +898,7 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, VT, Expand);
}
- // For most targets @llvm.get.dynamic.area.offest just returns 0.
+ // For most targets @llvm.get.dynamic.area.offset just returns 0.
setOperationAction(ISD::GET_DYNAMIC_AREA_OFFSET, VT, Expand);
}
@@ -1833,3 +1833,7 @@ void TargetLoweringBase::insertSSPDeclar
Value *TargetLoweringBase::getSDagStackGuard(const Module &M) const {
return M.getGlobalVariable("__stack_chk_guard");
}
+
+Value *TargetLoweringBase::getSSPStackGuardCheck(const Module &M) const {
+ return nullptr;
+}
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=272053&r1=272052&r2=272053&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Jun 7 15:15:35 2016
@@ -1974,8 +1974,39 @@ Value *X86TargetLowering::getIRStackGuar
}
void X86TargetLowering::insertSSPDeclarations(Module &M) const {
- if (!Subtarget.isTargetGlibc())
- TargetLowering::insertSSPDeclarations(M);
+ // MSVC CRT provides functionalities for stack protection.
+ if (Subtarget.getTargetTriple().isOSMSVCRT()) {
+ // MSVC CRT has a global variable holding security cookie.
+ M.getOrInsertGlobal("__security_cookie",
+ Type::getInt8PtrTy(M.getContext()));
+
+ // MSVC CRT has a function to validate security cookie.
+ auto *SecurityCheckCookie = cast<Function>(
+ M.getOrInsertFunction("__security_check_cookie",
+ Type::getVoidTy(M.getContext()),
+ Type::getInt8PtrTy(M.getContext()), nullptr));
+ SecurityCheckCookie->setCallingConv(CallingConv::X86_FastCall);
+ SecurityCheckCookie->addAttribute(1, Attribute::AttrKind::InReg);
+ return;
+ }
+ // glibc has a special slot for the stack guard.
+ if (Subtarget.isTargetGlibc())
+ return;
+ TargetLowering::insertSSPDeclarations(M);
+}
+
+Value *X86TargetLowering::getSDagStackGuard(const Module &M) const {
+ // MSVC CRT has a global variable holding security cookie.
+ if (Subtarget.getTargetTriple().isOSMSVCRT())
+ return M.getGlobalVariable("__security_cookie");
+ return TargetLowering::getSDagStackGuard(M);
+}
+
+Value *X86TargetLowering::getSSPStackGuardCheck(const Module &M) const {
+ // MSVC CRT has a function to validate security cookie.
+ if (Subtarget.getTargetTriple().isOSMSVCRT())
+ return M.getFunction("__security_check_cookie");
+ return TargetLowering::getSSPStackGuardCheck(M);
}
Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=272053&r1=272052&r2=272053&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Tue Jun 7 15:15:35 2016
@@ -969,7 +969,10 @@ namespace llvm {
/// returns the address of that location. Otherwise, returns nullptr.
Value *getIRStackGuard(IRBuilder<> &IRB) const override;
+ bool useLoadStackGuardNode() const override;
void insertSSPDeclarations(Module &M) const override;
+ Value *getSDagStackGuard(const Module &M) const override;
+ Value *getSSPStackGuardCheck(const Module &M) const override;
/// Return true if the target stores SafeStack pointer at a fixed offset in
/// some non-standard address space, and populates the address space and
@@ -981,7 +984,6 @@ namespace llvm {
bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override;
- bool useLoadStackGuardNode() const override;
/// \brief Customize the preferred legalization strategy for certain types.
LegalizeTypeAction getPreferredVectorAction(EVT VT) const override;
Added: llvm/trunk/test/CodeGen/X86/stack-protector-msvc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stack-protector-msvc.ll?rev=272053&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/stack-protector-msvc.ll (added)
+++ llvm/trunk/test/CodeGen/X86/stack-protector-msvc.ll Tue Jun 7 15:15:35 2016
@@ -0,0 +1,40 @@
+
+; 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 at 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
+
+@"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]
+
+define void @test(i8* %a) nounwind ssp {
+entry:
+ %a_addr = alloca i8* ; <i8**> [#uses=2]
+ %buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store i8* %a, i8** %a_addr
+ %buf1 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1]
+ %0 = load i8*, i8** %a_addr, align 4 ; <i8*> [#uses=1]
+ %1 = call i8* @strcpy(i8* %buf1, i8* %0) nounwind ; <i8*> [#uses=0]
+ %buf2 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1]
+ %2 = call i32 (i8*, ...) @printf(i8* getelementptr ([11 x i8], [11 x i8]* @"\01LC", i32 0, i32 0), i8* %buf2) nounwind ; <i32> [#uses=0]
+ br label %return
+
+return: ; preds = %entry
+ ret void
+}
+
+declare i8* @strcpy(i8*, i8*) nounwind
+
+declare i32 @printf(i8*, ...) nounwind
+
Modified: llvm/trunk/test/CodeGen/X86/stack-protector-weight.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stack-protector-weight.ll?rev=272053&r1=272052&r2=272053&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/stack-protector-weight.ll (original)
+++ llvm/trunk/test/CodeGen/X86/stack-protector-weight.ll Tue Jun 7 15:15:35 2016
@@ -1,17 +1,31 @@
-; RUN: llc -mtriple=x86_64-apple-darwin -print-machineinstrs=expand-isel-pseudos -enable-selectiondag-sp=true %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=SELDAG
-; RUN: llc -mtriple=x86_64-apple-darwin -print-machineinstrs=expand-isel-pseudos -enable-selectiondag-sp=false %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=IR
-
-; SELDAG: # Machine code for function test_branch_weights:
-; SELDAG: Successors according to CFG: BB#[[SUCCESS:[0-9]+]]({{[0-9a-fx/= ]+}}100.00%) BB#[[FAILURE:[0-9]+]]
-; SELDAG: BB#[[FAILURE]]:
-; SELDAG: CALL64pcrel32 <es:__stack_chk_fail>
-; SELDAG: BB#[[SUCCESS]]:
-
-; IR: # Machine code for function test_branch_weights:
-; IR: Successors according to CFG: BB#[[SUCCESS:[0-9]+]]({{[0-9a-fx/= ]+}}100.00%) BB#[[FAILURE:[0-9]+]]
-; IR: BB#[[SUCCESS]]:
-; IR: BB#[[FAILURE]]:
-; IR: CALL64pcrel32 <ga:@__stack_chk_fail>
+; RUN: llc -mtriple=x86_64-apple-darwin -print-machineinstrs=expand-isel-pseudos -enable-selectiondag-sp=true %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=DARWIN-SELDAG
+; RUN: llc -mtriple=x86_64-apple-darwin -print-machineinstrs=expand-isel-pseudos -enable-selectiondag-sp=false %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=DARWIN-IR
+; RUN: llc -mtriple=i386-pc-windows-msvc -print-machineinstrs=expand-isel-pseudos -enable-selectiondag-sp=true %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=MSVC-SELDAG
+; RUN: llc -mtriple=i386-pc-windows-msvc -print-machineinstrs=expand-isel-pseudos -enable-selectiondag-sp=false %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=MSVC-IR
+
+; DARWIN-SELDAG: # Machine code for function test_branch_weights:
+; DARWIN-SELDAG: Successors according to CFG: BB#[[SUCCESS:[0-9]+]]({{[0-9a-fx/= ]+}}100.00%) BB#[[FAILURE:[0-9]+]]
+; DARWIN-SELDAG: BB#[[FAILURE]]:
+; DARWIN-SELDAG: CALL64pcrel32 <es:__stack_chk_fail>
+; DARWIN-SELDAG: BB#[[SUCCESS]]:
+
+; DARWIN-IR: # Machine code for function test_branch_weights:
+; DARWIN-IR: Successors according to CFG: BB#[[SUCCESS:[0-9]+]]({{[0-9a-fx/= ]+}}100.00%) BB#[[FAILURE:[0-9]+]]
+; DARWIN-IR: BB#[[SUCCESS]]:
+; DARWIN-IR: BB#[[FAILURE]]:
+; DARWIN-IR: CALL64pcrel32 <ga:@__stack_chk_fail>
+
+; MSVC-SELDAG: # Machine code for function test_branch_weights:
+; MSVC-SELDAG: mem:Volatile LD4[@__security_cookie]
+; MSVC-SELDAG: ST4[FixedStack0]
+; MSVC-SELDAG: LD4[FixedStack0]
+; MSVC-SELDAG: CALLpcrel32 <ga:@__security_check_cookie>
+
+; MSVC-IR: # Machine code for function test_branch_weights:
+; MSVC-IR: mem:Volatile LD4[@__security_cookie]
+; MSVC-IR: ST4[FixedStack0]
+; MSVC-IR: LD4[%StackGuardSlot]
+; MSVC-IR: CALLpcrel32 <ga:@__security_check_cookie>
define i32 @test_branch_weights(i32 %n) #0 {
entry:
@@ -33,4 +47,4 @@ declare void @foo2(i32*)
declare void @llvm.lifetime.end(i64, i8* nocapture)
-attributes #0 = { ssp "stack-protector-buffer-size"="8" }
+attributes #0 = { sspstrong "stack-protector-buffer-size"="8" }
Modified: llvm/trunk/test/CodeGen/X86/stack-protector.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stack-protector.ll?rev=272053&r1=272052&r2=272053&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/stack-protector.ll (original)
+++ llvm/trunk/test/CodeGen/X86/stack-protector.ll Tue Jun 7 15:15:35 2016
@@ -3,6 +3,7 @@
; RUN: llc -code-model=kernel -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-KERNEL-X64 %s
; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | FileCheck --check-prefix=DARWIN-X64 %s
; RUN: llc -mtriple=amd64-pc-openbsd < %s -o - | FileCheck --check-prefix=OPENBSD-AMD64 %s
+; RUN: llc -mtriple=i386-pc-windows-msvc < %s -o - | FileCheck -check-prefix=MSVC-I386 %s
%struct.foo = type { [16 x i8] }
%struct.foo.0 = type { [4 x i8] }
@@ -40,6 +41,10 @@ entry:
; DARWIN-X64-LABEL: test1a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test1a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a.addr = alloca i8*, align 8
%buf = alloca [16 x i8], align 16
store i8* %a, i8** %a.addr, align 8
@@ -76,6 +81,10 @@ entry:
; OPENBSD-AMD64-LABEL: test1b:
; OPENBSD-AMD64: movq __guard_local(%rip)
; OPENBSD-AMD64: callq __stack_smash_handler
+
+; MSVC-I386-LABEL: test1b:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a.addr = alloca i8*, align 8
%buf = alloca [16 x i8], align 16
store i8* %a, i8** %a.addr, align 8
@@ -108,6 +117,10 @@ entry:
; DARWIN-X64-LABEL: test1c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test1c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a.addr = alloca i8*, align 8
%buf = alloca [16 x i8], align 16
store i8* %a, i8** %a.addr, align 8
@@ -140,6 +153,10 @@ entry:
; DARWIN-X64-LABEL: test1d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test1d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a.addr = alloca i8*, align 8
%buf = alloca [16 x i8], align 16
store i8* %a, i8** %a.addr, align 8
@@ -171,6 +188,10 @@ entry:
; DARWIN-X64-LABEL: test2a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test2a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a.addr = alloca i8*, align 8
%b = alloca %struct.foo, align 1
store i8* %a, i8** %a.addr, align 8
@@ -239,6 +260,10 @@ entry:
; DARWIN-X64-LABEL: test2c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test2c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a.addr = alloca i8*, align 8
%b = alloca %struct.foo, align 1
store i8* %a, i8** %a.addr, align 8
@@ -273,6 +298,10 @@ entry:
; DARWIN-X64-LABEL: test2d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test2d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a.addr = alloca i8*, align 8
%b = alloca %struct.foo, align 1
store i8* %a, i8** %a.addr, align 8
@@ -306,6 +335,10 @@ entry:
; DARWIN-X64-LABEL: test3a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test3a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a.addr = alloca i8*, align 8
%buf = alloca [4 x i8], align 1
store i8* %a, i8** %a.addr, align 8
@@ -338,6 +371,10 @@ entry:
; DARWIN-X64-LABEL: test3b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test3b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a.addr = alloca i8*, align 8
%buf = alloca [4 x i8], align 1
store i8* %a, i8** %a.addr, align 8
@@ -370,6 +407,10 @@ entry:
; DARWIN-X64-LABEL: test3c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test3c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a.addr = alloca i8*, align 8
%buf = alloca [4 x i8], align 1
store i8* %a, i8** %a.addr, align 8
@@ -402,6 +443,10 @@ entry:
; DARWIN-X64-LABEL: test3d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test3d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a.addr = alloca i8*, align 8
%buf = alloca [4 x i8], align 1
store i8* %a, i8** %a.addr, align 8
@@ -433,6 +478,10 @@ entry:
; DARWIN-X64-LABEL: test4a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test4a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a.addr = alloca i8*, align 8
%b = alloca %struct.foo.0, align 1
store i8* %a, i8** %a.addr, align 8
@@ -467,6 +516,10 @@ entry:
; DARWIN-X64-LABEL: test4b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test4b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a.addr = alloca i8*, align 8
%b = alloca %struct.foo.0, align 1
store i8* %a, i8** %a.addr, align 8
@@ -501,6 +554,10 @@ entry:
; DARWIN-X64-LABEL: test4c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test4c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a.addr = alloca i8*, align 8
%b = alloca %struct.foo.0, align 1
store i8* %a, i8** %a.addr, align 8
@@ -535,6 +592,10 @@ entry:
; DARWIN-X64-LABEL: test4d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test4d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a.addr = alloca i8*, align 8
%b = alloca %struct.foo.0, align 1
store i8* %a, i8** %a.addr, align 8
@@ -568,6 +629,10 @@ entry:
; DARWIN-X64-LABEL: test5a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test5a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a.addr = alloca i8*, align 8
store i8* %a, i8** %a.addr, align 8
%0 = load i8*, i8** %a.addr, align 8
@@ -596,6 +661,10 @@ entry:
; DARWIN-X64-LABEL: test5b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test5b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a.addr = alloca i8*, align 8
store i8* %a, i8** %a.addr, align 8
%0 = load i8*, i8** %a.addr, align 8
@@ -624,6 +693,10 @@ entry:
; DARWIN-X64-LABEL: test5c:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test5c:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a.addr = alloca i8*, align 8
store i8* %a, i8** %a.addr, align 8
%0 = load i8*, i8** %a.addr, align 8
@@ -652,6 +725,10 @@ entry:
; DARWIN-X64-LABEL: test5d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test5d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a.addr = alloca i8*, align 8
store i8* %a, i8** %a.addr, align 8
%0 = load i8*, i8** %a.addr, align 8
@@ -679,6 +756,10 @@ entry:
; DARWIN-X64-LABEL: test6a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test6a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%retval = alloca i32, align 4
%a = alloca i32, align 4
%j = alloca i32*, align 8
@@ -711,6 +792,11 @@ entry:
; DARWIN-X64-LABEL: test6b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+
+; MSVC-I386-LABEL: test6b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%retval = alloca i32, align 4
%a = alloca i32, align 4
%j = alloca i32*, align 8
@@ -743,6 +829,10 @@ entry:
; DARWIN-X64-LABEL: test6c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test6c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%retval = alloca i32, align 4
%a = alloca i32, align 4
%j = alloca i32*, align 8
@@ -775,6 +865,10 @@ entry:
; DARWIN-X64-LABEL: test6d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test6d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%retval = alloca i32, align 4
%a = alloca i32, align 4
%j = alloca i32*, align 8
@@ -806,6 +900,10 @@ entry:
; DARWIN-X64-LABEL: test7a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test7a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32, align 4
%0 = ptrtoint i32* %a to i64
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
@@ -833,6 +931,10 @@ entry:
; DARWIN-X64-LABEL: test7b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test7b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32, align 4
%0 = ptrtoint i32* %a to i64
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
@@ -860,6 +962,10 @@ entry:
; DARWIN-X64-LABEL: test7c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test7c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32, align 4
%0 = ptrtoint i32* %a to i64
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
@@ -887,6 +993,10 @@ entry:
; DARWIN-X64-LABEL: test7d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test7d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32, align 4
%0 = ptrtoint i32* %a to i64
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
@@ -913,6 +1023,10 @@ entry:
; DARWIN-X64-LABEL: test8a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test8a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%b = alloca i32, align 4
call void @funcall(i32* %b)
ret void
@@ -939,6 +1053,10 @@ entry:
; DARWIN-X64-LABEL: test8b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test8b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%b = alloca i32, align 4
call void @funcall(i32* %b)
ret void
@@ -965,6 +1083,10 @@ entry:
; DARWIN-X64-LABEL: test8c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test8c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%b = alloca i32, align 4
call void @funcall(i32* %b)
ret void
@@ -991,6 +1113,10 @@ entry:
; DARWIN-X64-LABEL: test8d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test8d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%b = alloca i32, align 4
call void @funcall(i32* %b)
ret void
@@ -1016,6 +1142,10 @@ entry:
; DARWIN-X64-LABEL: test9a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test9a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%x = alloca double, align 8
%call = call double @testi_aux()
store double %call, double* %x, align 8
@@ -1046,6 +1176,10 @@ entry:
; DARWIN-X64-LABEL: test9b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test9b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%x = alloca double, align 8
%call = call double @testi_aux()
store double %call, double* %x, align 8
@@ -1076,6 +1210,10 @@ entry:
; DARWIN-X64-LABEL: test9c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test9c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%x = alloca double, align 8
%call = call double @testi_aux()
store double %call, double* %x, align 8
@@ -1106,6 +1244,10 @@ entry:
; DARWIN-X64-LABEL: test9d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test9d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%x = alloca double, align 8
%call = call double @testi_aux()
store double %call, double* %x, align 8
@@ -1135,6 +1277,10 @@ entry:
; DARWIN-X64-LABEL: test10a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test10a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%x = alloca double, align 8
%call = call double @testi_aux()
store double %call, double* %x, align 8
@@ -1180,6 +1326,10 @@ entry:
; DARWIN-X64-LABEL: test10b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test10b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%x = alloca double, align 8
%call = call double @testi_aux()
store double %call, double* %x, align 8
@@ -1225,6 +1375,10 @@ entry:
; DARWIN-X64-LABEL: test10c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test10c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%x = alloca double, align 8
%call = call double @testi_aux()
store double %call, double* %x, align 8
@@ -1270,6 +1424,10 @@ entry:
; DARWIN-X64-LABEL: test10d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test10d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%x = alloca double, align 8
%call = call double @testi_aux()
store double %call, double* %x, align 8
@@ -1314,6 +1472,10 @@ entry:
; DARWIN-X64-LABEL: test11a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test11a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%c = alloca %struct.pair, align 4
%b = alloca i32*, align 8
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
@@ -1344,6 +1506,10 @@ entry:
; DARWIN-X64-LABEL: test11b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test11b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%c = alloca %struct.pair, align 4
%b = alloca i32*, align 8
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
@@ -1374,6 +1540,10 @@ entry:
; DARWIN-X64-LABEL: test11c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test11c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%c = alloca %struct.pair, align 4
%b = alloca i32*, align 8
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
@@ -1404,6 +1574,10 @@ entry:
; DARWIN-X64-LABEL: test11d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test11d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%c = alloca %struct.pair, align 4
%b = alloca i32*, align 8
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
@@ -1433,6 +1607,10 @@ entry:
; DARWIN-X64-LABEL: test12a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test12a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%c = alloca %struct.pair, align 4
%b = alloca i32*, align 8
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
@@ -1462,6 +1640,10 @@ entry:
; DARWIN-X64-LABEL: test12b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test12b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%c = alloca %struct.pair, align 4
%b = alloca i32*, align 8
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
@@ -1490,6 +1672,10 @@ entry:
; DARWIN-X64-LABEL: test12c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test12c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%c = alloca %struct.pair, align 4
%b = alloca i32*, align 8
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
@@ -1519,6 +1705,10 @@ entry:
; DARWIN-X64-LABEL: test12d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test12d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%c = alloca %struct.pair, align 4
%b = alloca i32*, align 8
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
@@ -1547,6 +1737,10 @@ entry:
; DARWIN-X64-LABEL: test13a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test13a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%c = alloca %struct.pair, align 4
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i64 0, i32 1
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %y)
@@ -1574,6 +1768,10 @@ entry:
; DARWIN-X64-LABEL: test13b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test13b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%c = alloca %struct.pair, align 4
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i64 0, i32 1
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %y)
@@ -1601,6 +1799,10 @@ entry:
; DARWIN-X64-LABEL: test13c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test13c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%c = alloca %struct.pair, align 4
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i64 0, i32 1
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %y)
@@ -1628,6 +1830,10 @@ entry:
; DARWIN-X64-LABEL: test13d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test13d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%c = alloca %struct.pair, align 4
%y = getelementptr inbounds %struct.pair, %struct.pair* %c, i64 0, i32 1
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %y)
@@ -1654,6 +1860,10 @@ entry:
; DARWIN-X64-LABEL: test14a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test14a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32, align 4
%add.ptr5 = getelementptr inbounds i32, i32* %a, i64 -12
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
@@ -1681,6 +1891,10 @@ entry:
; DARWIN-X64-LABEL: test14b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test14b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32, align 4
%add.ptr5 = getelementptr inbounds i32, i32* %a, i64 -12
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
@@ -1708,6 +1922,10 @@ entry:
; DARWIN-X64-LABEL: test14c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test14c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32, align 4
%add.ptr5 = getelementptr inbounds i32, i32* %a, i64 -12
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
@@ -1735,6 +1953,10 @@ entry:
; DARWIN-X64-LABEL: test14d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test14d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32, align 4
%add.ptr5 = getelementptr inbounds i32, i32* %a, i64 -12
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
@@ -1762,6 +1984,10 @@ entry:
; DARWIN-X64-LABEL: test15a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test15a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32, align 4
%b = alloca float*, align 8
store i32 0, i32* %a, align 4
@@ -1794,6 +2020,10 @@ entry:
; DARWIN-X64-LABEL: test15b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test15b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32, align 4
%b = alloca float*, align 8
store i32 0, i32* %a, align 4
@@ -1826,6 +2056,10 @@ entry:
; DARWIN-X64-LABEL: test15c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test15c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32, align 4
%b = alloca float*, align 8
store i32 0, i32* %a, align 4
@@ -1858,6 +2092,10 @@ entry:
; DARWIN-X64-LABEL: test15d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test15d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32, align 4
%b = alloca float*, align 8
store i32 0, i32* %a, align 4
@@ -1889,6 +2127,10 @@ entry:
; DARWIN-X64-LABEL: test16a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test16a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32, align 4
store i32 0, i32* %a, align 4
%0 = bitcast i32* %a to float*
@@ -1918,6 +2160,10 @@ entry:
; DARWIN-X64-LABEL: test16b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test16b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32, align 4
store i32 0, i32* %a, align 4
%0 = bitcast i32* %a to float*
@@ -1947,6 +2193,10 @@ entry:
; DARWIN-X64-LABEL: test16c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test16c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32, align 4
store i32 0, i32* %a, align 4
%0 = bitcast i32* %a to float*
@@ -1976,6 +2226,10 @@ entry:
; DARWIN-X64-LABEL: test16d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test16d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32, align 4
store i32 0, i32* %a, align 4
%0 = bitcast i32* %a to float*
@@ -2003,6 +2257,10 @@ entry:
; DARWIN-X64-LABEL: test17a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test17a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%c = alloca %struct.vec, align 16
%y = getelementptr inbounds %struct.vec, %struct.vec* %c, i64 0, i32 0
%add.ptr = getelementptr inbounds <4 x i32>, <4 x i32>* %y, i64 -12
@@ -2031,6 +2289,10 @@ entry:
; DARWIN-X64-LABEL: test17b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test17b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%c = alloca %struct.vec, align 16
%y = getelementptr inbounds %struct.vec, %struct.vec* %c, i64 0, i32 0
%add.ptr = getelementptr inbounds <4 x i32>, <4 x i32>* %y, i64 -12
@@ -2059,6 +2321,10 @@ entry:
; DARWIN-X64-LABEL: test17c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test17c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%c = alloca %struct.vec, align 16
%y = getelementptr inbounds %struct.vec, %struct.vec* %c, i64 0, i32 0
%add.ptr = getelementptr inbounds <4 x i32>, <4 x i32>* %y, i64 -12
@@ -2087,6 +2353,10 @@ entry:
; DARWIN-X64-LABEL: test17d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test17d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%c = alloca %struct.vec, align 16
%y = getelementptr inbounds %struct.vec, %struct.vec* %c, i64 0, i32 0
%add.ptr = getelementptr inbounds <4 x i32>, <4 x i32>* %y, i64 -12
@@ -2114,6 +2384,10 @@ entry:
; DARWIN-X64-LABEL: test18a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test18a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32, align 4
%exn.slot = alloca i8*
%ehselector.slot = alloca i32
@@ -2151,6 +2425,10 @@ entry:
; DARWIN-X64-LABEL: test18b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test18b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32, align 4
%exn.slot = alloca i8*
%ehselector.slot = alloca i32
@@ -2188,6 +2466,10 @@ entry:
; DARWIN-X64-LABEL: test18c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test18c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32, align 4
%exn.slot = alloca i8*
%ehselector.slot = alloca i32
@@ -2225,6 +2507,10 @@ entry:
; DARWIN-X64-LABEL: test18d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test18d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32, align 4
%exn.slot = alloca i8*
%ehselector.slot = alloca i32
@@ -2261,6 +2547,10 @@ entry:
; DARWIN-X64-LABEL: test19a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test19a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%c = alloca %struct.pair, align 4
%exn.slot = alloca i8*
%ehselector.slot = alloca i32
@@ -2301,6 +2591,10 @@ entry:
; DARWIN-X64-LABEL: test19b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test19b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%c = alloca %struct.pair, align 4
%exn.slot = alloca i8*
%ehselector.slot = alloca i32
@@ -2341,6 +2635,10 @@ entry:
; DARWIN-X64-LABEL: test19c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test19c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%c = alloca %struct.pair, align 4
%exn.slot = alloca i8*
%ehselector.slot = alloca i32
@@ -2385,6 +2683,10 @@ entry:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
; DARWIN-X64-NOT: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test19d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%c = alloca %struct.pair, align 4
%exn.slot = alloca i8*
%ehselector.slot = alloca i32
@@ -2423,6 +2725,10 @@ entry:
; DARWIN-X64-LABEL: test20a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test20a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32*, align 8
%b = alloca i32**, align 8
%call = call i32* @getp()
@@ -2454,6 +2760,10 @@ entry:
; DARWIN-X64-LABEL: test20b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test20b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32*, align 8
%b = alloca i32**, align 8
%call = call i32* @getp()
@@ -2485,6 +2795,10 @@ entry:
; DARWIN-X64-LABEL: test20c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test20c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32*, align 8
%b = alloca i32**, align 8
%call = call i32* @getp()
@@ -2516,6 +2830,10 @@ entry:
; DARWIN-X64-LABEL: test20d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test20d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32*, align 8
%b = alloca i32**, align 8
%call = call i32* @getp()
@@ -2546,6 +2864,10 @@ entry:
; DARWIN-X64-LABEL: test21a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test21a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32*, align 8
%b = alloca float**, align 8
%call = call i32* @getp()
@@ -2578,6 +2900,10 @@ entry:
; DARWIN-X64-LABEL: test21b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test21b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca i32*, align 8
%b = alloca float**, align 8
%call = call i32* @getp()
@@ -2610,6 +2936,10 @@ entry:
; DARWIN-X64-LABEL: test21c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test21c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32*, align 8
%b = alloca float**, align 8
%call = call i32* @getp()
@@ -2642,6 +2972,10 @@ entry:
; DARWIN-X64-LABEL: test21d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test21d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca i32*, align 8
%b = alloca float**, align 8
%call = call i32* @getp()
@@ -2673,6 +3007,10 @@ entry:
; DARWIN-X64-LABEL: test22a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test22a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca %class.A, align 1
%array = getelementptr inbounds %class.A, %class.A* %a, i32 0, i32 0
%arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
@@ -2701,6 +3039,10 @@ entry:
; DARWIN-X64-LABEL: test22b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test22b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca %class.A, align 1
%array = getelementptr inbounds %class.A, %class.A* %a, i32 0, i32 0
%arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
@@ -2729,6 +3071,10 @@ entry:
; DARWIN-X64-LABEL: test22c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test22c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca %class.A, align 1
%array = getelementptr inbounds %class.A, %class.A* %a, i32 0, i32 0
%arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
@@ -2757,6 +3103,10 @@ entry:
; DARWIN-X64-LABEL: test22d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test22d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca %class.A, align 1
%array = getelementptr inbounds %class.A, %class.A* %a, i32 0, i32 0
%arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
@@ -2784,6 +3134,10 @@ entry:
; DARWIN-X64-LABEL: test23a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test23a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%x = alloca %struct.deep, align 1
%b = getelementptr inbounds %struct.deep, %struct.deep* %x, i32 0, i32 0
%c = bitcast %union.anon* %b to %struct.anon*
@@ -2816,6 +3170,10 @@ entry:
; DARWIN-X64-LABEL: test23b:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test23b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%x = alloca %struct.deep, align 1
%b = getelementptr inbounds %struct.deep, %struct.deep* %x, i32 0, i32 0
%c = bitcast %union.anon* %b to %struct.anon*
@@ -2848,6 +3206,10 @@ entry:
; DARWIN-X64-LABEL: test23c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test23c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%x = alloca %struct.deep, align 1
%b = getelementptr inbounds %struct.deep, %struct.deep* %x, i32 0, i32 0
%c = bitcast %union.anon* %b to %struct.anon*
@@ -2880,6 +3242,10 @@ entry:
; DARWIN-X64-LABEL: test23d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test23d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%x = alloca %struct.deep, align 1
%b = getelementptr inbounds %struct.deep, %struct.deep* %x, i32 0, i32 0
%c = bitcast %union.anon* %b to %struct.anon*
@@ -2911,6 +3277,10 @@ entry:
; DARWIN-X64-LABEL: test24a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test24a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%n.addr = alloca i32, align 4
%a = alloca i32*, align 8
store i32 %n, i32* %n.addr, align 4
@@ -2943,6 +3313,10 @@ entry:
; DARWIN-X64-LABEL: test24b:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test24b:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%n.addr = alloca i32, align 4
%a = alloca i32*, align 8
store i32 %n, i32* %n.addr, align 4
@@ -2975,6 +3349,10 @@ entry:
; DARWIN-X64-LABEL: test24c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test24c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%n.addr = alloca i32, align 4
%a = alloca i32*, align 8
store i32 %n, i32* %n.addr, align 4
@@ -3007,6 +3385,10 @@ entry:
; DARWIN-X64-LABEL: test24d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test24d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%n.addr = alloca i32, align 4
%a = alloca i32*, align 8
store i32 %n, i32* %n.addr, align 4
@@ -3038,6 +3420,10 @@ entry:
; DARWIN-X64-LABEL: test25a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test25a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca [4 x i32], align 16
%arrayidx = getelementptr inbounds [4 x i32], [4 x i32]* %a, i32 0, i64 0
%0 = load i32, i32* %arrayidx, align 4
@@ -3065,6 +3451,10 @@ entry:
; DARWIN-X64-LABEL: test25b:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test25b:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%a = alloca [4 x i32], align 16
%arrayidx = getelementptr inbounds [4 x i32], [4 x i32]* %a, i32 0, i64 0
%0 = load i32, i32* %arrayidx, align 4
@@ -3092,6 +3482,10 @@ entry:
; DARWIN-X64-LABEL: test25c:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test25c:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca [4 x i32], align 16
%arrayidx = getelementptr inbounds [4 x i32], [4 x i32]* %a, i32 0, i64 0
%0 = load i32, i32* %arrayidx, align 4
@@ -3119,6 +3513,10 @@ entry:
; DARWIN-X64-LABEL: test25d:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test25d:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%a = alloca [4 x i32], align 16
%arrayidx = getelementptr inbounds [4 x i32], [4 x i32]* %a, i32 0, i64 0
%0 = load i32, i32* %arrayidx, align 4
@@ -3148,6 +3546,10 @@ entry:
; DARWIN-X64-LABEL: test26:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test26:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%c = alloca %struct.nest, align 4
%b = getelementptr inbounds %struct.nest, %struct.nest* %c, i32 0, i32 1
%_a = getelementptr inbounds %struct.pair, %struct.pair* %b, i32 0, i32 0
@@ -3180,6 +3582,10 @@ bb:
; DARWIN-X64-LABEL: test27:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test27:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%tmp = alloca %struct.small*, align 8
%tmp1 = call i32 (...) @dummy(%struct.small** %tmp)
%tmp2 = load %struct.small*, %struct.small** %tmp, align 8
@@ -3233,6 +3639,10 @@ entry:
; DARWIN-X64-LABEL: test28a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test28a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%test = alloca [32 x i8], align 16
%arraydecay = getelementptr inbounds [32 x i8], [32 x i8]* %test, i32 0, i32 0
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay)
@@ -3259,6 +3669,10 @@ entry:
; DARWIN-X64-LABEL: test28b:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test28b:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%test = alloca [33 x i8], align 16
%arraydecay = getelementptr inbounds [33 x i8], [33 x i8]* %test, i32 0, i32 0
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay)
@@ -3285,6 +3699,10 @@ entry:
; DARWIN-X64-LABEL: test29a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test29a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%test = alloca [4 x i8], align 1
%arraydecay = getelementptr inbounds [4 x i8], [4 x i8]* %test, i32 0, i32 0
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay)
@@ -3311,6 +3729,10 @@ entry:
; DARWIN-X64-LABEL: test29b:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test29b:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%test = alloca [5 x i8], align 1
%arraydecay = getelementptr inbounds [5 x i8], [5 x i8]* %test, i32 0, i32 0
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay)
@@ -3338,6 +3760,10 @@ entry:
; DARWIN-X64-LABEL: test30a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test30a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%test = alloca %struct.small_char, align 4
%test.coerce = alloca { i64, i8 }
%0 = bitcast { i64, i8 }* %test.coerce to i8*
@@ -3372,6 +3798,10 @@ entry:
; DARWIN-X64-LABEL: test30b:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test30b:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%test = alloca %struct.small_char, align 4
%test.coerce = alloca { i64, i8 }
%0 = bitcast { i64, i8 }* %test.coerce to i8*
@@ -3406,6 +3836,10 @@ entry:
; DARWIN-X64-LABEL: test31a:
; DARWIN-X64-NOT: callq ___stack_chk_fail
; DARWIN-X64: .cfi_endproc
+
+; MSVC-I386-LABEL: test31a:
+; MSVC-I386-NOT: calll @__security_check_cookie at 4
+; MSVC-I386: retl
%test = alloca i8*, align 8
%0 = alloca i8, i64 4
store i8* %0, i8** %test, align 8
@@ -3434,6 +3868,10 @@ entry:
; DARWIN-X64-LABEL: test31b:
; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
; DARWIN-X64: callq ___stack_chk_fail
+
+; MSVC-I386-LABEL: test31b:
+; MSVC-I386: movl ___security_cookie,
+; MSVC-I386: calll @__security_check_cookie at 4
%test = alloca i8*, align 8
%0 = alloca i8, i64 5
store i8* %0, i8** %test, align 8
More information about the llvm-commits
mailing list