Index: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp @@ -2098,7 +2098,8 @@ void X86TargetLowering::insertSSPDeclarations(Module &M) const { // MSVC CRT provides functionalities for stack protection. - if (Subtarget.getTargetTriple().isOSMSVCRT()) { + if (Subtarget.getTargetTriple().isWindowsMSVCEnvironment() || + Subtarget.getTargetTriple().isWindowsItaniumEnvironment()) { // MSVC CRT has a global variable holding security cookie. M.getOrInsertGlobal("__security_cookie", Type::getInt8PtrTy(M.getContext())); @@ -2120,15 +2121,19 @@ Value *X86TargetLowering::getSDagStackGuard(const Module &M) const { // MSVC CRT has a global variable holding security cookie. - if (Subtarget.getTargetTriple().isOSMSVCRT()) + if (Subtarget.getTargetTriple().isWindowsMSVCEnvironment() || + Subtarget.getTargetTriple().isWindowsItaniumEnvironment()) { 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()) + if (Subtarget.getTargetTriple().isWindowsMSVCEnvironment() || + Subtarget.getTargetTriple().isWindowsItaniumEnvironment()) { return M.getFunction("__security_check_cookie"); + } return TargetLowering::getSSPStackGuardCheck(M); } Index: llvm/trunk/test/CodeGen/X86/stack-protector.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/stack-protector.ll +++ llvm/trunk/test/CodeGen/X86/stack-protector.ll @@ -4,6 +4,7 @@ ; 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 +; RUN: llc -mtriple=x86_64-w64-mingw32 < %s -o - | FileCheck --check-prefix=MINGW-X64 %s %struct.foo = type { [16 x i8] } %struct.foo.0 = type { [4 x i8] } @@ -45,6 +46,11 @@ ; MSVC-I386-LABEL: test1a: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test1a: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %a.addr = alloca i8*, align 8 %buf = alloca [16 x i8], align 16 store i8* %a, i8** %a.addr, align 8 @@ -85,6 +91,11 @@ ; MSVC-I386-LABEL: test1b: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test1b: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %a.addr = alloca i8*, align 8 %buf = alloca [16 x i8], align 16 store i8* %a, i8** %a.addr, align 8 @@ -121,6 +132,11 @@ ; MSVC-I386-LABEL: test1c: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test1c: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %a.addr = alloca i8*, align 8 %buf = alloca [16 x i8], align 16 store i8* %a, i8** %a.addr, align 8 @@ -157,6 +173,11 @@ ; MSVC-I386-LABEL: test1d: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test1d: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %a.addr = alloca i8*, align 8 %buf = alloca [16 x i8], align 16 store i8* %a, i8** %a.addr, align 8 @@ -192,6 +213,11 @@ ; MSVC-I386-LABEL: test2a: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test2a: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %a.addr = alloca i8*, align 8 %b = alloca %struct.foo, align 1 store i8* %a, i8** %a.addr, align 8 @@ -226,6 +252,11 @@ ; DARWIN-X64-LABEL: test2b: ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard ; DARWIN-X64: callq ___stack_chk_fail + +; MINGW-X64-LABEL: test2b: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %a.addr = alloca i8*, align 8 %b = alloca %struct.foo, align 1 store i8* %a, i8** %a.addr, align 8 @@ -264,6 +295,11 @@ ; MSVC-I386-LABEL: test2c: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test2c: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %a.addr = alloca i8*, align 8 %b = alloca %struct.foo, align 1 store i8* %a, i8** %a.addr, align 8 @@ -302,6 +338,11 @@ ; MSVC-I386-LABEL: test2d: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test2d: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %a.addr = alloca i8*, align 8 %b = alloca %struct.foo, align 1 store i8* %a, i8** %a.addr, align 8 @@ -339,6 +380,11 @@ ; MSVC-I386-LABEL: test3a: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test3a: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %a.addr = alloca i8*, align 8 %buf = alloca [4 x i8], align 1 store i8* %a, i8** %a.addr, align 8 @@ -375,6 +421,11 @@ ; MSVC-I386-LABEL: test3b: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test3b: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %a.addr = alloca i8*, align 8 %buf = alloca [4 x i8], align 1 store i8* %a, i8** %a.addr, align 8 @@ -411,6 +462,11 @@ ; MSVC-I386-LABEL: test3c: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test3c: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %a.addr = alloca i8*, align 8 %buf = alloca [4 x i8], align 1 store i8* %a, i8** %a.addr, align 8 @@ -447,6 +503,11 @@ ; MSVC-I386-LABEL: test3d: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test3d: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %a.addr = alloca i8*, align 8 %buf = alloca [4 x i8], align 1 store i8* %a, i8** %a.addr, align 8 @@ -482,6 +543,11 @@ ; MSVC-I386-LABEL: test4a: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test4a: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %a.addr = alloca i8*, align 8 %b = alloca %struct.foo.0, align 1 store i8* %a, i8** %a.addr, align 8 @@ -520,6 +586,11 @@ ; MSVC-I386-LABEL: test4b: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test4b: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %a.addr = alloca i8*, align 8 %b = alloca %struct.foo.0, align 1 store i8* %a, i8** %a.addr, align 8 @@ -558,6 +629,11 @@ ; MSVC-I386-LABEL: test4c: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test4c: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %a.addr = alloca i8*, align 8 %b = alloca %struct.foo.0, align 1 store i8* %a, i8** %a.addr, align 8 @@ -596,6 +672,11 @@ ; MSVC-I386-LABEL: test4d: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test4d: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %a.addr = alloca i8*, align 8 %b = alloca %struct.foo.0, align 1 store i8* %a, i8** %a.addr, align 8 @@ -633,6 +714,11 @@ ; MSVC-I386-LABEL: test5a: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test5a: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %a.addr = alloca i8*, align 8 store i8* %a, i8** %a.addr, align 8 %0 = load i8*, i8** %a.addr, align 8 @@ -665,6 +751,11 @@ ; MSVC-I386-LABEL: test5b: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test5b: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %a.addr = alloca i8*, align 8 store i8* %a, i8** %a.addr, align 8 %0 = load i8*, i8** %a.addr, align 8 @@ -697,6 +788,11 @@ ; MSVC-I386-LABEL: test5c: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test5c: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %a.addr = alloca i8*, align 8 store i8* %a, i8** %a.addr, align 8 %0 = load i8*, i8** %a.addr, align 8 @@ -729,6 +825,11 @@ ; MSVC-I386-LABEL: test5d: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test5d: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %a.addr = alloca i8*, align 8 store i8* %a, i8** %a.addr, align 8 %0 = load i8*, i8** %a.addr, align 8 @@ -760,6 +861,11 @@ ; MSVC-I386-LABEL: test6a: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test6a: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %retval = alloca i32, align 4 %a = alloca i32, align 4 %j = alloca i32*, align 8 @@ -793,10 +899,14 @@ ; DARWIN-X64-NOT: callq ___stack_chk_fail ; DARWIN-X64: .cfi_endproc - ; MSVC-I386-LABEL: test6b: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test6b: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %retval = alloca i32, align 4 %a = alloca i32, align 4 %j = alloca i32*, align 8 @@ -833,6 +943,11 @@ ; MSVC-I386-LABEL: test6c: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test6c: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %retval = alloca i32, align 4 %a = alloca i32, align 4 %j = alloca i32*, align 8 @@ -869,6 +984,11 @@ ; MSVC-I386-LABEL: test6d: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test6d: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %retval = alloca i32, align 4 %a = alloca i32, align 4 %j = alloca i32*, align 8 @@ -904,6 +1024,11 @@ ; MSVC-I386-LABEL: test7a: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test7a: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %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) @@ -935,6 +1060,11 @@ ; MSVC-I386-LABEL: test7b: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test7b: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %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) @@ -966,6 +1096,11 @@ ; MSVC-I386-LABEL: test7c: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test7c: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: .seh_endproc + %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) @@ -997,6 +1132,11 @@ ; MSVC-I386-LABEL: test7d: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test7d: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %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) @@ -1027,6 +1167,11 @@ ; MSVC-I386-LABEL: test8a: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test8a: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %b = alloca i32, align 4 call void @funcall(i32* %b) ret void @@ -1057,6 +1202,11 @@ ; MSVC-I386-LABEL: test8b: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test8b: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %b = alloca i32, align 4 call void @funcall(i32* %b) ret void @@ -1087,6 +1237,11 @@ ; MSVC-I386-LABEL: test8c: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test8c: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %b = alloca i32, align 4 call void @funcall(i32* %b) ret void @@ -1117,6 +1272,11 @@ ; MSVC-I386-LABEL: test8d: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test8d: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %b = alloca i32, align 4 call void @funcall(i32* %b) ret void @@ -2687,6 +2847,11 @@ ; MSVC-I386-LABEL: test19d: ; MSVC-I386: movl ___security_cookie, ; MSVC-I386: calll @__security_check_cookie@4 + +; MINGW-X64-LABEL: test19d: +; MINGW-X64: mov{{l|q}} __stack_chk_guard +; MINGW-X64: callq __stack_chk_fail + %c = alloca %struct.pair, align 4 %exn.slot = alloca i8* %ehselector.slot = alloca i32 @@ -3455,6 +3620,11 @@ ; MSVC-I386-LABEL: test25b: ; MSVC-I386-NOT: calll @__security_check_cookie@4 ; MSVC-I386: retl + +; MINGW-X64-LABEL: test25b: +; MINGW-X64-NOT: callq __stack_chk_fail +; MINGW-X64: .seh_endproc + %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 Index: llvm/trunk/test/CodeGen/X86/win32-ssp.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/win32-ssp.ll +++ llvm/trunk/test/CodeGen/X86/win32-ssp.ll @@ -0,0 +1,29 @@ +; RUN: llc -mtriple=x86_64-w64-mingw32 < %s -o - | FileCheck --check-prefix=MINGW %s +; RUN: llc -mtriple=x86_64-pc-windows-itanium < %s -o - | FileCheck --check-prefix=MSVC %s +; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s -o - | FileCheck --check-prefix=MSVC %s + +declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) +declare dso_local void @other(i8*) +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) + +define dso_local void @func() sspstrong { +entry: +; MINGW-LABEL: func: +; MINGW: mov{{l|q}} __stack_chk_guard +; MINGW: callq other +; MINGW: mov{{l|q}} __stack_chk_guard +; MINGW: callq __stack_chk_fail +; MINGW: .seh_endproc + +; MSVC-LABEL: func: +; MSVC: mov{{l|q}} __security_cookie +; MSVC: callq other +; MSVC: callq __security_check_cookie +; MSVC: .seh_endproc + + %c = alloca i8, align 1 + call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %c) + call void @other(i8* nonnull %c) + call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull %c) + ret void +}