1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s 3; RUN: llc < %s -mtriple=x86_64-pc-win32 -mattr=+sahf | FileCheck %s 4 5define i32 @f1(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) "frame-pointer"="all" { 6; CHECK-LABEL: f1: 7; CHECK: # %bb.0: 8; CHECK-NEXT: pushq %rbp 9; CHECK-NEXT: .seh_pushreg %rbp 10; CHECK-NEXT: movq %rsp, %rbp 11; CHECK-NEXT: .seh_setframe %rbp, 0 12; CHECK-NEXT: .seh_endprologue 13; CHECK-NEXT: movl 48(%rbp), %eax 14; CHECK-NEXT: popq %rbp 15; CHECK-NEXT: retq 16; CHECK-NEXT: .seh_endproc 17 ret i32 %p5 18} 19 20define void @f2(i32 %p, ...) "frame-pointer"="all" { 21; CHECK-LABEL: f2: 22; CHECK: # %bb.0: 23; CHECK-NEXT: pushq %rbp 24; CHECK-NEXT: .seh_pushreg %rbp 25; CHECK-NEXT: pushq %rax 26; CHECK-NEXT: .seh_stackalloc 8 27; CHECK-NEXT: movq %rsp, %rbp 28; CHECK-NEXT: .seh_setframe %rbp, 0 29; CHECK-NEXT: .seh_endprologue 30; CHECK-NEXT: movq %rdx, 32(%rbp) 31; CHECK-NEXT: movq %r8, 40(%rbp) 32; CHECK-NEXT: movq %r9, 48(%rbp) 33; CHECK-NEXT: leaq 32(%rbp), %rax 34; CHECK-NEXT: movq %rax, (%rbp) 35; CHECK-NEXT: addq $8, %rsp 36; CHECK-NEXT: popq %rbp 37; CHECK-NEXT: retq 38; CHECK-NEXT: .seh_endproc 39 %ap = alloca i8, align 8 40 call void @llvm.va_start(ptr %ap) 41 ret void 42} 43 44define ptr @f3() "frame-pointer"="all" { 45; CHECK-LABEL: f3: 46; CHECK: # %bb.0: 47; CHECK-NEXT: pushq %rbp 48; CHECK-NEXT: .seh_pushreg %rbp 49; CHECK-NEXT: movq %rsp, %rbp 50; CHECK-NEXT: .seh_setframe %rbp, 0 51; CHECK-NEXT: .seh_endprologue 52; CHECK-NEXT: movq 8(%rbp), %rax 53; CHECK-NEXT: popq %rbp 54; CHECK-NEXT: retq 55; CHECK-NEXT: .seh_endproc 56 %ra = call ptr @llvm.returnaddress(i32 0) 57 ret ptr %ra 58} 59 60define ptr @f4() "frame-pointer"="all" { 61; CHECK-LABEL: f4: 62; CHECK: # %bb.0: 63; CHECK-NEXT: pushq %rbp 64; CHECK-NEXT: .seh_pushreg %rbp 65; CHECK-NEXT: subq $304, %rsp # imm = 0x130 66; CHECK-NEXT: .seh_stackalloc 304 67; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rbp 68; CHECK-NEXT: .seh_setframe %rbp, 128 69; CHECK-NEXT: .seh_endprologue 70; CHECK-NEXT: movq 184(%rbp), %rax 71; CHECK-NEXT: addq $304, %rsp # imm = 0x130 72; CHECK-NEXT: popq %rbp 73; CHECK-NEXT: retq 74; CHECK-NEXT: .seh_endproc 75 alloca [300 x i8] 76 %ra = call ptr @llvm.returnaddress(i32 0) 77 ret ptr %ra 78} 79 80declare void @external(ptr) 81 82define void @f5() "frame-pointer"="all" { 83; CHECK-LABEL: f5: 84; CHECK: # %bb.0: 85; CHECK-NEXT: pushq %rbp 86; CHECK-NEXT: .seh_pushreg %rbp 87; CHECK-NEXT: subq $336, %rsp # imm = 0x150 88; CHECK-NEXT: .seh_stackalloc 336 89; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rbp 90; CHECK-NEXT: .seh_setframe %rbp, 128 91; CHECK-NEXT: .seh_endprologue 92; CHECK-NEXT: leaq -92(%rbp), %rcx 93; CHECK-NEXT: callq external 94; CHECK-NEXT: nop 95; CHECK-NEXT: addq $336, %rsp # imm = 0x150 96; CHECK-NEXT: popq %rbp 97; CHECK-NEXT: retq 98; CHECK-NEXT: .seh_endproc 99 %a = alloca [300 x i8] 100 call void @external(ptr %a) 101 ret void 102} 103 104define void @f6(i32 %p, ...) "frame-pointer"="all" { 105; CHECK-LABEL: f6: 106; CHECK: # %bb.0: 107; CHECK-NEXT: pushq %rbp 108; CHECK-NEXT: .seh_pushreg %rbp 109; CHECK-NEXT: subq $336, %rsp # imm = 0x150 110; CHECK-NEXT: .seh_stackalloc 336 111; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rbp 112; CHECK-NEXT: .seh_setframe %rbp, 128 113; CHECK-NEXT: .seh_endprologue 114; CHECK-NEXT: leaq -92(%rbp), %rcx 115; CHECK-NEXT: callq external 116; CHECK-NEXT: nop 117; CHECK-NEXT: addq $336, %rsp # imm = 0x150 118; CHECK-NEXT: popq %rbp 119; CHECK-NEXT: retq 120; CHECK-NEXT: .seh_endproc 121 %a = alloca [300 x i8] 122 call void @external(ptr %a) 123 ret void 124} 125 126define i32 @f7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "frame-pointer"="all" { 127; CHECK-LABEL: f7: 128; CHECK: # %bb.0: 129; CHECK-NEXT: pushq %rbp 130; CHECK-NEXT: .seh_pushreg %rbp 131; CHECK-NEXT: subq $304, %rsp # imm = 0x130 132; CHECK-NEXT: .seh_stackalloc 304 133; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rbp 134; CHECK-NEXT: .seh_setframe %rbp, 128 135; CHECK-NEXT: .seh_endprologue 136; CHECK-NEXT: andq $-64, %rsp 137; CHECK-NEXT: movl 224(%rbp), %eax 138; CHECK-NEXT: leaq 176(%rbp), %rsp 139; CHECK-NEXT: popq %rbp 140; CHECK-NEXT: retq 141; CHECK-NEXT: .seh_endproc 142 alloca [300 x i8], align 64 143 ret i32 %e 144} 145 146define i32 @f8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "frame-pointer"="all" { 147; CHECK-LABEL: f8: 148; CHECK: # %bb.0: 149; CHECK-NEXT: pushq %rbp 150; CHECK-NEXT: .seh_pushreg %rbp 151; CHECK-NEXT: pushq %rsi 152; CHECK-NEXT: .seh_pushreg %rsi 153; CHECK-NEXT: pushq %rbx 154; CHECK-NEXT: .seh_pushreg %rbx 155; CHECK-NEXT: subq $352, %rsp # imm = 0x160 156; CHECK-NEXT: .seh_stackalloc 352 157; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rbp 158; CHECK-NEXT: .seh_setframe %rbp, 128 159; CHECK-NEXT: .seh_endprologue 160; CHECK-NEXT: andq $-64, %rsp 161; CHECK-NEXT: movq %rsp, %rbx 162; CHECK-NEXT: movl 288(%rbp), %esi 163; CHECK-NEXT: movl %ecx, %eax 164; CHECK-NEXT: leaq 15(,%rax,4), %rax 165; CHECK-NEXT: andq $-16, %rax 166; CHECK-NEXT: callq __chkstk 167; CHECK-NEXT: subq %rax, %rsp 168; CHECK-NEXT: subq $32, %rsp 169; CHECK-NEXT: movq %rbx, %rcx 170; CHECK-NEXT: callq external 171; CHECK-NEXT: addq $32, %rsp 172; CHECK-NEXT: movl %esi, %eax 173; CHECK-NEXT: leaq 224(%rbp), %rsp 174; CHECK-NEXT: popq %rbx 175; CHECK-NEXT: popq %rsi 176; CHECK-NEXT: popq %rbp 177; CHECK-NEXT: retq 178; CHECK-NEXT: .seh_endproc 179 %alloca = alloca [300 x i8], align 64 180 alloca i32, i32 %a 181 call void @external(ptr %alloca) 182 ret i32 %e 183} 184 185define i64 @f9() { 186; CHECK-LABEL: f9: 187; CHECK: # %bb.0: # %entry 188; CHECK-NEXT: pushq %rbp 189; CHECK-NEXT: .seh_pushreg %rbp 190; CHECK-NEXT: movq %rsp, %rbp 191; CHECK-NEXT: .seh_setframe %rbp, 0 192; CHECK-NEXT: .seh_endprologue 193; CHECK-NEXT: pushfq 194; CHECK-NEXT: popq %rax 195; CHECK-NEXT: popq %rbp 196; CHECK-NEXT: retq 197; CHECK-NEXT: .seh_endproc 198entry: 199 %call = call i64 @llvm.x86.flags.read.u64() 200 ret i64 %call 201} 202 203declare i64 @dummy() 204 205define i64 @f10(ptr %foo, i64 %bar, i64 %baz) { 206; CHECK-LABEL: f10: 207; CHECK: # %bb.0: 208; CHECK-NEXT: pushq %rsi 209; CHECK-NEXT: .seh_pushreg %rsi 210; CHECK-NEXT: pushq %rbx 211; CHECK-NEXT: .seh_pushreg %rbx 212; CHECK-NEXT: subq $40, %rsp 213; CHECK-NEXT: .seh_stackalloc 40 214; CHECK-NEXT: .seh_endprologue 215; CHECK-NEXT: movq %rdx, %rsi 216; CHECK-NEXT: movq %rdx, %rax 217; CHECK-NEXT: lock cmpxchgq %r8, (%rcx) 218; CHECK-NEXT: sete %bl 219; CHECK-NEXT: callq dummy 220; CHECK-NEXT: testb %bl, %bl 221; CHECK-NEXT: cmoveq %rsi, %rax 222; CHECK-NEXT: addq $40, %rsp 223; CHECK-NEXT: popq %rbx 224; CHECK-NEXT: popq %rsi 225; CHECK-NEXT: retq 226; CHECK-NEXT: .seh_endproc 227 %cx = cmpxchg ptr %foo, i64 %bar, i64 %baz seq_cst seq_cst 228 %v = extractvalue { i64, i1 } %cx, 0 229 %p = extractvalue { i64, i1 } %cx, 1 230 %call = call i64 @dummy() 231 %sel = select i1 %p, i64 %call, i64 %bar 232 ret i64 %sel 233} 234 235define ptr @f11() "frame-pointer"="all" { 236; CHECK-LABEL: f11: 237; CHECK: # %bb.0: 238; CHECK-NEXT: pushq %rbp 239; CHECK-NEXT: .seh_pushreg %rbp 240; CHECK-NEXT: movq %rsp, %rbp 241; CHECK-NEXT: .seh_setframe %rbp, 0 242; CHECK-NEXT: .seh_endprologue 243; CHECK-NEXT: leaq 8(%rbp), %rax 244; CHECK-NEXT: popq %rbp 245; CHECK-NEXT: retq 246; CHECK-NEXT: .seh_endproc 247 %aora = call ptr @llvm.addressofreturnaddress() 248 ret ptr %aora 249} 250 251define ptr @f12() { 252; CHECK-LABEL: f12: 253; CHECK: # %bb.0: 254; CHECK-NEXT: movq %rsp, %rax 255; CHECK-NEXT: retq 256 %aora = call ptr @llvm.addressofreturnaddress() 257 ret ptr %aora 258} 259 260declare ptr @llvm.returnaddress(i32) nounwind readnone 261declare ptr @llvm.addressofreturnaddress() nounwind readnone 262declare i64 @llvm.x86.flags.read.u64() 263declare void @llvm.va_start(ptr) nounwind 264