1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+push2pop2 | FileCheck %s --check-prefix=CHECK 3; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+push2pop2,+ppx | FileCheck %s --check-prefix=PPX 4; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+push2pop2 -frame-pointer=all | FileCheck %s --check-prefix=FRAME 5 6define void @csr1() nounwind { 7; CHECK-LABEL: csr1: 8; CHECK: # %bb.0: # %entry 9; CHECK-NEXT: pushq %rbp 10; CHECK-NEXT: #APP 11; CHECK-NEXT: #NO_APP 12; CHECK-NEXT: popq %rbp 13; CHECK-NEXT: retq 14; 15; PPX-LABEL: csr1: 16; PPX: # %bb.0: # %entry 17; PPX-NEXT: pushp %rbp 18; PPX-NEXT: #APP 19; PPX-NEXT: #NO_APP 20; PPX-NEXT: popp %rbp 21; PPX-NEXT: retq 22; 23; FRAME-LABEL: csr1: 24; FRAME: # %bb.0: # %entry 25; FRAME-NEXT: pushq %rbp 26; FRAME-NEXT: movq %rsp, %rbp 27; FRAME-NEXT: pushq %rbp 28; FRAME-NEXT: pushq %rax 29; FRAME-NEXT: #APP 30; FRAME-NEXT: #NO_APP 31; FRAME-NEXT: popq %rax 32; FRAME-NEXT: popq %rbp 33; FRAME-NEXT: popq %rbp 34; FRAME-NEXT: retq 35entry: 36 tail call void asm sideeffect "", "~{rbp},~{dirflag},~{fpsr},~{flags}"() 37 ret void 38} 39 40define void @csr2() nounwind { 41; CHECK-LABEL: csr2: 42; CHECK: # %bb.0: # %entry 43; CHECK-NEXT: pushq %rbp 44; CHECK-NEXT: pushq %r15 45; CHECK-NEXT: #APP 46; CHECK-NEXT: #NO_APP 47; CHECK-NEXT: popq %r15 48; CHECK-NEXT: popq %rbp 49; CHECK-NEXT: retq 50; 51; PPX-LABEL: csr2: 52; PPX: # %bb.0: # %entry 53; PPX-NEXT: pushp %rbp 54; PPX-NEXT: pushp %r15 55; PPX-NEXT: #APP 56; PPX-NEXT: #NO_APP 57; PPX-NEXT: popp %r15 58; PPX-NEXT: popp %rbp 59; PPX-NEXT: retq 60; 61; FRAME-LABEL: csr2: 62; FRAME: # %bb.0: # %entry 63; FRAME-NEXT: pushq %rbp 64; FRAME-NEXT: movq %rsp, %rbp 65; FRAME-NEXT: pushq %r15 66; FRAME-NEXT: pushq %rbp 67; FRAME-NEXT: pushq %rax 68; FRAME-NEXT: #APP 69; FRAME-NEXT: #NO_APP 70; FRAME-NEXT: popq %rax 71; FRAME-NEXT: popq %rbp 72; FRAME-NEXT: popq %r15 73; FRAME-NEXT: popq %rbp 74; FRAME-NEXT: retq 75entry: 76 tail call void asm sideeffect "", "~{rbp},~{r15},~{dirflag},~{fpsr},~{flags}"() 77 ret void 78} 79 80define void @csr3() nounwind { 81; CHECK-LABEL: csr3: 82; CHECK: # %bb.0: # %entry 83; CHECK-NEXT: pushq %rbp 84; CHECK-NEXT: push2 %r14, %r15 85; CHECK-NEXT: #APP 86; CHECK-NEXT: #NO_APP 87; CHECK-NEXT: pop2 %r15, %r14 88; CHECK-NEXT: popq %rbp 89; CHECK-NEXT: retq 90; 91; PPX-LABEL: csr3: 92; PPX: # %bb.0: # %entry 93; PPX-NEXT: pushp %rbp 94; PPX-NEXT: push2p %r14, %r15 95; PPX-NEXT: #APP 96; PPX-NEXT: #NO_APP 97; PPX-NEXT: pop2p %r15, %r14 98; PPX-NEXT: popp %rbp 99; PPX-NEXT: retq 100; 101; FRAME-LABEL: csr3: 102; FRAME: # %bb.0: # %entry 103; FRAME-NEXT: pushq %rbp 104; FRAME-NEXT: movq %rsp, %rbp 105; FRAME-NEXT: push2 %r14, %r15 106; FRAME-NEXT: pushq %rbp 107; FRAME-NEXT: pushq %rax 108; FRAME-NEXT: #APP 109; FRAME-NEXT: #NO_APP 110; FRAME-NEXT: popq %rax 111; FRAME-NEXT: popq %rbp 112; FRAME-NEXT: pop2 %r15, %r14 113; FRAME-NEXT: popq %rbp 114; FRAME-NEXT: retq 115entry: 116 tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{dirflag},~{fpsr},~{flags}"() 117 ret void 118} 119 120define void @csr4() nounwind { 121; CHECK-LABEL: csr4: 122; CHECK: # %bb.0: # %entry 123; CHECK-NEXT: pushq %rax 124; CHECK-NEXT: push2 %r15, %rbp 125; CHECK-NEXT: push2 %r13, %r14 126; CHECK-NEXT: #APP 127; CHECK-NEXT: #NO_APP 128; CHECK-NEXT: pop2 %r14, %r13 129; CHECK-NEXT: pop2 %rbp, %r15 130; CHECK-NEXT: popq %rax 131; CHECK-NEXT: retq 132; 133; PPX-LABEL: csr4: 134; PPX: # %bb.0: # %entry 135; PPX-NEXT: pushq %rax 136; PPX-NEXT: push2p %r15, %rbp 137; PPX-NEXT: push2p %r13, %r14 138; PPX-NEXT: #APP 139; PPX-NEXT: #NO_APP 140; PPX-NEXT: pop2p %r14, %r13 141; PPX-NEXT: pop2p %rbp, %r15 142; PPX-NEXT: popq %rax 143; PPX-NEXT: retq 144; 145; FRAME-LABEL: csr4: 146; FRAME: # %bb.0: # %entry 147; FRAME-NEXT: pushq %rbp 148; FRAME-NEXT: movq %rsp, %rbp 149; FRAME-NEXT: push2 %r14, %r15 150; FRAME-NEXT: pushq %r13 151; FRAME-NEXT: pushq %rbp 152; FRAME-NEXT: pushq %rax 153; FRAME-NEXT: #APP 154; FRAME-NEXT: #NO_APP 155; FRAME-NEXT: popq %rax 156; FRAME-NEXT: popq %rbp 157; FRAME-NEXT: popq %r13 158; FRAME-NEXT: pop2 %r15, %r14 159; FRAME-NEXT: popq %rbp 160; FRAME-NEXT: retq 161entry: 162 tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{dirflag},~{fpsr},~{flags}"() 163 ret void 164} 165 166define void @csr5() nounwind { 167; CHECK-LABEL: csr5: 168; CHECK: # %bb.0: # %entry 169; CHECK-NEXT: pushq %rbp 170; CHECK-NEXT: push2 %r14, %r15 171; CHECK-NEXT: push2 %r12, %r13 172; CHECK-NEXT: #APP 173; CHECK-NEXT: #NO_APP 174; CHECK-NEXT: pop2 %r13, %r12 175; CHECK-NEXT: pop2 %r15, %r14 176; CHECK-NEXT: popq %rbp 177; CHECK-NEXT: retq 178; 179; PPX-LABEL: csr5: 180; PPX: # %bb.0: # %entry 181; PPX-NEXT: pushp %rbp 182; PPX-NEXT: push2p %r14, %r15 183; PPX-NEXT: push2p %r12, %r13 184; PPX-NEXT: #APP 185; PPX-NEXT: #NO_APP 186; PPX-NEXT: pop2p %r13, %r12 187; PPX-NEXT: pop2p %r15, %r14 188; PPX-NEXT: popp %rbp 189; PPX-NEXT: retq 190; 191; FRAME-LABEL: csr5: 192; FRAME: # %bb.0: # %entry 193; FRAME-NEXT: pushq %rbp 194; FRAME-NEXT: movq %rsp, %rbp 195; FRAME-NEXT: push2 %r14, %r15 196; FRAME-NEXT: push2 %r12, %r13 197; FRAME-NEXT: pushq %rbp 198; FRAME-NEXT: pushq %rax 199; FRAME-NEXT: #APP 200; FRAME-NEXT: #NO_APP 201; FRAME-NEXT: popq %rax 202; FRAME-NEXT: popq %rbp 203; FRAME-NEXT: pop2 %r13, %r12 204; FRAME-NEXT: pop2 %r15, %r14 205; FRAME-NEXT: popq %rbp 206; FRAME-NEXT: retq 207entry: 208 tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{r12},~{dirflag},~{fpsr},~{flags}"() 209 ret void 210} 211 212define void @csr6() nounwind { 213; CHECK-LABEL: csr6: 214; CHECK: # %bb.0: # %entry 215; CHECK-NEXT: pushq %rax 216; CHECK-NEXT: push2 %r15, %rbp 217; CHECK-NEXT: push2 %r13, %r14 218; CHECK-NEXT: push2 %rbx, %r12 219; CHECK-NEXT: #APP 220; CHECK-NEXT: #NO_APP 221; CHECK-NEXT: pop2 %r12, %rbx 222; CHECK-NEXT: pop2 %r14, %r13 223; CHECK-NEXT: pop2 %rbp, %r15 224; CHECK-NEXT: popq %rax 225; CHECK-NEXT: retq 226; 227; PPX-LABEL: csr6: 228; PPX: # %bb.0: # %entry 229; PPX-NEXT: pushq %rax 230; PPX-NEXT: push2p %r15, %rbp 231; PPX-NEXT: push2p %r13, %r14 232; PPX-NEXT: push2p %rbx, %r12 233; PPX-NEXT: #APP 234; PPX-NEXT: #NO_APP 235; PPX-NEXT: pop2p %r12, %rbx 236; PPX-NEXT: pop2p %r14, %r13 237; PPX-NEXT: pop2p %rbp, %r15 238; PPX-NEXT: popq %rax 239; PPX-NEXT: retq 240; 241; FRAME-LABEL: csr6: 242; FRAME: # %bb.0: # %entry 243; FRAME-NEXT: pushq %rbp 244; FRAME-NEXT: movq %rsp, %rbp 245; FRAME-NEXT: push2 %r14, %r15 246; FRAME-NEXT: push2 %r12, %r13 247; FRAME-NEXT: pushq %rbx 248; FRAME-NEXT: pushq %rbp 249; FRAME-NEXT: pushq %rax 250; FRAME-NEXT: #APP 251; FRAME-NEXT: #NO_APP 252; FRAME-NEXT: popq %rax 253; FRAME-NEXT: popq %rbp 254; FRAME-NEXT: popq %rbx 255; FRAME-NEXT: pop2 %r13, %r12 256; FRAME-NEXT: pop2 %r15, %r14 257; FRAME-NEXT: popq %rbp 258; FRAME-NEXT: retq 259entry: 260 tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{r12},~{rbx},~{dirflag},~{fpsr},~{flags}"() 261 ret void 262} 263 264declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) 265 266define void @lea_in_epilog(i1 %arg, ptr %arg1, ptr %arg2, i64 %arg3, i64 %arg4, i64 %arg5, i64 %arg6, i64 %arg7, i64 %arg8, i64 %arg9, i64 %arg10) nounwind { 267; CHECK-LABEL: lea_in_epilog: 268; CHECK: # %bb.0: # %bb 269; CHECK-NEXT: testb $1, %dil 270; CHECK-NEXT: je .LBB6_5 271; CHECK-NEXT: # %bb.1: # %bb13 272; CHECK-NEXT: pushq %rax 273; CHECK-NEXT: push2 %r15, %rbp 274; CHECK-NEXT: push2 %r13, %r14 275; CHECK-NEXT: push2 %rbx, %r12 276; CHECK-NEXT: subq $16, %rsp 277; CHECK-NEXT: movq %r9, %r14 278; CHECK-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill 279; CHECK-NEXT: addq {{[0-9]+}}(%rsp), %r14 280; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r13 281; CHECK-NEXT: addq %r14, %r13 282; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r15 283; CHECK-NEXT: addq %r14, %r15 284; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rbx 285; CHECK-NEXT: addq %r14, %rbx 286; CHECK-NEXT: xorl %ebp, %ebp 287; CHECK-NEXT: xorl %r12d, %r12d 288; CHECK-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill 289; CHECK-NEXT: .p2align 4 290; CHECK-NEXT: .LBB6_2: # %bb15 291; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 292; CHECK-NEXT: incq %r12 293; CHECK-NEXT: movl $432, %edx # imm = 0x1B0 294; CHECK-NEXT: xorl %edi, %edi 295; CHECK-NEXT: movq %r15, %rsi 296; CHECK-NEXT: callq memcpy@PLT 297; CHECK-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload 298; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax 299; CHECK-NEXT: addq %rax, %r13 300; CHECK-NEXT: addq %rax, %r15 301; CHECK-NEXT: addq %rax, %rbx 302; CHECK-NEXT: addq %rax, %r14 303; CHECK-NEXT: addq $8, %rbp 304; CHECK-NEXT: testb $1, %dil 305; CHECK-NEXT: je .LBB6_2 306; CHECK-NEXT: # %bb.3: # %bb11 307; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload 308; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsp 309; CHECK-NEXT: pop2 %r12, %rbx 310; CHECK-NEXT: pop2 %r14, %r13 311; CHECK-NEXT: pop2 %rbp, %r15 312; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsp 313; CHECK-NEXT: jne .LBB6_5 314; CHECK-NEXT: # %bb.4: # %bb12 315; CHECK-NEXT: movq $0, (%rax) 316; CHECK-NEXT: .LBB6_5: # %bb14 317; CHECK-NEXT: retq 318; 319; PPX-LABEL: lea_in_epilog: 320; PPX: # %bb.0: # %bb 321; PPX-NEXT: testb $1, %dil 322; PPX-NEXT: je .LBB6_5 323; PPX-NEXT: # %bb.1: # %bb13 324; PPX-NEXT: pushq %rax 325; PPX-NEXT: push2p %r15, %rbp 326; PPX-NEXT: push2p %r13, %r14 327; PPX-NEXT: push2p %rbx, %r12 328; PPX-NEXT: subq $16, %rsp 329; PPX-NEXT: movq %r9, %r14 330; PPX-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill 331; PPX-NEXT: addq {{[0-9]+}}(%rsp), %r14 332; PPX-NEXT: movq {{[0-9]+}}(%rsp), %r13 333; PPX-NEXT: addq %r14, %r13 334; PPX-NEXT: movq {{[0-9]+}}(%rsp), %r15 335; PPX-NEXT: addq %r14, %r15 336; PPX-NEXT: movq {{[0-9]+}}(%rsp), %rbx 337; PPX-NEXT: addq %r14, %rbx 338; PPX-NEXT: xorl %ebp, %ebp 339; PPX-NEXT: xorl %r12d, %r12d 340; PPX-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill 341; PPX-NEXT: .p2align 4 342; PPX-NEXT: .LBB6_2: # %bb15 343; PPX-NEXT: # =>This Inner Loop Header: Depth=1 344; PPX-NEXT: incq %r12 345; PPX-NEXT: movl $432, %edx # imm = 0x1B0 346; PPX-NEXT: xorl %edi, %edi 347; PPX-NEXT: movq %r15, %rsi 348; PPX-NEXT: callq memcpy@PLT 349; PPX-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload 350; PPX-NEXT: movq {{[0-9]+}}(%rsp), %rax 351; PPX-NEXT: addq %rax, %r13 352; PPX-NEXT: addq %rax, %r15 353; PPX-NEXT: addq %rax, %rbx 354; PPX-NEXT: addq %rax, %r14 355; PPX-NEXT: addq $8, %rbp 356; PPX-NEXT: testb $1, %dil 357; PPX-NEXT: je .LBB6_2 358; PPX-NEXT: # %bb.3: # %bb11 359; PPX-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload 360; PPX-NEXT: leaq {{[0-9]+}}(%rsp), %rsp 361; PPX-NEXT: pop2p %r12, %rbx 362; PPX-NEXT: pop2p %r14, %r13 363; PPX-NEXT: pop2p %rbp, %r15 364; PPX-NEXT: leaq {{[0-9]+}}(%rsp), %rsp 365; PPX-NEXT: jne .LBB6_5 366; PPX-NEXT: # %bb.4: # %bb12 367; PPX-NEXT: movq $0, (%rax) 368; PPX-NEXT: .LBB6_5: # %bb14 369; PPX-NEXT: retq 370; 371; FRAME-LABEL: lea_in_epilog: 372; FRAME: # %bb.0: # %bb 373; FRAME-NEXT: testb $1, %dil 374; FRAME-NEXT: je .LBB6_5 375; FRAME-NEXT: # %bb.1: # %bb13 376; FRAME-NEXT: pushq %rbp 377; FRAME-NEXT: movq %rsp, %rbp 378; FRAME-NEXT: push2 %r14, %r15 379; FRAME-NEXT: push2 %r12, %r13 380; FRAME-NEXT: pushq %rbx 381; FRAME-NEXT: subq $24, %rsp 382; FRAME-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill 383; FRAME-NEXT: addq 16(%rbp), %r9 384; FRAME-NEXT: movq 48(%rbp), %rbx 385; FRAME-NEXT: addq %r9, %rbx 386; FRAME-NEXT: movq 40(%rbp), %r12 387; FRAME-NEXT: addq %r9, %r12 388; FRAME-NEXT: movq 32(%rbp), %r15 389; FRAME-NEXT: addq %r9, %r15 390; FRAME-NEXT: xorl %r13d, %r13d 391; FRAME-NEXT: xorl %r14d, %r14d 392; FRAME-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill 393; FRAME-NEXT: .p2align 4 394; FRAME-NEXT: .LBB6_2: # %bb15 395; FRAME-NEXT: # =>This Inner Loop Header: Depth=1 396; FRAME-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill 397; FRAME-NEXT: incq %r14 398; FRAME-NEXT: movl $432, %edx # imm = 0x1B0 399; FRAME-NEXT: xorl %edi, %edi 400; FRAME-NEXT: movq %r12, %rsi 401; FRAME-NEXT: callq memcpy@PLT 402; FRAME-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload 403; FRAME-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Reload 404; FRAME-NEXT: movq 16(%rbp), %rax 405; FRAME-NEXT: addq %rax, %rbx 406; FRAME-NEXT: addq %rax, %r12 407; FRAME-NEXT: addq %rax, %r15 408; FRAME-NEXT: addq %rax, %r9 409; FRAME-NEXT: addq $8, %r13 410; FRAME-NEXT: testb $1, %dil 411; FRAME-NEXT: je .LBB6_2 412; FRAME-NEXT: # %bb.3: # %bb11 413; FRAME-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload 414; FRAME-NEXT: leaq {{[0-9]+}}(%rsp), %rsp 415; FRAME-NEXT: popq %rbx 416; FRAME-NEXT: pop2 %r13, %r12 417; FRAME-NEXT: pop2 %r15, %r14 418; FRAME-NEXT: popq %rbp 419; FRAME-NEXT: jne .LBB6_5 420; FRAME-NEXT: # %bb.4: # %bb12 421; FRAME-NEXT: movq $0, (%rax) 422; FRAME-NEXT: .LBB6_5: # %bb14 423; FRAME-NEXT: retq 424bb: 425 br i1 %arg, label %bb13, label %bb14 426 427bb11: 428 br i1 %arg, label %bb14, label %bb12 429 430bb12: 431 store double 0.000000e+00, ptr %arg1, align 8 432 br label %bb14 433 434bb13: 435 %getelementptr = getelementptr i8, ptr null, i64 %arg5 436 br label %bb15 437 438bb14: 439 ret void 440 441bb15: 442 %phi = phi i64 [ 0, %bb13 ], [ %add, %bb15 ] 443 %getelementptr16 = getelementptr double, ptr null, i64 %phi 444 %add = add i64 %phi, 1 445 %mul = mul i64 %arg6, %add 446 %getelementptr17 = getelementptr i8, ptr %getelementptr, i64 %mul 447 call void @llvm.memcpy.p0.p0.i64(ptr %getelementptr16, ptr %getelementptr17, i64 0, i1 false) 448 %getelementptr18 = getelementptr i8, ptr %getelementptr17, i64 %arg7 449 %getelementptr19 = getelementptr i8, ptr %getelementptr17, i64 %arg8 450 call void @llvm.memcpy.p0.p0.i64(ptr null, ptr %getelementptr19, i64 0, i1 false) 451 %getelementptr20 = getelementptr i8, ptr %getelementptr17, i64 %arg9 452 call void @llvm.memcpy.p0.p0.i64(ptr null, ptr %getelementptr20, i64 432, i1 false) 453 %getelementptr21 = getelementptr i8, ptr %getelementptr17, i64 %arg10 454 call void @llvm.memcpy.p0.p0.i64(ptr null, ptr %getelementptr21, i64 0, i1 false) 455 br i1 %arg, label %bb11, label %bb15 456} 457