1; RUN: llc -mtriple=i386-pc-windows-msvc < %s -o - | FileCheck -check-prefix=MSVC-X86 %s 2; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s -o - | FileCheck -check-prefix=MSVC-X64 %s 3 4; Make sure fastisel falls back and does something secure. 5; RUN: llc -mtriple=i686-pc-windows-msvc -O0 < %s -o - | FileCheck -check-prefix=MSVC-X86-O0 %s 6; RUN: llc -mtriple=x86_64-pc-windows-msvc -O0 < %s -o - | FileCheck -check-prefix=MSVC-X64-O0 %s 7 8@"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <ptr> [#uses=1] 9 10define void @test(ptr %a) nounwind ssp { 11entry: 12 %a_addr = alloca ptr ; <ptr> [#uses=2] 13 %buf = alloca [8 x i8] ; <ptr> [#uses=2] 14 store ptr %a, ptr %a_addr 15 %0 = load ptr, ptr %a_addr, align 4 ; <ptr> [#uses=1] 16 %1 = call ptr @strcpy(ptr %buf, ptr %0) nounwind ; <ptr> [#uses=0] 17 %2 = call i32 (ptr, ...) @printf(ptr @"\01LC", ptr %buf) nounwind ; <i32> [#uses=0] 18 br label %return 19 20return: ; preds = %entry 21 ret void 22} 23 24; MSVC-X86-LABEL: _test: 25; MSVC-X86: movl ___security_cookie, %[[REG1:[^ ]*]] 26; MSVC-X86: xorl %esp, %[[REG1]] 27; MSVC-X86: movl %[[REG1]], [[SLOT:[0-9]*]](%esp) 28; MSVC-X86: calll _strcpy 29; MSVC-X86: movl [[SLOT]](%esp), %ecx 30; MSVC-X86: xorl %esp, %ecx 31; MSVC-X86: calll @__security_check_cookie@4 32; MSVC-X86: retl 33 34; MSVC-X64-LABEL: test: 35; MSVC-X64: movq __security_cookie(%rip), %[[REG1:[^ ]*]] 36; MSVC-X64: xorq %rsp, %[[REG1]] 37; MSVC-X64: movq %[[REG1]], [[SLOT:[0-9]*]](%rsp) 38; MSVC-X64: callq strcpy 39; MSVC-X64: movq [[SLOT]](%rsp), %rcx 40; MSVC-X64: xorq %rsp, %rcx 41; MSVC-X64: callq __security_check_cookie 42; MSVC-X64: retq 43 44; MSVC-X86-O0-LABEL: _test: 45; MSVC-X86-O0: movl ___security_cookie, %[[REG1:[^ ]*]] 46; MSVC-X86-O0: xorl %esp, %[[REG1]] 47; MSVC-X86-O0: movl %[[REG1]], [[SLOT:[0-9]*]](%esp) 48; MSVC-X86-O0: calll _strcpy 49; MSVC-X86-O0: movl [[SLOT]](%esp), %ecx 50; MSVC-X86-O0: xorl %esp, %ecx 51; MSVC-X86-O0: calll @__security_check_cookie@4 52; MSVC-X86-O0: retl 53 54; MSVC-X64-O0-LABEL: test: 55; MSVC-X64-O0: movq __security_cookie(%rip), %[[REG1:[^ ]*]] 56; MSVC-X64-O0: xorq %rsp, %[[REG1]] 57; MSVC-X64-O0: movq %[[REG1]], [[SLOT:[0-9]*]](%rsp) 58; MSVC-X64-O0: callq strcpy 59; MSVC-X64-O0: movq [[SLOT]](%rsp), %rcx 60; MSVC-X64-O0: xorq %rsp, %rcx 61; MSVC-X64-O0: callq __security_check_cookie 62; MSVC-X64-O0: retq 63 64 65declare void @escape(ptr) 66 67define void @test_vla(i32 %n) nounwind ssp { 68 %vla = alloca i32, i32 %n 69 call void @escape(ptr %vla) 70 ret void 71} 72 73; MSVC-X86-LABEL: _test_vla: 74; MSVC-X86: pushl %ebp 75; MSVC-X86: movl %esp, %ebp 76; MSVC-X86: movl ___security_cookie, %[[REG1:[^ ]*]] 77; MSVC-X86: xorl %ebp, %[[REG1]] 78; MSVC-X86: movl %[[REG1]], [[SLOT:-[0-9]*]](%ebp) 79; MSVC-X86: calll __chkstk 80; MSVC-X86: pushl 81; MSVC-X86: calll _escape 82; MSVC-X86: movl [[SLOT]](%ebp), %ecx 83; MSVC-X86: xorl %ebp, %ecx 84; MSVC-X86: calll @__security_check_cookie@4 85; MSVC-X86: movl %ebp, %esp 86; MSVC-X86: popl %ebp 87; MSVC-X86: retl 88 89; MSVC-X64-LABEL: test_vla: 90; MSVC-X64: pushq %rbp 91; MSVC-X64: subq $16, %rsp 92; MSVC-X64: leaq 16(%rsp), %rbp 93; MSVC-X64: movq __security_cookie(%rip), %[[REG1:[^ ]*]] 94; MSVC-X64: xorq %rbp, %[[REG1]] 95; MSVC-X64: movq %[[REG1]], [[SLOT:-[0-9]*]](%rbp) 96; MSVC-X64: callq __chkstk 97; MSVC-X64: callq escape 98; MSVC-X64: movq [[SLOT]](%rbp), %rcx 99; MSVC-X64: xorq %rbp, %rcx 100; MSVC-X64: callq __security_check_cookie 101; MSVC-X64: retq 102 103 104; This case is interesting because we address local variables with RBX but XOR 105; the guard value with RBP. That's fine, either value will do, as long as they 106; are the same across the life of the frame. 107 108define void @test_vla_realign(i32 %n) nounwind ssp { 109 %realign = alloca i32, align 32 110 %vla = alloca i32, i32 %n 111 call void @escape(ptr %realign) 112 call void @escape(ptr %vla) 113 ret void 114} 115 116; MSVC-X86-LABEL: _test_vla_realign: 117; MSVC-X86: pushl %ebp 118; MSVC-X86: movl %esp, %ebp 119; MSVC-X86: pushl %esi 120; MSVC-X86: andl $-32, %esp 121; MSVC-X86: subl $32, %esp 122; MSVC-X86: movl %esp, %esi 123; MSVC-X86: movl ___security_cookie, %[[REG1:[^ ]*]] 124; MSVC-X86: xorl %ebp, %[[REG1]] 125; MSVC-X86: movl %[[REG1]], [[SLOT:[0-9]*]](%esi) 126; MSVC-X86: calll __chkstk 127; MSVC-X86: pushl 128; MSVC-X86: calll _escape 129; MSVC-X86: movl [[SLOT]](%esi), %ecx 130; MSVC-X86: xorl %ebp, %ecx 131; MSVC-X86: calll @__security_check_cookie@4 132; MSVC-X86: leal -8(%ebp), %esp 133; MSVC-X86: popl %esi 134; MSVC-X86: popl %ebp 135; MSVC-X86: retl 136 137; MSVC-X64-LABEL: test_vla_realign: 138; MSVC-X64: pushq %rbp 139; MSVC-X64: pushq %rbx 140; MSVC-X64: subq $32, %rsp 141; MSVC-X64: leaq 32(%rsp), %rbp 142; MSVC-X64: andq $-32, %rsp 143; MSVC-X64: movq %rsp, %rbx 144; MSVC-X64: movq __security_cookie(%rip), %[[REG1:[^ ]*]] 145; MSVC-X64: xorq %rbp, %[[REG1]] 146; MSVC-X64: movq %[[REG1]], [[SLOT:[0-9]*]](%rbx) 147; MSVC-X64: callq __chkstk 148; MSVC-X64: callq escape 149; MSVC-X64: movq [[SLOT]](%rbx), %rcx 150; MSVC-X64: xorq %rbp, %rcx 151; MSVC-X64: callq __security_check_cookie 152; MSVC-X64: retq 153 154 155declare ptr @strcpy(ptr, ptr) nounwind 156 157declare i32 @printf(ptr, ...) nounwind 158 159