1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-- | FileCheck %s --check-prefixes=ALL,i686 3; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s -check-prefixes=ALL,x86_64 4 5 6%0 = type { x86_fp80, x86_fp80 } 7 8; This is basically this code on x86-64: 9; _Complex long double test() { return 1.0; } 10define %0 @test() { 11; ALL-LABEL: test: 12; ALL: # %bb.0: 13; ALL-NEXT: fldz 14; ALL-NEXT: fld1 15; ALL-NEXT: ret{{[l|q]}} 16 %A = fpext double 1.0 to x86_fp80 17 %B = fpext double 0.0 to x86_fp80 18 %mrv = insertvalue %0 undef, x86_fp80 %A, 0 19 %mrv1 = insertvalue %0 %mrv, x86_fp80 %B, 1 20 ret %0 %mrv1 21} 22 23 24;_test2: 25; fld1 26; fld %st(0) 27; ret 28define %0 @test2() { 29; ALL-LABEL: test2: 30; ALL: # %bb.0: 31; ALL-NEXT: fld1 32; ALL-NEXT: fld %st(0) 33; ALL-NEXT: ret{{[l|q]}} 34 %A = fpext double 1.0 to x86_fp80 35 %mrv = insertvalue %0 undef, x86_fp80 %A, 0 36 %mrv1 = insertvalue %0 %mrv, x86_fp80 %A, 1 37 ret %0 %mrv1 38} 39 40; Uses both values. 41define void @call1(ptr%P1, ptr%P2) { 42; i686-LABEL: call1: 43; i686: # %bb.0: 44; i686-NEXT: pushl %edi 45; i686-NEXT: .cfi_def_cfa_offset 8 46; i686-NEXT: pushl %esi 47; i686-NEXT: .cfi_def_cfa_offset 12 48; i686-NEXT: .cfi_offset %esi, -12 49; i686-NEXT: .cfi_offset %edi, -8 50; i686-NEXT: movl {{[0-9]+}}(%esp), %esi 51; i686-NEXT: movl {{[0-9]+}}(%esp), %edi 52; i686-NEXT: calll test@PLT 53; i686-NEXT: fstpt (%edi) 54; i686-NEXT: fstpt (%esi) 55; i686-NEXT: popl %esi 56; i686-NEXT: .cfi_def_cfa_offset 8 57; i686-NEXT: popl %edi 58; i686-NEXT: .cfi_def_cfa_offset 4 59; i686-NEXT: retl 60; 61; x86_64-LABEL: call1: 62; x86_64: # %bb.0: 63; x86_64-NEXT: pushq %r14 64; x86_64-NEXT: .cfi_def_cfa_offset 16 65; x86_64-NEXT: pushq %rbx 66; x86_64-NEXT: .cfi_def_cfa_offset 24 67; x86_64-NEXT: pushq %rax 68; x86_64-NEXT: .cfi_def_cfa_offset 32 69; x86_64-NEXT: .cfi_offset %rbx, -24 70; x86_64-NEXT: .cfi_offset %r14, -16 71; x86_64-NEXT: movq %rsi, %rbx 72; x86_64-NEXT: movq %rdi, %r14 73; x86_64-NEXT: callq test@PLT 74; x86_64-NEXT: fstpt (%r14) 75; x86_64-NEXT: fstpt (%rbx) 76; x86_64-NEXT: addq $8, %rsp 77; x86_64-NEXT: .cfi_def_cfa_offset 24 78; x86_64-NEXT: popq %rbx 79; x86_64-NEXT: .cfi_def_cfa_offset 16 80; x86_64-NEXT: popq %r14 81; x86_64-NEXT: .cfi_def_cfa_offset 8 82; x86_64-NEXT: retq 83 %a = call %0 @test() 84 %b = extractvalue %0 %a, 0 85 store x86_fp80 %b, ptr %P1 86 87 %c = extractvalue %0 %a, 1 88 store x86_fp80 %c, ptr %P2 89 ret void 90} 91 92; Uses both values, requires fxch 93define void @call2(ptr%P1, ptr%P2) { 94; i686-LABEL: call2: 95; i686: # %bb.0: 96; i686-NEXT: pushl %edi 97; i686-NEXT: .cfi_def_cfa_offset 8 98; i686-NEXT: pushl %esi 99; i686-NEXT: .cfi_def_cfa_offset 12 100; i686-NEXT: .cfi_offset %esi, -12 101; i686-NEXT: .cfi_offset %edi, -8 102; i686-NEXT: movl {{[0-9]+}}(%esp), %esi 103; i686-NEXT: movl {{[0-9]+}}(%esp), %edi 104; i686-NEXT: calll test@PLT 105; i686-NEXT: fxch %st(1) 106; i686-NEXT: fstpt (%edi) 107; i686-NEXT: fstpt (%esi) 108; i686-NEXT: popl %esi 109; i686-NEXT: .cfi_def_cfa_offset 8 110; i686-NEXT: popl %edi 111; i686-NEXT: .cfi_def_cfa_offset 4 112; i686-NEXT: retl 113; 114; x86_64-LABEL: call2: 115; x86_64: # %bb.0: 116; x86_64-NEXT: pushq %r14 117; x86_64-NEXT: .cfi_def_cfa_offset 16 118; x86_64-NEXT: pushq %rbx 119; x86_64-NEXT: .cfi_def_cfa_offset 24 120; x86_64-NEXT: pushq %rax 121; x86_64-NEXT: .cfi_def_cfa_offset 32 122; x86_64-NEXT: .cfi_offset %rbx, -24 123; x86_64-NEXT: .cfi_offset %r14, -16 124; x86_64-NEXT: movq %rsi, %rbx 125; x86_64-NEXT: movq %rdi, %r14 126; x86_64-NEXT: callq test@PLT 127; x86_64-NEXT: fxch %st(1) 128; x86_64-NEXT: fstpt (%r14) 129; x86_64-NEXT: fstpt (%rbx) 130; x86_64-NEXT: addq $8, %rsp 131; x86_64-NEXT: .cfi_def_cfa_offset 24 132; x86_64-NEXT: popq %rbx 133; x86_64-NEXT: .cfi_def_cfa_offset 16 134; x86_64-NEXT: popq %r14 135; x86_64-NEXT: .cfi_def_cfa_offset 8 136; x86_64-NEXT: retq 137 %a = call %0 @test() 138 %b = extractvalue %0 %a, 1 139 store x86_fp80 %b, ptr %P1 140 141 %c = extractvalue %0 %a, 0 142 store x86_fp80 %c, ptr %P2 143 ret void 144} 145 146; Uses ST(0), ST(1) is dead but must be popped. 147define void @call3(ptr%P1, ptr%P2) { 148; i686-LABEL: call3: 149; i686: # %bb.0: 150; i686-NEXT: pushl %esi 151; i686-NEXT: .cfi_def_cfa_offset 8 152; i686-NEXT: .cfi_offset %esi, -8 153; i686-NEXT: movl {{[0-9]+}}(%esp), %esi 154; i686-NEXT: calll test@PLT 155; i686-NEXT: fstp %st(1) 156; i686-NEXT: fstpt (%esi) 157; i686-NEXT: popl %esi 158; i686-NEXT: .cfi_def_cfa_offset 4 159; i686-NEXT: retl 160; 161; x86_64-LABEL: call3: 162; x86_64: # %bb.0: 163; x86_64-NEXT: pushq %rbx 164; x86_64-NEXT: .cfi_def_cfa_offset 16 165; x86_64-NEXT: .cfi_offset %rbx, -16 166; x86_64-NEXT: movq %rdi, %rbx 167; x86_64-NEXT: callq test@PLT 168; x86_64-NEXT: fstp %st(1) 169; x86_64-NEXT: fstpt (%rbx) 170; x86_64-NEXT: popq %rbx 171; x86_64-NEXT: .cfi_def_cfa_offset 8 172; x86_64-NEXT: retq 173 %a = call %0 @test() 174 %b = extractvalue %0 %a, 0 175 store x86_fp80 %b, ptr %P1 176 ret void 177} 178 179; Uses ST(1), ST(0) is dead and must be popped. 180define void @call4(ptr%P1, ptr%P2) { 181; i686-LABEL: call4: 182; i686: # %bb.0: 183; i686-NEXT: pushl %esi 184; i686-NEXT: .cfi_def_cfa_offset 8 185; i686-NEXT: .cfi_offset %esi, -8 186; i686-NEXT: movl {{[0-9]+}}(%esp), %esi 187; i686-NEXT: calll test@PLT 188; i686-NEXT: fstp %st(0) 189; i686-NEXT: fstpt (%esi) 190; i686-NEXT: popl %esi 191; i686-NEXT: .cfi_def_cfa_offset 4 192; i686-NEXT: retl 193; 194; x86_64-LABEL: call4: 195; x86_64: # %bb.0: 196; x86_64-NEXT: pushq %rbx 197; x86_64-NEXT: .cfi_def_cfa_offset 16 198; x86_64-NEXT: .cfi_offset %rbx, -16 199; x86_64-NEXT: movq %rsi, %rbx 200; x86_64-NEXT: callq test@PLT 201; x86_64-NEXT: fstp %st(0) 202; x86_64-NEXT: fstpt (%rbx) 203; x86_64-NEXT: popq %rbx 204; x86_64-NEXT: .cfi_def_cfa_offset 8 205; x86_64-NEXT: retq 206 %a = call %0 @test() 207 208 %c = extractvalue %0 %a, 1 209 store x86_fp80 %c, ptr %P2 210 ret void 211} 212 213