1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 2; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck -check-prefixes=X64 %s 3; RUN: llc -mtriple=i386-pc-win32 < %s | FileCheck -check-prefix=WIN32 %s 4 5define { half, i32 } @test_frexp_f16_i32(half %a) { 6; X64-LABEL: test_frexp_f16_i32: 7; X64: # %bb.0: 8; X64-NEXT: subq $24, %rsp 9; X64-NEXT: .cfi_def_cfa_offset 32 10; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill 11; X64-NEXT: callq __extendhfsf2@PLT 12; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 13; X64-NEXT: callq __truncsfhf2@PLT 14; X64-NEXT: pextrw $0, %xmm0, %ecx 15; X64-NEXT: movl %ecx, %eax 16; X64-NEXT: andl $31744, %eax # imm = 0x7C00 17; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload 18; X64-NEXT: pextrw $0, %xmm0, %edx 19; X64-NEXT: movl %edx, %esi 20; X64-NEXT: andl $32767, %esi # imm = 0x7FFF 21; X64-NEXT: cmpl $1024, %esi # imm = 0x400 22; X64-NEXT: cmovael %edx, %ecx 23; X64-NEXT: cmovael %esi, %eax 24; X64-NEXT: shrl $10, %eax 25; X64-NEXT: leal -12(%rax), %edi 26; X64-NEXT: cmpl $1024, %esi # imm = 0x400 27; X64-NEXT: cmovael %eax, %edi 28; X64-NEXT: addl $-14, %edi 29; X64-NEXT: andl $-31745, %ecx # imm = 0x83FF 30; X64-NEXT: orl $14336, %ecx # imm = 0x3800 31; X64-NEXT: addl $-31744, %esi # imm = 0x8400 32; X64-NEXT: movzwl %si, %esi 33; X64-NEXT: xorl %eax, %eax 34; X64-NEXT: cmpl $33792, %esi # imm = 0x8400 35; X64-NEXT: cmoval %edi, %eax 36; X64-NEXT: cmovbel %edx, %ecx 37; X64-NEXT: pinsrw $0, %ecx, %xmm0 38; X64-NEXT: addq $24, %rsp 39; X64-NEXT: .cfi_def_cfa_offset 8 40; X64-NEXT: retq 41; 42; WIN32-LABEL: test_frexp_f16_i32: 43; WIN32: # %bb.0: 44; WIN32-NEXT: pushl %esi 45; WIN32-NEXT: subl $20, %esp 46; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax 47; WIN32-NEXT: movl %eax, (%esp) 48; WIN32-NEXT: calll ___gnu_h2f_ieee 49; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 50; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 51; WIN32-NEXT: fstpl (%esp) 52; WIN32-NEXT: calll _frexp 53; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 54; WIN32-NEXT: flds {{[0-9]+}}(%esp) 55; WIN32-NEXT: fstps (%esp) 56; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi 57; WIN32-NEXT: calll ___gnu_f2h_ieee 58; WIN32-NEXT: movl %esi, %edx 59; WIN32-NEXT: addl $20, %esp 60; WIN32-NEXT: popl %esi 61; WIN32-NEXT: retl 62 %result = call { half, i32 } @llvm.frexp.f16.i32(half %a) 63 ret { half, i32 } %result 64} 65 66define half @test_frexp_f16_i32_only_use_fract(half %a) { 67; X64-LABEL: test_frexp_f16_i32_only_use_fract: 68; X64: # %bb.0: 69; X64-NEXT: subq $24, %rsp 70; X64-NEXT: .cfi_def_cfa_offset 32 71; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill 72; X64-NEXT: callq __extendhfsf2@PLT 73; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 74; X64-NEXT: callq __truncsfhf2@PLT 75; X64-NEXT: pextrw $0, %xmm0, %eax 76; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload 77; X64-NEXT: pextrw $0, %xmm0, %ecx 78; X64-NEXT: movl %ecx, %edx 79; X64-NEXT: andl $32767, %edx # imm = 0x7FFF 80; X64-NEXT: cmpl $1024, %edx # imm = 0x400 81; X64-NEXT: cmovael %ecx, %eax 82; X64-NEXT: andl $-31745, %eax # imm = 0x83FF 83; X64-NEXT: orl $14336, %eax # imm = 0x3800 84; X64-NEXT: addl $-31744, %edx # imm = 0x8400 85; X64-NEXT: movzwl %dx, %edx 86; X64-NEXT: cmpl $33792, %edx # imm = 0x8400 87; X64-NEXT: cmovbel %ecx, %eax 88; X64-NEXT: pinsrw $0, %eax, %xmm0 89; X64-NEXT: addq $24, %rsp 90; X64-NEXT: .cfi_def_cfa_offset 8 91; X64-NEXT: retq 92; 93; WIN32-LABEL: test_frexp_f16_i32_only_use_fract: 94; WIN32: # %bb.0: 95; WIN32-NEXT: subl $20, %esp 96; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax 97; WIN32-NEXT: movl %eax, (%esp) 98; WIN32-NEXT: calll ___gnu_h2f_ieee 99; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 100; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 101; WIN32-NEXT: fstpl (%esp) 102; WIN32-NEXT: calll _frexp 103; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 104; WIN32-NEXT: flds {{[0-9]+}}(%esp) 105; WIN32-NEXT: fstps (%esp) 106; WIN32-NEXT: calll ___gnu_f2h_ieee 107; WIN32-NEXT: addl $20, %esp 108; WIN32-NEXT: retl 109 %result = call { half, i32 } @llvm.frexp.f16.i32(half %a) 110 %result.0 = extractvalue { half, i32 } %result, 0 111 ret half %result.0 112} 113 114define i32 @test_frexp_f16_i32_only_use_exp(half %a) { 115; X64-LABEL: test_frexp_f16_i32_only_use_exp: 116; X64: # %bb.0: 117; X64-NEXT: subq $24, %rsp 118; X64-NEXT: .cfi_def_cfa_offset 32 119; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill 120; X64-NEXT: callq __extendhfsf2@PLT 121; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 122; X64-NEXT: callq __truncsfhf2@PLT 123; X64-NEXT: pextrw $0, %xmm0, %eax 124; X64-NEXT: andl $31744, %eax # imm = 0x7C00 125; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload 126; X64-NEXT: pextrw $0, %xmm0, %ecx 127; X64-NEXT: andl $32767, %ecx # imm = 0x7FFF 128; X64-NEXT: cmpl $1024, %ecx # imm = 0x400 129; X64-NEXT: cmovael %ecx, %eax 130; X64-NEXT: shrl $10, %eax 131; X64-NEXT: leal -12(%rax), %edx 132; X64-NEXT: cmpl $1024, %ecx # imm = 0x400 133; X64-NEXT: cmovael %eax, %edx 134; X64-NEXT: addl $-14, %edx 135; X64-NEXT: addl $-31744, %ecx # imm = 0x8400 136; X64-NEXT: movzwl %cx, %ecx 137; X64-NEXT: xorl %eax, %eax 138; X64-NEXT: cmpl $33792, %ecx # imm = 0x8400 139; X64-NEXT: cmoval %edx, %eax 140; X64-NEXT: addq $24, %rsp 141; X64-NEXT: .cfi_def_cfa_offset 8 142; X64-NEXT: retq 143; 144; WIN32-LABEL: test_frexp_f16_i32_only_use_exp: 145; WIN32: # %bb.0: 146; WIN32-NEXT: subl $16, %esp 147; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax 148; WIN32-NEXT: movl %eax, (%esp) 149; WIN32-NEXT: calll ___gnu_h2f_ieee 150; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 151; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 152; WIN32-NEXT: fstpl (%esp) 153; WIN32-NEXT: calll _frexp 154; WIN32-NEXT: fstp %st(0) 155; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax 156; WIN32-NEXT: addl $16, %esp 157; WIN32-NEXT: retl 158 %result = call { half, i32 } @llvm.frexp.f16.i32(half %a) 159 %result.0 = extractvalue { half, i32 } %result, 1 160 ret i32 %result.0 161} 162 163; FIXME 164; define { <2 x half>, <2 x i32> } @test_frexp_v2f16_v2i32(<2 x half> %a) { 165; %result = call { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half> %a) 166; ret { <2 x half>, <2 x i32> } %result 167; } 168 169; define <2 x half> @test_frexp_v2f16_v2i32_only_use_fract(<2 x half> %a) { 170; %result = call { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half> %a) 171; %result.0 = extractvalue { <2 x half>, <2 x i32> } %result, 0 172; ret <2 x half> %result.0 173; } 174 175; define <2 x i32> @test_frexp_v2f16_v2i32_only_use_exp(<2 x half> %a) { 176; %result = call { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half> %a) 177; %result.1 = extractvalue { <2 x half>, <2 x i32> } %result, 1 178; ret <2 x i32> %result.1 179; } 180 181define { float, i32 } @test_frexp_f32_i32(float %a) { 182; X64-LABEL: test_frexp_f32_i32: 183; X64: # %bb.0: 184; X64-NEXT: pushq %rax 185; X64-NEXT: .cfi_def_cfa_offset 16 186; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 187; X64-NEXT: callq frexpf@PLT 188; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax 189; X64-NEXT: popq %rcx 190; X64-NEXT: .cfi_def_cfa_offset 8 191; X64-NEXT: retq 192; 193; WIN32-LABEL: test_frexp_f32_i32: 194; WIN32: # %bb.0: 195; WIN32-NEXT: subl $20, %esp 196; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 197; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 198; WIN32-NEXT: flds {{[0-9]+}}(%esp) 199; WIN32-NEXT: fstpl (%esp) 200; WIN32-NEXT: calll _frexp 201; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 202; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax 203; WIN32-NEXT: flds {{[0-9]+}}(%esp) 204; WIN32-NEXT: addl $20, %esp 205; WIN32-NEXT: retl 206 %result = call { float, i32 } @llvm.frexp.f32.i32(float %a) 207 ret { float, i32 } %result 208} 209 210define float @test_frexp_f32_i32_only_use_fract(float %a) { 211; X64-LABEL: test_frexp_f32_i32_only_use_fract: 212; X64: # %bb.0: 213; X64-NEXT: pushq %rax 214; X64-NEXT: .cfi_def_cfa_offset 16 215; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 216; X64-NEXT: callq frexpf@PLT 217; X64-NEXT: popq %rax 218; X64-NEXT: .cfi_def_cfa_offset 8 219; X64-NEXT: retq 220; 221; WIN32-LABEL: test_frexp_f32_i32_only_use_fract: 222; WIN32: # %bb.0: 223; WIN32-NEXT: subl $20, %esp 224; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 225; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 226; WIN32-NEXT: flds {{[0-9]+}}(%esp) 227; WIN32-NEXT: fstpl (%esp) 228; WIN32-NEXT: calll _frexp 229; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 230; WIN32-NEXT: flds {{[0-9]+}}(%esp) 231; WIN32-NEXT: addl $20, %esp 232; WIN32-NEXT: retl 233 %result = call { float, i32 } @llvm.frexp.f32.i32(float %a) 234 %result.0 = extractvalue { float, i32 } %result, 0 235 ret float %result.0 236} 237 238define i32 @test_frexp_f32_i32_only_use_exp(float %a) { 239; X64-LABEL: test_frexp_f32_i32_only_use_exp: 240; X64: # %bb.0: 241; X64-NEXT: pushq %rax 242; X64-NEXT: .cfi_def_cfa_offset 16 243; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 244; X64-NEXT: callq frexpf@PLT 245; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax 246; X64-NEXT: popq %rcx 247; X64-NEXT: .cfi_def_cfa_offset 8 248; X64-NEXT: retq 249; 250; WIN32-LABEL: test_frexp_f32_i32_only_use_exp: 251; WIN32: # %bb.0: 252; WIN32-NEXT: subl $16, %esp 253; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 254; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 255; WIN32-NEXT: flds {{[0-9]+}}(%esp) 256; WIN32-NEXT: fstpl (%esp) 257; WIN32-NEXT: calll _frexp 258; WIN32-NEXT: fstp %st(0) 259; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax 260; WIN32-NEXT: addl $16, %esp 261; WIN32-NEXT: retl 262 %result = call { float, i32 } @llvm.frexp.f32.i32(float %a) 263 %result.0 = extractvalue { float, i32 } %result, 1 264 ret i32 %result.0 265} 266 267; FIXME: Widen vector result 268; define { <2 x float>, <2 x i32> } @test_frexp_v2f32_v2i32(<2 x float> %a) { 269; %result = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %a) 270; ret { <2 x float>, <2 x i32> } %result 271; } 272 273; define <2 x float> @test_frexp_v2f32_v2i32_only_use_fract(<2 x float> %a) { 274; %result = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %a) 275; %result.0 = extractvalue { <2 x float>, <2 x i32> } %result, 0 276; ret <2 x float> %result.0 277; } 278 279; define <2 x i32> @test_frexp_v2f32_v2i32_only_use_exp(<2 x float> %a) { 280; %result = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %a) 281; %result.1 = extractvalue { <2 x float>, <2 x i32> } %result, 1 282; ret <2 x i32> %result.1 283; } 284 285define { <4 x float>, <4 x i32> } @test_frexp_v4f32_v4i32(<4 x float> %a) { 286; X64-LABEL: test_frexp_v4f32_v4i32: 287; X64: # %bb.0: 288; X64-NEXT: subq $72, %rsp 289; X64-NEXT: .cfi_def_cfa_offset 80 290; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 291; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3,3,3] 292; X64-NEXT: movq %rsp, %rdi 293; X64-NEXT: callq frexpf@PLT 294; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 295; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload 296; X64-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1] 297; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 298; X64-NEXT: callq frexpf@PLT 299; X64-NEXT: unpcklps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 300; X64-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 301; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 302; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 303; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload 304; X64-NEXT: callq frexpf@PLT 305; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 306; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload 307; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,1,1,1] 308; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 309; X64-NEXT: callq frexpf@PLT 310; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 311; X64-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 312; X64-NEXT: unpcklpd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload 313; X64-NEXT: # xmm1 = xmm1[0],mem[0] 314; X64-NEXT: movaps %xmm1, %xmm0 315; X64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 316; X64-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero 317; X64-NEXT: unpcklps {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1] 318; X64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 319; X64-NEXT: movss {{.*#+}} xmm3 = mem[0],zero,zero,zero 320; X64-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1] 321; X64-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0],xmm2[0] 322; X64-NEXT: addq $72, %rsp 323; X64-NEXT: .cfi_def_cfa_offset 8 324; X64-NEXT: retq 325; 326; WIN32-LABEL: test_frexp_v4f32_v4i32: 327; WIN32: # %bb.0: 328; WIN32-NEXT: pushl %esi 329; WIN32-NEXT: subl $44, %esp 330; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi 331; WIN32-NEXT: leal 24(%esi), %eax 332; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 333; WIN32-NEXT: flds {{[0-9]+}}(%esp) 334; WIN32-NEXT: fstpl (%esp) 335; WIN32-NEXT: calll _frexp 336; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill 337; WIN32-NEXT: leal 20(%esi), %eax 338; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 339; WIN32-NEXT: flds {{[0-9]+}}(%esp) 340; WIN32-NEXT: fstpl (%esp) 341; WIN32-NEXT: calll _frexp 342; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill 343; WIN32-NEXT: leal 16(%esi), %eax 344; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 345; WIN32-NEXT: flds {{[0-9]+}}(%esp) 346; WIN32-NEXT: fstpl (%esp) 347; WIN32-NEXT: calll _frexp 348; WIN32-NEXT: leal 28(%esi), %eax 349; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 350; WIN32-NEXT: flds {{[0-9]+}}(%esp) 351; WIN32-NEXT: fstpl (%esp) 352; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 353; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload 354; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 355; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload 356; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 357; WIN32-NEXT: calll _frexp 358; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 359; WIN32-NEXT: flds {{[0-9]+}}(%esp) 360; WIN32-NEXT: flds {{[0-9]+}}(%esp) 361; WIN32-NEXT: flds {{[0-9]+}}(%esp) 362; WIN32-NEXT: flds {{[0-9]+}}(%esp) 363; WIN32-NEXT: fstps 12(%esi) 364; WIN32-NEXT: fstps 8(%esi) 365; WIN32-NEXT: fstps 4(%esi) 366; WIN32-NEXT: fstps (%esi) 367; WIN32-NEXT: movl %esi, %eax 368; WIN32-NEXT: addl $44, %esp 369; WIN32-NEXT: popl %esi 370; WIN32-NEXT: retl 371 %result = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %a) 372 ret { <4 x float>, <4 x i32> } %result 373} 374 375define <4 x float> @test_frexp_v4f32_v4i32_only_use_fract(<4 x float> %a) { 376; X64-LABEL: test_frexp_v4f32_v4i32_only_use_fract: 377; X64: # %bb.0: 378; X64-NEXT: subq $72, %rsp 379; X64-NEXT: .cfi_def_cfa_offset 80 380; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 381; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3,3,3] 382; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 383; X64-NEXT: callq frexpf@PLT 384; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill 385; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload 386; X64-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1] 387; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 388; X64-NEXT: callq frexpf@PLT 389; X64-NEXT: unpcklps (%rsp), %xmm0 # 16-byte Folded Reload 390; X64-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 391; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill 392; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 393; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload 394; X64-NEXT: callq frexpf@PLT 395; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 396; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload 397; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,1,1,1] 398; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 399; X64-NEXT: callq frexpf@PLT 400; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 401; X64-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 402; X64-NEXT: unpcklpd (%rsp), %xmm1 # 16-byte Folded Reload 403; X64-NEXT: # xmm1 = xmm1[0],mem[0] 404; X64-NEXT: movaps %xmm1, %xmm0 405; X64-NEXT: addq $72, %rsp 406; X64-NEXT: .cfi_def_cfa_offset 8 407; X64-NEXT: retq 408; 409; WIN32-LABEL: test_frexp_v4f32_v4i32_only_use_fract: 410; WIN32: # %bb.0: 411; WIN32-NEXT: pushl %esi 412; WIN32-NEXT: subl $60, %esp 413; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi 414; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 415; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 416; WIN32-NEXT: flds {{[0-9]+}}(%esp) 417; WIN32-NEXT: fstpl (%esp) 418; WIN32-NEXT: calll _frexp 419; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill 420; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 421; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 422; WIN32-NEXT: flds {{[0-9]+}}(%esp) 423; WIN32-NEXT: fstpl (%esp) 424; WIN32-NEXT: calll _frexp 425; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill 426; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 427; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 428; WIN32-NEXT: flds {{[0-9]+}}(%esp) 429; WIN32-NEXT: fstpl (%esp) 430; WIN32-NEXT: calll _frexp 431; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 432; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 433; WIN32-NEXT: flds {{[0-9]+}}(%esp) 434; WIN32-NEXT: fstpl (%esp) 435; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 436; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload 437; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 438; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload 439; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 440; WIN32-NEXT: calll _frexp 441; WIN32-NEXT: fstps {{[0-9]+}}(%esp) 442; WIN32-NEXT: flds {{[0-9]+}}(%esp) 443; WIN32-NEXT: flds {{[0-9]+}}(%esp) 444; WIN32-NEXT: flds {{[0-9]+}}(%esp) 445; WIN32-NEXT: flds {{[0-9]+}}(%esp) 446; WIN32-NEXT: fstps 12(%esi) 447; WIN32-NEXT: fstps 8(%esi) 448; WIN32-NEXT: fstps 4(%esi) 449; WIN32-NEXT: fstps (%esi) 450; WIN32-NEXT: movl %esi, %eax 451; WIN32-NEXT: addl $60, %esp 452; WIN32-NEXT: popl %esi 453; WIN32-NEXT: retl 454 %result = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %a) 455 %result.0 = extractvalue { <4 x float>, <4 x i32> } %result, 0 456 ret <4 x float> %result.0 457} 458 459define <4 x i32> @test_frexp_v4f32_v4i32_only_use_exp(<4 x float> %a) { 460; X64-LABEL: test_frexp_v4f32_v4i32_only_use_exp: 461; X64: # %bb.0: 462; X64-NEXT: subq $40, %rsp 463; X64-NEXT: .cfi_def_cfa_offset 48 464; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 465; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3,3,3] 466; X64-NEXT: movq %rsp, %rdi 467; X64-NEXT: callq frexpf@PLT 468; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload 469; X64-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1] 470; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 471; X64-NEXT: callq frexpf@PLT 472; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 473; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload 474; X64-NEXT: callq frexpf@PLT 475; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload 476; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,1,1,1] 477; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 478; X64-NEXT: callq frexpf@PLT 479; X64-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero 480; X64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 481; X64-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 482; X64-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero 483; X64-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero 484; X64-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1] 485; X64-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 486; X64-NEXT: addq $40, %rsp 487; X64-NEXT: .cfi_def_cfa_offset 8 488; X64-NEXT: retq 489; 490; WIN32-LABEL: test_frexp_v4f32_v4i32_only_use_exp: 491; WIN32: # %bb.0: 492; WIN32-NEXT: pushl %esi 493; WIN32-NEXT: subl $12, %esp 494; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi 495; WIN32-NEXT: leal 8(%esi), %eax 496; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 497; WIN32-NEXT: flds {{[0-9]+}}(%esp) 498; WIN32-NEXT: fstpl (%esp) 499; WIN32-NEXT: calll _frexp 500; WIN32-NEXT: fstp %st(0) 501; WIN32-NEXT: leal 4(%esi), %eax 502; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 503; WIN32-NEXT: flds {{[0-9]+}}(%esp) 504; WIN32-NEXT: fstpl (%esp) 505; WIN32-NEXT: calll _frexp 506; WIN32-NEXT: fstp %st(0) 507; WIN32-NEXT: leal 12(%esi), %eax 508; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 509; WIN32-NEXT: flds {{[0-9]+}}(%esp) 510; WIN32-NEXT: fstpl (%esp) 511; WIN32-NEXT: calll _frexp 512; WIN32-NEXT: fstp %st(0) 513; WIN32-NEXT: movl %esi, {{[0-9]+}}(%esp) 514; WIN32-NEXT: flds {{[0-9]+}}(%esp) 515; WIN32-NEXT: fstpl (%esp) 516; WIN32-NEXT: calll _frexp 517; WIN32-NEXT: fstp %st(0) 518; WIN32-NEXT: movl %esi, %eax 519; WIN32-NEXT: addl $12, %esp 520; WIN32-NEXT: popl %esi 521; WIN32-NEXT: retl 522 %result = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %a) 523 %result.1 = extractvalue { <4 x float>, <4 x i32> } %result, 1 524 ret <4 x i32> %result.1 525} 526 527define { double, i32 } @test_frexp_f64_i32(double %a) { 528; X64-LABEL: test_frexp_f64_i32: 529; X64: # %bb.0: 530; X64-NEXT: pushq %rax 531; X64-NEXT: .cfi_def_cfa_offset 16 532; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 533; X64-NEXT: callq frexp@PLT 534; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax 535; X64-NEXT: popq %rcx 536; X64-NEXT: .cfi_def_cfa_offset 8 537; X64-NEXT: retq 538; 539; WIN32-LABEL: test_frexp_f64_i32: 540; WIN32: # %bb.0: 541; WIN32-NEXT: subl $16, %esp 542; WIN32-NEXT: fldl {{[0-9]+}}(%esp) 543; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 544; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 545; WIN32-NEXT: fstpl (%esp) 546; WIN32-NEXT: calll _frexp 547; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax 548; WIN32-NEXT: addl $16, %esp 549; WIN32-NEXT: retl 550 %result = call { double, i32 } @llvm.frexp.f64.i32(double %a) 551 ret { double, i32 } %result 552} 553 554define double @test_frexp_f64_i32_only_use_fract(double %a) { 555; X64-LABEL: test_frexp_f64_i32_only_use_fract: 556; X64: # %bb.0: 557; X64-NEXT: pushq %rax 558; X64-NEXT: .cfi_def_cfa_offset 16 559; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 560; X64-NEXT: callq frexp@PLT 561; X64-NEXT: popq %rax 562; X64-NEXT: .cfi_def_cfa_offset 8 563; X64-NEXT: retq 564; 565; WIN32-LABEL: test_frexp_f64_i32_only_use_fract: 566; WIN32: # %bb.0: 567; WIN32-NEXT: subl $16, %esp 568; WIN32-NEXT: fldl {{[0-9]+}}(%esp) 569; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 570; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 571; WIN32-NEXT: fstpl (%esp) 572; WIN32-NEXT: calll _frexp 573; WIN32-NEXT: addl $16, %esp 574; WIN32-NEXT: retl 575 %result = call { double, i32 } @llvm.frexp.f64.i32(double %a) 576 %result.0 = extractvalue { double, i32 } %result, 0 577 ret double %result.0 578} 579 580define i32 @test_frexp_f64_i32_only_use_exp(double %a) { 581; X64-LABEL: test_frexp_f64_i32_only_use_exp: 582; X64: # %bb.0: 583; X64-NEXT: pushq %rax 584; X64-NEXT: .cfi_def_cfa_offset 16 585; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi 586; X64-NEXT: callq frexp@PLT 587; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax 588; X64-NEXT: popq %rcx 589; X64-NEXT: .cfi_def_cfa_offset 8 590; X64-NEXT: retq 591; 592; WIN32-LABEL: test_frexp_f64_i32_only_use_exp: 593; WIN32: # %bb.0: 594; WIN32-NEXT: subl $16, %esp 595; WIN32-NEXT: fldl {{[0-9]+}}(%esp) 596; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax 597; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp) 598; WIN32-NEXT: fstpl (%esp) 599; WIN32-NEXT: calll _frexp 600; WIN32-NEXT: fstp %st(0) 601; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax 602; WIN32-NEXT: addl $16, %esp 603; WIN32-NEXT: retl 604 %result = call { double, i32 } @llvm.frexp.f64.i32(double %a) 605 %result.0 = extractvalue { double, i32 } %result, 1 606 ret i32 %result.0 607} 608 609; FIXME: Widen vector result 610; define { <2 x double>, <2 x i32> } @test_frexp_v2f64_v2i32(<2 x double> %a) { 611; %result = call { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double> %a) 612; ret { <2 x double>, <2 x i32> } %result 613; } 614 615; define <2 x double> @test_frexp_v2f64_v2i32_only_use_fract(<2 x double> %a) { 616; %result = call { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double> %a) 617; %result.0 = extractvalue { <2 x double>, <2 x i32> } %result, 0 618; ret <2 x double> %result.0 619; } 620 621; define <2 x i32> @test_frexp_v2f64_v2i32_only_use_exp(<2 x double> %a) { 622; %result = call { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double> %a) 623; %result.1 = extractvalue { <2 x double>, <2 x i32> } %result, 1 624; ret <2 x i32> %result.1 625; } 626 627declare { float, i32 } @llvm.frexp.f32.i32(float) #0 628declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>) #0 629declare { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float>) #0 630 631declare { half, i32 } @llvm.frexp.f16.i32(half) #0 632declare { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half>) #0 633 634declare { double, i32 } @llvm.frexp.f64.i32(double) #0 635declare { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double>) #0 636 637declare { half, i16 } @llvm.frexp.f16.i16(half) #0 638declare { <2 x half>, <2 x i16> } @llvm.frexp.v2f16.v2i16(<2 x half>) #0 639 640attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } 641