From fd1fb1b259831245b33d75b1d51a840be47a2afe Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 11 Jul 2025 21:47:34 -0400 Subject: [PATCH 1/2] [Windows] Allow legalizing LDEXP_F128 and FREXP_F128 with libcalls Attempting to use `llvm.ldexp.f128` or `llvm.frexp.f128` on Windows platforms results in a legalization failure. The needed functions `ldexpf128` and `frexpf128` aren't available on Windows, but it should be a failure to link that can be solved by adding a `f128` library is preferable to crashing. Note that due to [44744] this lowering actually incorrectly produces `ldexpl` and `frexpl` symbols, which aren't correct for `_Float128` on Windows. This will be fixed separately. This patch also adds `{frexp,ldexp}.f128` tests on a couple architectures that were missing them, unrelated to the Windows-only change here. [44744]: https://github.com/llvm/llvm-project/issues/44744 Fixes: https://github.com/llvm/llvm-project/issues/144006 --- llvm/lib/IR/RuntimeLibcalls.cpp | 2 - llvm/test/CodeGen/AArch64/ldexp.ll | 13 +++ llvm/test/CodeGen/AArch64/llvm.frexp.ll | 67 ++++++++++++ llvm/test/CodeGen/ARM/ldexp.ll | 8 ++ llvm/test/CodeGen/ARM/llvm.frexp.ll | 53 ++++++++++ llvm/test/CodeGen/Mips/ldexp.ll | 14 +++ llvm/test/CodeGen/X86/ldexp.ll | 57 ++++++++++ llvm/test/CodeGen/X86/llvm.frexp.ll | 133 ++++++++++++++++++++++++ 8 files changed, 345 insertions(+), 2 deletions(-) diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index 64c9415c54d4d..2dbd6b2ef78ea 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -206,12 +206,10 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, if (TT.isOSWindows() && !TT.isOSCygMing()) { setLibcallImpl(RTLIB::LDEXP_F32, RTLIB::Unsupported); setLibcallImpl(RTLIB::LDEXP_F80, RTLIB::Unsupported); - setLibcallImpl(RTLIB::LDEXP_F128, RTLIB::Unsupported); setLibcallImpl(RTLIB::LDEXP_PPCF128, RTLIB::Unsupported); setLibcallImpl(RTLIB::FREXP_F32, RTLIB::Unsupported); setLibcallImpl(RTLIB::FREXP_F80, RTLIB::Unsupported); - setLibcallImpl(RTLIB::FREXP_F128, RTLIB::Unsupported); setLibcallImpl(RTLIB::FREXP_PPCF128, RTLIB::Unsupported); } diff --git a/llvm/test/CodeGen/AArch64/ldexp.ll b/llvm/test/CodeGen/AArch64/ldexp.ll index 6019fa1490e3d..75822f512ffdb 100644 --- a/llvm/test/CodeGen/AArch64/ldexp.ll +++ b/llvm/test/CodeGen/AArch64/ldexp.ll @@ -147,4 +147,17 @@ entry: ret half %0 } +define fp128 @testExpf128(fp128 %val, i32 %a) { +; SVE-LABEL: testExpf128: +; SVE: // %bb.0: // %entry +; SVE-NEXT: b ldexpl +; +; WINDOWS-LABEL: testExpf128: +; WINDOWS: // %bb.0: // %entry +; WINDOWS-NEXT: b ldexpl +entry: + %ldexp = call fp128 @llvm.ldexp.f128.i32(fp128 %val, i32 %a) + ret fp128 %ldexp +} + declare half @llvm.ldexp.f16.i32(half, i32) memory(none) diff --git a/llvm/test/CodeGen/AArch64/llvm.frexp.ll b/llvm/test/CodeGen/AArch64/llvm.frexp.ll index 2213aa1429dbd..dca895cfcb976 100644 --- a/llvm/test/CodeGen/AArch64/llvm.frexp.ll +++ b/llvm/test/CodeGen/AArch64/llvm.frexp.ll @@ -1131,6 +1131,73 @@ define <2 x i32> @test_frexp_v2f64_v2i32_only_use_exp(<2 x double> %a) nounwind ret <2 x i32> %result.1 } + +define { fp128, i32 } @test_frexp_f128_i32(fp128 %a) nounwind { +; CHECK-LABEL: test_frexp_f128_i32: +; CHECK: // %bb.0: +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: add x0, sp, #12 +; CHECK-NEXT: bl frexpl +; CHECK-NEXT: ldr w0, [sp, #12] +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: ret +; +; WINDOWS-LABEL: test_frexp_f128_i32: +; WINDOWS: // %bb.0: +; WINDOWS-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINDOWS-NEXT: add x0, sp, #12 +; WINDOWS-NEXT: bl frexpl +; WINDOWS-NEXT: ldr w0, [sp, #12] +; WINDOWS-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINDOWS-NEXT: ret + %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a) + ret { fp128, i32 } %result +} + +define fp128 @test_frexp_f128_i32_only_use_fract(fp128 %a) nounwind { +; CHECK-LABEL: test_frexp_f128_i32_only_use_fract: +; CHECK: // %bb.0: +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: add x0, sp, #12 +; CHECK-NEXT: bl frexpl +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: ret +; +; WINDOWS-LABEL: test_frexp_f128_i32_only_use_fract: +; WINDOWS: // %bb.0: +; WINDOWS-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINDOWS-NEXT: add x0, sp, #12 +; WINDOWS-NEXT: bl frexpl +; WINDOWS-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINDOWS-NEXT: ret + %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a) + %result.0 = extractvalue { fp128, i32 } %result, 0 + ret fp128 %result.0 +} + +define i32 @test_frexp_f128_i32_only_use_exp(fp128 %a) nounwind { +; CHECK-LABEL: test_frexp_f128_i32_only_use_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: add x0, sp, #12 +; CHECK-NEXT: bl frexpl +; CHECK-NEXT: ldr w0, [sp, #12] +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: ret +; +; WINDOWS-LABEL: test_frexp_f128_i32_only_use_exp: +; WINDOWS: // %bb.0: +; WINDOWS-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINDOWS-NEXT: add x0, sp, #12 +; WINDOWS-NEXT: bl frexpl +; WINDOWS-NEXT: ldr w0, [sp, #12] +; WINDOWS-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINDOWS-NEXT: ret + %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a) + %result.0 = extractvalue { fp128, i32 } %result, 1 + ret i32 %result.0 +} + declare { float, i32 } @llvm.frexp.f32.i32(float) #0 declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>) #0 declare { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float>) #0 diff --git a/llvm/test/CodeGen/ARM/ldexp.ll b/llvm/test/CodeGen/ARM/ldexp.ll index cdf91eb902e05..1c2c35eaf4f37 100644 --- a/llvm/test/CodeGen/ARM/ldexp.ll +++ b/llvm/test/CodeGen/ARM/ldexp.ll @@ -55,4 +55,12 @@ entry: ret half %0 } +define fp128 @testExpf128(fp128 %val, i32 %a) { +; LINUX: bl ldexpl +; WINDOWS: bl ldexpl +entry: + %0 = tail call fp128 @llvm.ldexp.f128.i32(fp128 %val, i32 %a) + ret fp128 %0 +} + declare half @llvm.ldexp.f16.i32(half, i32) memory(none) diff --git a/llvm/test/CodeGen/ARM/llvm.frexp.ll b/llvm/test/CodeGen/ARM/llvm.frexp.ll index 43edb17fe1081..376426d701b3e 100644 --- a/llvm/test/CodeGen/ARM/llvm.frexp.ll +++ b/llvm/test/CodeGen/ARM/llvm.frexp.ll @@ -544,6 +544,59 @@ define <2 x i32> @test_frexp_v2f64_v2i32_only_use_exp(<2 x double> %a) { ret <2 x i32> %result.1 } +define { fp128, i32 } @test_frexp_f128_i32(fp128 %a) nounwind { +; CHECK-LABEL: test_frexp_f128_i32: +; CHECK: @ %bb.0: +; CHECK-NEXT: push {r4, lr} +; CHECK-NEXT: sub sp, #8 +; CHECK-NEXT: mov r12, r3 +; CHECK-NEXT: ldr r3, [sp, #16] +; CHECK-NEXT: mov r4, r0 +; CHECK-NEXT: add r0, sp, #4 +; CHECK-NEXT: str r0, [sp] +; CHECK-NEXT: mov r0, r1 +; CHECK-NEXT: mov r1, r2 +; CHECK-NEXT: mov r2, r12 +; CHECK-NEXT: bl frexpl +; CHECK-NEXT: ldr.w r12, [sp, #4] +; CHECK-NEXT: stm.w r4, {r0, r1, r2, r3, r12} +; CHECK-NEXT: add sp, #8 +; CHECK-NEXT: pop {r4, pc} + %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a) + ret { fp128, i32 } %result +} + +define fp128 @test_frexp_f128_i32_only_use_fract(fp128 %a) nounwind { +; CHECK-LABEL: test_frexp_f128_i32_only_use_fract: +; CHECK: @ %bb.0: +; CHECK-NEXT: push {r7, lr} +; CHECK-NEXT: sub sp, #8 +; CHECK-NEXT: add.w r12, sp, #4 +; CHECK-NEXT: str.w r12, [sp] +; CHECK-NEXT: bl frexpl +; CHECK-NEXT: add sp, #8 +; CHECK-NEXT: pop {r7, pc} + %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a) + %result.0 = extractvalue { fp128, i32 } %result, 0 + ret fp128 %result.0 +} + +define i32 @test_frexp_f128_i32_only_use_exp(fp128 %a) nounwind { +; CHECK-LABEL: test_frexp_f128_i32_only_use_exp: +; CHECK: @ %bb.0: +; CHECK-NEXT: push {r7, lr} +; CHECK-NEXT: sub sp, #8 +; CHECK-NEXT: add.w r12, sp, #4 +; CHECK-NEXT: str.w r12, [sp] +; CHECK-NEXT: bl frexpl +; CHECK-NEXT: ldr r0, [sp, #4] +; CHECK-NEXT: add sp, #8 +; CHECK-NEXT: pop {r7, pc} + %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a) + %result.0 = extractvalue { fp128, i32 } %result, 1 + ret i32 %result.0 +} + declare { float, i32 } @llvm.frexp.f32.i32(float) #0 declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>) #0 declare { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float>) #0 diff --git a/llvm/test/CodeGen/Mips/ldexp.ll b/llvm/test/CodeGen/Mips/ldexp.ll index d321cdb828e43..ca509057ead80 100644 --- a/llvm/test/CodeGen/Mips/ldexp.ll +++ b/llvm/test/CodeGen/Mips/ldexp.ll @@ -141,6 +141,20 @@ define x86_fp80 @ldexp_f80(x86_fp80 %arg0, i32 %arg1) nounwind { ret x86_fp80 %ldexp } +define fp128 @ldexp_f128(fp128 %arg0, i32 %arg1) nounwind { +; SOFT-LABEL: ldexp_f128: +; SOFT: # %bb.0: +; SOFT-NEXT: addiu $sp, $sp, -32 +; SOFT-NEXT: sw $ra, 28($sp) # 4-byte Folded Spill +; SOFT-NEXT: lw $1, 48($sp) +; SOFT-NEXT: jal ldexpl +; SOFT-NEXT: sw $1, 16($sp) +; SOFT-NEXT: lw $ra, 28($sp) # 4-byte Folded Reload +; SOFT-NEXT: jr $ra +; SOFT-NEXT: addiu $sp, $sp, 32 + %ldexp = call fp128 @llvm.ldexp.f128.i32(fp128 %arg0, i32 %arg1) + ret fp128 %ldexp +} declare double @llvm.ldexp.f64.i32(double, i32) #0 declare float @llvm.ldexp.f32.i32(float, i32) #0 diff --git a/llvm/test/CodeGen/X86/ldexp.ll b/llvm/test/CodeGen/X86/ldexp.ll index 59ec7bfcaa910..c2126250deeca 100644 --- a/llvm/test/CodeGen/X86/ldexp.ll +++ b/llvm/test/CodeGen/X86/ldexp.ll @@ -557,6 +557,63 @@ define half @ldexp_f16(half %arg0, i32 %arg1) nounwind { ret half %ldexp } +define fp128 @ldexp_f128(fp128 %arg0, i32 %arg1) nounwind { +; X64-LABEL: ldexp_f128: +; X64: # %bb.0: +; X64-NEXT: jmp ldexpl@PLT # TAILCALL +; +; WIN64-LABEL: ldexp_f128: +; WIN64: # %bb.0: +; WIN64-NEXT: subq $56, %rsp +; WIN64-NEXT: .seh_stackalloc 56 +; WIN64-NEXT: .seh_endprologue +; WIN64-NEXT: movaps (%rcx), %xmm0 +; WIN64-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp) +; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rcx +; WIN64-NEXT: callq ldexpl +; WIN64-NEXT: nop +; WIN64-NEXT: .seh_startepilogue +; WIN64-NEXT: addq $56, %rsp +; WIN64-NEXT: .seh_endepilogue +; WIN64-NEXT: retq +; WIN64-NEXT: .seh_endproc +; +; WIN32-LABEL: ldexp_f128: +; WIN32: # %bb.0: +; WIN32-NEXT: pushl %ebp +; WIN32-NEXT: movl %esp, %ebp +; WIN32-NEXT: pushl %edi +; WIN32-NEXT: pushl %esi +; WIN32-NEXT: andl $-16, %esp +; WIN32-NEXT: subl $16, %esp +; WIN32-NEXT: movl 8(%ebp), %esi +; WIN32-NEXT: movl %esp, %eax +; WIN32-NEXT: pushl 28(%ebp) +; WIN32-NEXT: pushl 24(%ebp) +; WIN32-NEXT: pushl 20(%ebp) +; WIN32-NEXT: pushl 16(%ebp) +; WIN32-NEXT: pushl 12(%ebp) +; WIN32-NEXT: pushl %eax +; WIN32-NEXT: calll _ldexpl +; WIN32-NEXT: addl $24, %esp +; WIN32-NEXT: movl (%esp), %eax +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi +; WIN32-NEXT: movl %edi, 12(%esi) +; WIN32-NEXT: movl %edx, 8(%esi) +; WIN32-NEXT: movl %ecx, 4(%esi) +; WIN32-NEXT: movl %eax, (%esi) +; WIN32-NEXT: movl %esi, %eax +; WIN32-NEXT: leal -8(%ebp), %esp +; WIN32-NEXT: popl %esi +; WIN32-NEXT: popl %edi +; WIN32-NEXT: popl %ebp +; WIN32-NEXT: retl + %ldexp = call fp128 @llvm.ldexp.f128.i32(fp128 %arg0, i32 %arg1) + ret fp128 %ldexp +} + declare double @llvm.ldexp.f64.i32(double, i32) #0 declare float @llvm.ldexp.f32.i32(float, i32) #0 declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>) #0 diff --git a/llvm/test/CodeGen/X86/llvm.frexp.ll b/llvm/test/CodeGen/X86/llvm.frexp.ll index 83840dd85c533..8e94038df4bee 100644 --- a/llvm/test/CodeGen/X86/llvm.frexp.ll +++ b/llvm/test/CodeGen/X86/llvm.frexp.ll @@ -600,6 +600,139 @@ define i32 @test_frexp_f64_i32_only_use_exp(double %a) nounwind { ; ret <2 x i32> %result.1 ; } +define { fp128, i32 } @test_frexp_f128_i32(fp128 %a) nounwind { +; X64-LABEL: test_frexp_f128_i32: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; X64-NEXT: callq frexpl@PLT +; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax +; X64-NEXT: popq %rcx +; X64-NEXT: retq +; +; WIN32-LABEL: test_frexp_f128_i32: +; WIN32: # %bb.0: +; WIN32-NEXT: pushl %ebp +; WIN32-NEXT: movl %esp, %ebp +; WIN32-NEXT: pushl %ebx +; WIN32-NEXT: pushl %edi +; WIN32-NEXT: pushl %esi +; WIN32-NEXT: andl $-16, %esp +; WIN32-NEXT: subl $48, %esp +; WIN32-NEXT: movl 8(%ebp), %esi +; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax +; WIN32-NEXT: leal {{[0-9]+}}(%esp), %ecx +; WIN32-NEXT: pushl %eax +; WIN32-NEXT: pushl 24(%ebp) +; WIN32-NEXT: pushl 20(%ebp) +; WIN32-NEXT: pushl 16(%ebp) +; WIN32-NEXT: pushl 12(%ebp) +; WIN32-NEXT: pushl %ecx +; WIN32-NEXT: calll _frexpl +; WIN32-NEXT: addl $24, %esp +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebx +; WIN32-NEXT: movl %ebx, 12(%esi) +; WIN32-NEXT: movl %edi, 8(%esi) +; WIN32-NEXT: movl %edx, 4(%esi) +; WIN32-NEXT: movl %ecx, (%esi) +; WIN32-NEXT: movl %eax, 16(%esi) +; WIN32-NEXT: movl %esi, %eax +; WIN32-NEXT: leal -12(%ebp), %esp +; WIN32-NEXT: popl %esi +; WIN32-NEXT: popl %edi +; WIN32-NEXT: popl %ebx +; WIN32-NEXT: popl %ebp +; WIN32-NEXT: retl + %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a) + ret { fp128, i32 } %result +} + +define fp128 @test_frexp_f128_i32_only_use_fract(fp128 %a) nounwind { +; X64-LABEL: test_frexp_f128_i32_only_use_fract: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; X64-NEXT: callq frexpl@PLT +; X64-NEXT: popq %rax +; X64-NEXT: retq +; +; WIN32-LABEL: test_frexp_f128_i32_only_use_fract: +; WIN32: # %bb.0: +; WIN32-NEXT: pushl %ebp +; WIN32-NEXT: movl %esp, %ebp +; WIN32-NEXT: pushl %edi +; WIN32-NEXT: pushl %esi +; WIN32-NEXT: andl $-16, %esp +; WIN32-NEXT: subl $32, %esp +; WIN32-NEXT: movl 8(%ebp), %esi +; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax +; WIN32-NEXT: movl %esp, %ecx +; WIN32-NEXT: pushl %eax +; WIN32-NEXT: pushl 24(%ebp) +; WIN32-NEXT: pushl 20(%ebp) +; WIN32-NEXT: pushl 16(%ebp) +; WIN32-NEXT: pushl 12(%ebp) +; WIN32-NEXT: pushl %ecx +; WIN32-NEXT: calll _frexpl +; WIN32-NEXT: addl $24, %esp +; WIN32-NEXT: movl (%esp), %eax +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi +; WIN32-NEXT: movl %edi, 12(%esi) +; WIN32-NEXT: movl %edx, 8(%esi) +; WIN32-NEXT: movl %ecx, 4(%esi) +; WIN32-NEXT: movl %eax, (%esi) +; WIN32-NEXT: movl %esi, %eax +; WIN32-NEXT: leal -8(%ebp), %esp +; WIN32-NEXT: popl %esi +; WIN32-NEXT: popl %edi +; WIN32-NEXT: popl %ebp +; WIN32-NEXT: retl + %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a) + %result.0 = extractvalue { fp128, i32 } %result, 0 + ret fp128 %result.0 +} + +define i32 @test_frexp_f128_i32_only_use_exp(fp128 %a) nounwind { +; X64-LABEL: test_frexp_f128_i32_only_use_exp: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; X64-NEXT: callq frexpl@PLT +; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax +; X64-NEXT: popq %rcx +; X64-NEXT: retq +; +; WIN32-LABEL: test_frexp_f128_i32_only_use_exp: +; WIN32: # %bb.0: +; WIN32-NEXT: pushl %ebp +; WIN32-NEXT: movl %esp, %ebp +; WIN32-NEXT: andl $-16, %esp +; WIN32-NEXT: subl $48, %esp +; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax +; WIN32-NEXT: leal {{[0-9]+}}(%esp), %ecx +; WIN32-NEXT: pushl %eax +; WIN32-NEXT: pushl 20(%ebp) +; WIN32-NEXT: pushl 16(%ebp) +; WIN32-NEXT: pushl 12(%ebp) +; WIN32-NEXT: pushl 8(%ebp) +; WIN32-NEXT: pushl %ecx +; WIN32-NEXT: calll _frexpl +; WIN32-NEXT: addl $24, %esp +; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax +; WIN32-NEXT: movl %ebp, %esp +; WIN32-NEXT: popl %ebp +; WIN32-NEXT: retl + %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a) + %result.0 = extractvalue { fp128, i32 } %result, 1 + ret i32 %result.0 +} + declare { float, i32 } @llvm.frexp.f32.i32(float) #0 declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>) #0 declare { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float>) #0 From 81961ef78f016f18a1c447a13d70da5acdb3dbe8 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 12 Jul 2025 21:34:58 +0000 Subject: [PATCH 2/2] Update test without cfi --- llvm/test/CodeGen/X86/ldexp.ll | 6 ------ 1 file changed, 6 deletions(-) diff --git a/llvm/test/CodeGen/X86/ldexp.ll b/llvm/test/CodeGen/X86/ldexp.ll index c2126250deeca..01dd80961ed64 100644 --- a/llvm/test/CodeGen/X86/ldexp.ll +++ b/llvm/test/CodeGen/X86/ldexp.ll @@ -565,18 +565,12 @@ define fp128 @ldexp_f128(fp128 %arg0, i32 %arg1) nounwind { ; WIN64-LABEL: ldexp_f128: ; WIN64: # %bb.0: ; WIN64-NEXT: subq $56, %rsp -; WIN64-NEXT: .seh_stackalloc 56 -; WIN64-NEXT: .seh_endprologue ; WIN64-NEXT: movaps (%rcx), %xmm0 ; WIN64-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp) ; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rcx ; WIN64-NEXT: callq ldexpl -; WIN64-NEXT: nop -; WIN64-NEXT: .seh_startepilogue ; WIN64-NEXT: addq $56, %rsp -; WIN64-NEXT: .seh_endepilogue ; WIN64-NEXT: retq -; WIN64-NEXT: .seh_endproc ; ; WIN32-LABEL: ldexp_f128: ; WIN32: # %bb.0: