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(i8* %ap) 41 ret void 42} 43 44define i8* @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 i8* @llvm.returnaddress(i32 0) 57 ret i8* %ra 58} 59 60define i8* @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 i8* @llvm.returnaddress(i32 0) 77 ret i8* %ra 78} 79 80declare void @external(i8*) 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 %gep = getelementptr [300 x i8], [300 x i8]* %a, i32 0, i32 0 101 call void @external(i8* %gep) 102 ret void 103} 104 105define void @f6(i32 %p, ...) "frame-pointer"="all" { 106; CHECK-LABEL: f6: 107; CHECK: # %bb.0: 108; CHECK-NEXT: pushq %rbp 109; CHECK-NEXT: .seh_pushreg %rbp 110; CHECK-NEXT: subq $336, %rsp # imm = 0x150 111; CHECK-NEXT: .seh_stackalloc 336 112; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rbp 113; CHECK-NEXT: .seh_setframe %rbp, 128 114; CHECK-NEXT: .seh_endprologue 115; CHECK-NEXT: leaq -92(%rbp), %rcx 116; CHECK-NEXT: callq external 117; CHECK-NEXT: nop 118; CHECK-NEXT: addq $336, %rsp # imm = 0x150 119; CHECK-NEXT: popq %rbp 120; CHECK-NEXT: retq 121; CHECK-NEXT: .seh_endproc 122 %a = alloca [300 x i8] 123 %gep = getelementptr [300 x i8], [300 x i8]* %a, i32 0, i32 0 124 call void @external(i8* %gep) 125 ret void 126} 127 128define i32 @f7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "frame-pointer"="all" { 129; CHECK-LABEL: f7: 130; CHECK: # %bb.0: 131; CHECK-NEXT: pushq %rbp 132; CHECK-NEXT: .seh_pushreg %rbp 133; CHECK-NEXT: subq $304, %rsp # imm = 0x130 134; CHECK-NEXT: .seh_stackalloc 304 135; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rbp 136; CHECK-NEXT: .seh_setframe %rbp, 128 137; CHECK-NEXT: .seh_endprologue 138; CHECK-NEXT: andq $-64, %rsp 139; CHECK-NEXT: movl 224(%rbp), %eax 140; CHECK-NEXT: leaq 176(%rbp), %rsp 141; CHECK-NEXT: popq %rbp 142; CHECK-NEXT: retq 143; CHECK-NEXT: .seh_endproc 144 alloca [300 x i8], align 64 145 ret i32 %e 146} 147 148define i32 @f8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "frame-pointer"="all" { 149; CHECK-LABEL: f8: 150; CHECK: # %bb.0: 151; CHECK-NEXT: pushq %rbp 152; CHECK-NEXT: .seh_pushreg %rbp 153; CHECK-NEXT: pushq %rsi 154; CHECK-NEXT: .seh_pushreg %rsi 155; CHECK-NEXT: pushq %rbx 156; CHECK-NEXT: .seh_pushreg %rbx 157; CHECK-NEXT: subq $352, %rsp # imm = 0x160 158; CHECK-NEXT: .seh_stackalloc 352 159; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rbp 160; CHECK-NEXT: .seh_setframe %rbp, 128 161; CHECK-NEXT: .seh_endprologue 162; CHECK-NEXT: andq $-64, %rsp 163; CHECK-NEXT: movq %rsp, %rbx 164; CHECK-NEXT: movl 288(%rbp), %esi 165; CHECK-NEXT: movl %ecx, %eax 166; CHECK-NEXT: leaq 15(,%rax,4), %rax 167; CHECK-NEXT: andq $-16, %rax 168; CHECK-NEXT: callq __chkstk 169; CHECK-NEXT: subq %rax, %rsp 170; CHECK-NEXT: subq $32, %rsp 171; CHECK-NEXT: movq %rbx, %rcx 172; CHECK-NEXT: callq external 173; CHECK-NEXT: addq $32, %rsp 174; CHECK-NEXT: movl %esi, %eax 175; CHECK-NEXT: leaq 224(%rbp), %rsp 176; CHECK-NEXT: popq %rbx 177; CHECK-NEXT: popq %rsi 178; CHECK-NEXT: popq %rbp 179; CHECK-NEXT: retq 180; CHECK-NEXT: .seh_endproc 181 %alloca = alloca [300 x i8], align 64 182 alloca i32, i32 %a 183 %gep = getelementptr [300 x i8], [300 x i8]* %alloca, i32 0, i32 0 184 call void @external(i8* %gep) 185 ret i32 %e 186} 187 188define i64 @f9() { 189; CHECK-LABEL: f9: 190; CHECK: # %bb.0: # %entry 191; CHECK-NEXT: pushq %rbp 192; CHECK-NEXT: .seh_pushreg %rbp 193; CHECK-NEXT: movq %rsp, %rbp 194; CHECK-NEXT: .seh_setframe %rbp, 0 195; CHECK-NEXT: .seh_endprologue 196; CHECK-NEXT: pushfq 197; CHECK-NEXT: popq %rax 198; CHECK-NEXT: popq %rbp 199; CHECK-NEXT: retq 200; CHECK-NEXT: .seh_endproc 201entry: 202 %call = call i64 @llvm.x86.flags.read.u64() 203 ret i64 %call 204} 205 206declare i64 @dummy() 207 208define i64 @f10(i64* %foo, i64 %bar, i64 %baz) { 209; CHECK-LABEL: f10: 210; CHECK: # %bb.0: 211; CHECK-NEXT: pushq %rsi 212; CHECK-NEXT: .seh_pushreg %rsi 213; CHECK-NEXT: pushq %rbx 214; CHECK-NEXT: .seh_pushreg %rbx 215; CHECK-NEXT: subq $40, %rsp 216; CHECK-NEXT: .seh_stackalloc 40 217; CHECK-NEXT: .seh_endprologue 218; CHECK-NEXT: movq %rdx, %rsi 219; CHECK-NEXT: movq %rdx, %rax 220; CHECK-NEXT: lock cmpxchgq %r8, (%rcx) 221; CHECK-NEXT: sete %bl 222; CHECK-NEXT: callq dummy 223; CHECK-NEXT: testb %bl, %bl 224; CHECK-NEXT: cmoveq %rsi, %rax 225; CHECK-NEXT: addq $40, %rsp 226; CHECK-NEXT: popq %rbx 227; CHECK-NEXT: popq %rsi 228; CHECK-NEXT: retq 229; CHECK-NEXT: .seh_endproc 230 %cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst 231 %v = extractvalue { i64, i1 } %cx, 0 232 %p = extractvalue { i64, i1 } %cx, 1 233 %call = call i64 @dummy() 234 %sel = select i1 %p, i64 %call, i64 %bar 235 ret i64 %sel 236} 237 238define i8* @f11() "frame-pointer"="all" { 239; CHECK-LABEL: f11: 240; CHECK: # %bb.0: 241; CHECK-NEXT: pushq %rbp 242; CHECK-NEXT: .seh_pushreg %rbp 243; CHECK-NEXT: movq %rsp, %rbp 244; CHECK-NEXT: .seh_setframe %rbp, 0 245; CHECK-NEXT: .seh_endprologue 246; CHECK-NEXT: leaq 8(%rbp), %rax 247; CHECK-NEXT: popq %rbp 248; CHECK-NEXT: retq 249; CHECK-NEXT: .seh_endproc 250 %aora = call i8* @llvm.addressofreturnaddress() 251 ret i8* %aora 252} 253 254define i8* @f12() { 255; CHECK-LABEL: f12: 256; CHECK: # %bb.0: 257; CHECK-NEXT: movq %rsp, %rax 258; CHECK-NEXT: retq 259 %aora = call i8* @llvm.addressofreturnaddress() 260 ret i8* %aora 261} 262 263declare i8* @llvm.returnaddress(i32) nounwind readnone 264declare i8* @llvm.addressofreturnaddress() nounwind readnone 265declare i64 @llvm.x86.flags.read.u64() 266declare void @llvm.va_start(i8*) nounwind 267