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