[llvm] [X86][AArch64][SPIRV] add more tests for `ldexp`/`frexp` (PR #208462)
Folkert de Vries via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 9 09:20:55 PDT 2026
https://github.com/folkertdev updated https://github.com/llvm/llvm-project/pull/208462
>From 4a0e12e73f424fcdb5ef59b14aa25a0400436ba2 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Thu, 9 Jul 2026 13:43:48 +0200
Subject: [PATCH 1/3] don't expand frexp on SPIRV
it has an actual intrinsic for it
---
llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp | 3 +
.../CodeGen/SPIRV/llvm-intrinsics/frexp.ll | 87 +++++++++++++++++--
2 files changed, 84 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
index eb16c9a314a23..8342a1de7ec7a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp
@@ -35,6 +35,9 @@ SPIRVTargetLowering::SPIRVTargetLowering(const TargetMachine &TM,
// consider 128-bit OpTypeInt as valid either.
setMaxAtomicSizeInBitsSupported(64);
setMinCmpXchgSizeInBits(8);
+
+ for (MVT VT : {MVT::f16, MVT::f32, MVT::f64})
+ setOperationAction(ISD::FFREXP, VT, Legal);
}
// Returns true of the types logically match, as defined in
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/frexp.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/frexp.ll
index f1d030352fa59..8b02dbd32bc63 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/frexp.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/frexp.ll
@@ -18,6 +18,19 @@
; CHECK-DAG: %[[#const_composite2:]] = OpConstantComposite %[[#vec4_float_type]] %[[#const_16:]] %[[#const_neg32:]] %[[#const_0:]] %[[#const_9999:]]
; CHECK-DAG: %[[#float_64_type:]] = OpTypeFloat 64
; CHECK-DAG: %[[#vec2_double_type:]] = OpTypeVector %[[#float_64_type]] 2
+; CHECK-DAG: %[[#void_type:]] = OpTypeVoid
+; CHECK-DAG: %[[#const_1:]] = OpConstant %[[#int_32_type]] 1
+; CHECK-DAG: %[[#int_null:]] = OpConstantNull %[[#int_32_type]]
+; CHECK-DAG: %[[#float_16_type:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#struct_f16_i32:]] = OpTypeStruct %[[#float_16_type]] %[[#int_32_type]]
+; CHECK-DAG: %[[#fn_ptr_type_struct_f16:]] = OpTypePointer Function %[[#struct_f16_i32]]
+; CHECK-DAG: %[[#fn_ptr_type_f16:]] = OpTypePointer Function %[[#float_16_type]]
+; CHECK-DAG: %[[#struct_f32_i32:]] = OpTypeStruct %[[#float_32_type]] %[[#int_32_type]]
+; CHECK-DAG: %[[#fn_ptr_type_struct_f32:]] = OpTypePointer Function %[[#struct_f32_i32]]
+; CHECK-DAG: %[[#fn_ptr_type_f32:]] = OpTypePointer Function %[[#float_32_type]]
+; CHECK-DAG: %[[#struct_f64_i32:]] = OpTypeStruct %[[#float_64_type]] %[[#int_32_type]]
+; CHECK-DAG: %[[#fn_ptr_type_struct_f64:]] = OpTypePointer Function %[[#struct_f64_i32]]
+; CHECK-DAG: %[[#fn_ptr_type_f64:]] = OpTypePointer Function %[[#float_64_type]]
; CHECK: %[[#]] = OpFunctionParameter %[[#float_32_type]]
; CHECK: %[[#var1:]] = OpVariable %[[#fn_ptr_type_i32]] Function
@@ -106,9 +119,71 @@ define <2 x double> @frexp_frexp_vector(<2 x double> %x) {
ret <2 x double> %f_part
}
-declare { float, i32 } @llvm.frexp.f32.i32(float)
-declare { double, i32 } @llvm.frexp.f64.i32(double)
-declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>)
-declare { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float>)
-declare { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double>)
-declare { float, i8 } @llvm.frexp.f32.i8(float)
+; CHECK: %[[#out_param_f16:]] = OpFunctionParameter %[[#fn_ptr_type_struct_f16]]
+; CHECK: %[[#x_var_f16:]] = OpFunctionParameter %[[#float_16_type]]
+; CHECK: %[[#var_f16:]] = OpVariable %[[#fn_ptr_type_i32]] Function
+; CHECK: %[[#extinst_f16:]] = OpExtInst %[[#float_16_type]] %[[#extinst_id]] frexp %[[#x_var_f16]] %[[#var_f16]]
+; CHECK: %[[#exp_load_f16:]] = OpLoad %[[#int_32_type]] %[[#var_f16]]
+; CHECK: %[[#mantissa_ptr_f16:]] = OpInBoundsPtrAccessChain %[[#fn_ptr_type_f16]] %[[#out_param_f16]] %[[#int_null]] %[[#int_null]]
+; CHECK: %[[#exp_ptr_f16:]] = OpInBoundsPtrAccessChain %[[#fn_ptr_type_i32]] %[[#out_param_f16]] %[[#int_null]] %[[#const_1]]
+; CHECK: OpStore %[[#mantissa_ptr_f16]] %[[#extinst_f16]] Aligned 2
+; CHECK: OpStore %[[#exp_ptr_f16]] %[[#exp_load_f16]] Aligned 4
+; CHECK: OpReturn
+define void @frexp_f16(ptr %out, half %x) {
+ %ret = call { half, i32 } @llvm.frexp.f16.i32(half %x)
+
+ %mantissa.ptr = getelementptr inbounds { half, i32 }, ptr %out, i32 0, i32 0
+ %exp.ptr = getelementptr inbounds { half, i32 }, ptr %out, i32 0, i32 1
+ %mantissa = extractvalue { half, i32 } %ret, 0
+ %exp = extractvalue { half, i32 } %ret, 1
+
+ store half %mantissa, ptr %mantissa.ptr
+ store i32 %exp, ptr %exp.ptr
+ ret void
+}
+
+; CHECK: %[[#out_param_f32:]] = OpFunctionParameter %[[#fn_ptr_type_struct_f32]]
+; CHECK: %[[#x_var_f32:]] = OpFunctionParameter %[[#float_32_type]]
+; CHECK: %[[#var_f32:]] = OpVariable %[[#fn_ptr_type_i32]] Function
+; CHECK: %[[#extinst_f32:]] = OpExtInst %[[#float_32_type]] %[[#extinst_id]] frexp %[[#x_var_f32]] %[[#var_f32]]
+; CHECK: %[[#exp_load_f32:]] = OpLoad %[[#int_32_type]] %[[#var_f32]]
+; CHECK: %[[#mantissa_ptr_f32:]] = OpInBoundsPtrAccessChain %[[#fn_ptr_type_f32]] %[[#out_param_f32]] %[[#int_null]] %[[#int_null]]
+; CHECK: %[[#exp_ptr_f32:]] = OpInBoundsPtrAccessChain %[[#fn_ptr_type_i32]] %[[#out_param_f32]] %[[#int_null]] %[[#const_1]]
+; CHECK: OpStore %[[#mantissa_ptr_f32]] %[[#extinst_f32]] Aligned 4
+; CHECK: OpStore %[[#exp_ptr_f32]] %[[#exp_load_f32]] Aligned 4
+; CHECK: OpReturn
+define void @frexp_f32(ptr %out, float %x) {
+ %ret = call { float, i32 } @llvm.frexp.f32.i32(float %x)
+
+ %mantissa.ptr = getelementptr inbounds { float, i32 }, ptr %out, i32 0, i32 0
+ %exp.ptr = getelementptr inbounds { float, i32 }, ptr %out, i32 0, i32 1
+ %mantissa = extractvalue { float, i32 } %ret, 0
+ %exp = extractvalue { float, i32 } %ret, 1
+
+ store float %mantissa, ptr %mantissa.ptr
+ store i32 %exp, ptr %exp.ptr
+ ret void
+}
+
+; CHECK: %[[#out_param_f64:]] = OpFunctionParameter %[[#fn_ptr_type_struct_f64]]
+; CHECK: %[[#x_var_f64:]] = OpFunctionParameter %[[#float_64_type]]
+; CHECK: %[[#var_f64:]] = OpVariable %[[#fn_ptr_type_i32]] Function
+; CHECK: %[[#extinst_f64:]] = OpExtInst %[[#float_64_type]] %[[#extinst_id]] frexp %[[#x_var_f64]] %[[#var_f64]]
+; CHECK: %[[#exp_load_f64:]] = OpLoad %[[#int_32_type]] %[[#var_f64]]
+; CHECK: %[[#mantissa_ptr_f64:]] = OpInBoundsPtrAccessChain %[[#fn_ptr_type_f64]] %[[#out_param_f64]] %[[#int_null]] %[[#int_null]]
+; CHECK: %[[#exp_ptr_f64:]] = OpInBoundsPtrAccessChain %[[#fn_ptr_type_i32]] %[[#out_param_f64]] %[[#int_null]] %[[#const_1]]
+; CHECK: OpStore %[[#mantissa_ptr_f64]] %[[#extinst_f64]] Aligned 8
+; CHECK: OpStore %[[#exp_ptr_f64]] %[[#exp_load_f64]] Aligned 4
+; CHECK: OpReturn
+define void @frexp_f64(ptr %out, double %x) {
+ %ret = call { double, i32 } @llvm.frexp.f64.i32(double %x)
+
+ %mantissa.ptr = getelementptr inbounds { double, i32 }, ptr %out, i32 0, i32 0
+ %exp.ptr = getelementptr inbounds { double, i32 }, ptr %out, i32 0, i32 1
+ %mantissa = extractvalue { double, i32 } %ret, 0
+ %exp = extractvalue { double, i32 } %ret, 1
+
+ store double %mantissa, ptr %mantissa.ptr
+ store i32 %exp, ptr %exp.ptr
+ ret void
+}
>From b3d3b81201bed6e244a0997f193325998363e6d4 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Thu, 9 Jul 2026 15:29:26 +0200
Subject: [PATCH 2/3] add frexp and ldexp f16/bf16 test cases
---
llvm/test/CodeGen/AArch64/ldexp-arm64ec.ll | 8 ++
llvm/test/CodeGen/AArch64/ldexp.ll | 1 -
llvm/test/CodeGen/AArch64/llvm.frexp.ll | 61 +++++++--
llvm/test/CodeGen/X86/ldexp.ll | 139 ++++++++++++---------
llvm/test/CodeGen/X86/llvm.frexp.ll | 59 +++++++--
5 files changed, 185 insertions(+), 83 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/ldexp-arm64ec.ll b/llvm/test/CodeGen/AArch64/ldexp-arm64ec.ll
index 73e24bba98af2..aea37c842cfba 100644
--- a/llvm/test/CodeGen/AArch64/ldexp-arm64ec.ll
+++ b/llvm/test/CodeGen/AArch64/ldexp-arm64ec.ll
@@ -11,6 +11,14 @@ define half @ldexp_f16(half %val, i32 %a) {
ret half %call
}
+; ARM64EC-LABEL: ldexp_bf16 =
+; ARM64EC: fcvt d0, s0
+; ARM64EC: bl "#ldexp"
+define bfloat @ldexp_bf16(bfloat %val, i32 %a) {
+ %call = call bfloat @llvm.ldexp.bf16(bfloat %val, i32 %a)
+ ret bfloat %call
+}
+
; ARM64EC-LABEL: ldexp_f32 =
; ARM64EC: fcvt d0, s0
; ARM64EC: bl "#ldexp"
diff --git a/llvm/test/CodeGen/AArch64/ldexp.ll b/llvm/test/CodeGen/AArch64/ldexp.ll
index a849a398eddb1..a18d61aa2553b 100644
--- a/llvm/test/CodeGen/AArch64/ldexp.ll
+++ b/llvm/test/CodeGen/AArch64/ldexp.ll
@@ -4,7 +4,6 @@
; RUN: llc -mtriple=aarch64-windows-msvc -mattr=+sve < %s -o - | FileCheck -check-prefixes=SVE,SVEWINDOWS %s
; RUN: llc -mtriple=aarch64-windows-msvc < %s -o - | FileCheck -check-prefixes=WINDOWS %s
-
define double @testExp(double %val, i32 %a) {
; SVE-LABEL: testExp:
; SVE: // %bb.0: // %entry
diff --git a/llvm/test/CodeGen/AArch64/llvm.frexp.ll b/llvm/test/CodeGen/AArch64/llvm.frexp.ll
index 12534a1c0114a..2729b9bc233fa 100644
--- a/llvm/test/CodeGen/AArch64/llvm.frexp.ll
+++ b/llvm/test/CodeGen/AArch64/llvm.frexp.ll
@@ -316,6 +316,54 @@ define <2 x i32> @test_frexp_v2f16_v2i32_only_use_exp(<2 x half> %a) nounwind {
ret <2 x i32> %result.1
}
+define { bfloat, i32 } @test_frexp_bf16_i32(bfloat %a) nounwind {
+; CHECK-LABEL: test_frexp_bf16_i32:
+; CHECK: // %bb.0:
+; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT: // kill: def $h0 killed $h0 def $d0
+; CHECK-NEXT: add x0, sp, #12
+; CHECK-NEXT: shll v0.4s, v0.4h, #16
+; CHECK-NEXT: // kill: def $s0 killed $s0 killed $q0
+; CHECK-NEXT: bl frexpf
+; CHECK-NEXT: fmov w9, s0
+; CHECK-NEXT: mov w8, #32767 // =0x7fff
+; CHECK-NEXT: fcmp s0, s0
+; CHECK-NEXT: ldr w0, [sp, #12]
+; CHECK-NEXT: ubfx w10, w9, #16, #1
+; CHECK-NEXT: add w8, w9, w8
+; CHECK-NEXT: orr w9, w9, #0x400000
+; CHECK-NEXT: add w8, w10, w8
+; CHECK-NEXT: csel w8, w9, w8, vs
+; CHECK-NEXT: lsr w8, w8, #16
+; CHECK-NEXT: fmov s0, w8
+; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
+; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
+; CHECK-NEXT: ret
+;
+; WINDOWS-LABEL: test_frexp_bf16_i32:
+; WINDOWS: // %bb.0:
+; WINDOWS-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
+; WINDOWS-NEXT: // kill: def $h0 killed $h0 def $d0
+; WINDOWS-NEXT: add x0, sp, #12
+; WINDOWS-NEXT: shll v0.4s, v0.4h, #16
+; WINDOWS-NEXT: fcvt d0, s0
+; WINDOWS-NEXT: bl frexp
+; WINDOWS-NEXT: fcvtxn s0, d0
+; WINDOWS-NEXT: mov w8, #32767 // =0x7fff
+; WINDOWS-NEXT: ldr w0, [sp, #12]
+; WINDOWS-NEXT: fmov w9, s0
+; WINDOWS-NEXT: ubfx w10, w9, #16, #1
+; WINDOWS-NEXT: add w8, w9, w8
+; WINDOWS-NEXT: add w8, w10, w8
+; WINDOWS-NEXT: lsr w8, w8, #16
+; WINDOWS-NEXT: fmov s0, w8
+; WINDOWS-NEXT: // kill: def $h0 killed $h0 killed $s0
+; WINDOWS-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
+; WINDOWS-NEXT: ret
+ %result = call { bfloat, i32 } @llvm.frexp.bf16.i32(bfloat %a)
+ ret { bfloat, i32 } %result
+}
+
define { <3 x float>, <3 x i32> } @test_frexp_v3f32_v3i32(<3 x float> %a) nounwind {
; CHECK-LABEL: test_frexp_v3f32_v3i32:
; CHECK: // %bb.0:
@@ -1133,17 +1181,4 @@ define <2 x i32> @test_frexp_v2f64_v2i32_only_use_exp(<2 x double> %a) nounwind
ret <2 x i32> %result.1
}
-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
-
-declare { half, i32 } @llvm.frexp.f16.i32(half) #0
-declare { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half>) #0
-
-declare { double, i32 } @llvm.frexp.f64.i32(double) #0
-declare { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double>) #0
-
-declare { half, i16 } @llvm.frexp.f16.i16(half) #0
-declare { <2 x half>, <2 x i16> } @llvm.frexp.v2f16.v2i16(<2 x half>) #0
-
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
diff --git a/llvm/test/CodeGen/X86/ldexp.ll b/llvm/test/CodeGen/X86/ldexp.ll
index 59ec7bfcaa910..b6f2793c4b1f7 100644
--- a/llvm/test/CodeGen/X86/ldexp.ll
+++ b/llvm/test/CodeGen/X86/ldexp.ll
@@ -3,6 +3,89 @@
; RUN: llc -mtriple=x86_64-pc-win32 -verify-machineinstrs < %s | FileCheck -check-prefixes=WIN64 %s
; RUN: llc -mtriple=i386-pc-win32 -verify-machineinstrs < %s | FileCheck -check-prefix=WIN32 %s
+define half @ldexp_f16(i8 zeroext %x) nounwind {
+; X64-LABEL: ldexp_f16:
+; X64: # %bb.0:
+; X64-NEXT: pushq %rax
+; X64-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
+; X64-NEXT: callq ldexpf at PLT
+; X64-NEXT: callq __truncsfhf2 at PLT
+; X64-NEXT: popq %rax
+; X64-NEXT: retq
+;
+; WIN64-LABEL: ldexp_f16:
+; WIN64: # %bb.0:
+; WIN64-NEXT: subq $40, %rsp
+; WIN64-NEXT: movzbl %cl, %edx
+; WIN64-NEXT: movsd {{.*#+}} xmm0 = [1.0E+0,0.0E+0]
+; WIN64-NEXT: callq ldexp
+; WIN64-NEXT: callq __truncdfhf2
+; WIN64-NEXT: addq $40, %rsp
+; WIN64-NEXT: retq
+;
+; WIN32-LABEL: ldexp_f16:
+; WIN32: # %bb.0:
+; WIN32-NEXT: subl $16, %esp
+; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
+; WIN32-NEXT: fld1
+; WIN32-NEXT: fstpl (%esp)
+; WIN32-NEXT: calll _ldexp
+; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT: flds {{[0-9]+}}(%esp)
+; WIN32-NEXT: fstps (%esp)
+; WIN32-NEXT: calll ___truncsfhf2
+; WIN32-NEXT: addl $16, %esp
+; WIN32-NEXT: retl
+ %zext = zext i8 %x to i32
+ %ldexp = call half @llvm.ldexp.f16.i32(half 1.000000e+00, i32 %zext)
+ ret half %ldexp
+}
+
+define bfloat @ldexp_bf16(i8 zeroext %x) nounwind {
+; X64-LABEL: ldexp_bf16:
+; X64: # %bb.0:
+; X64-NEXT: pushq %rax
+; X64-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
+; X64-NEXT: callq ldexpf at PLT
+; X64-NEXT: callq __truncsfbf2 at PLT
+; X64-NEXT: popq %rax
+; X64-NEXT: retq
+;
+; WIN64-LABEL: ldexp_bf16:
+; WIN64: # %bb.0:
+; WIN64-NEXT: subq $40, %rsp
+; WIN64-NEXT: movzbl %cl, %edx
+; WIN64-NEXT: movsd {{.*#+}} xmm0 = [1.0E+0,0.0E+0]
+; WIN64-NEXT: callq ldexp
+; WIN64-NEXT: cvtsd2ss %xmm0, %xmm0
+; WIN64-NEXT: callq __truncsfbf2
+; WIN64-NEXT: addq $40, %rsp
+; WIN64-NEXT: retq
+;
+; WIN32-LABEL: ldexp_bf16:
+; WIN32: # %bb.0:
+; WIN32-NEXT: subl $20, %esp
+; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
+; WIN32-NEXT: fld1
+; WIN32-NEXT: fstpl (%esp)
+; WIN32-NEXT: calll _ldexp
+; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT: flds {{[0-9]+}}(%esp)
+; WIN32-NEXT: fstps (%esp)
+; WIN32-NEXT: calll ___truncsfbf2
+; WIN32-NEXT: # kill: def $ax killed $ax def $eax
+; WIN32-NEXT: shll $16, %eax
+; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
+; WIN32-NEXT: flds {{[0-9]+}}(%esp)
+; WIN32-NEXT: addl $20, %esp
+; WIN32-NEXT: retl
+ %zext = zext i8 %x to i32
+ %ldexp = call bfloat @llvm.ldexp.bf16.i32(bfloat 1.000000e+00, i32 %zext)
+ ret bfloat %ldexp
+}
+
define float @ldexp_f32(i8 zeroext %x) nounwind {
; X64-LABEL: ldexp_f32:
; X64: # %bb.0:
@@ -509,61 +592,5 @@ define <4 x double> @ldexp_v4f64(<4 x double> %val, <4 x i32> %exp) nounwind {
ret <4 x double> %1
}
-define half @ldexp_f16(half %arg0, i32 %arg1) nounwind {
-; X64-LABEL: ldexp_f16:
-; X64: # %bb.0:
-; X64-NEXT: pushq %rbx
-; X64-NEXT: movl %edi, %ebx
-; X64-NEXT: callq __extendhfsf2 at PLT
-; X64-NEXT: movl %ebx, %edi
-; X64-NEXT: callq ldexpf at PLT
-; X64-NEXT: callq __truncsfhf2 at PLT
-; X64-NEXT: popq %rbx
-; X64-NEXT: retq
-;
-; WIN64-LABEL: ldexp_f16:
-; WIN64: # %bb.0:
-; WIN64-NEXT: pushq %rsi
-; WIN64-NEXT: subq $32, %rsp
-; WIN64-NEXT: movl %edx, %esi
-; WIN64-NEXT: callq __extendhfsf2
-; WIN64-NEXT: cvtss2sd %xmm0, %xmm0
-; WIN64-NEXT: movl %esi, %edx
-; WIN64-NEXT: callq ldexp
-; WIN64-NEXT: callq __truncdfhf2
-; WIN64-NEXT: addq $32, %rsp
-; WIN64-NEXT: popq %rsi
-; WIN64-NEXT: retq
-;
-; WIN32-LABEL: ldexp_f16:
-; WIN32: # %bb.0:
-; WIN32-NEXT: pushl %esi
-; WIN32-NEXT: subl $16, %esp
-; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
-; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
-; WIN32-NEXT: movl %eax, (%esp)
-; WIN32-NEXT: calll ___extendhfsf2
-; WIN32-NEXT: movl %esi, {{[0-9]+}}(%esp)
-; WIN32-NEXT: fstpl (%esp)
-; WIN32-NEXT: calll _ldexp
-; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT: flds {{[0-9]+}}(%esp)
-; WIN32-NEXT: fstps (%esp)
-; WIN32-NEXT: calll ___truncsfhf2
-; WIN32-NEXT: addl $16, %esp
-; WIN32-NEXT: popl %esi
-; WIN32-NEXT: retl
- %ldexp = call half @llvm.ldexp.f16.i32(half %arg0, i32 %arg1)
- ret half %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
-declare <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float>, <4 x i32>) #0
-declare <2 x double> @llvm.ldexp.v2f64.v2i32(<2 x double>, <2 x i32>) #0
-declare <4 x double> @llvm.ldexp.v4f64.v4i32(<4 x double>, <4 x i32>) #0
-declare half @llvm.ldexp.f16.i32(half, i32) #0
-
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
diff --git a/llvm/test/CodeGen/X86/llvm.frexp.ll b/llvm/test/CodeGen/X86/llvm.frexp.ll
index 9112c176eaf27..d14d737a5ca29 100644
--- a/llvm/test/CodeGen/X86/llvm.frexp.ll
+++ b/llvm/test/CodeGen/X86/llvm.frexp.ll
@@ -172,6 +172,52 @@ define i32 @test_frexp_f16_i32_only_use_exp(half %a) nounwind {
; ret <2 x i32> %result.1
; }
+define { bfloat, i32 } @test_frexp_bf16_i32(bfloat %a) nounwind {
+; X64-LABEL: test_frexp_bf16_i32:
+; X64: # %bb.0:
+; X64-NEXT: pushq %rax
+; X64-NEXT: pextrw $0, %xmm0, %eax
+; X64-NEXT: shll $16, %eax
+; X64-NEXT: movd %eax, %xmm0
+; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
+; X64-NEXT: callq frexpf at PLT
+; X64-NEXT: callq __truncsfbf2 at PLT
+; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax
+; X64-NEXT: popq %rcx
+; X64-NEXT: retq
+;
+; WIN32-LABEL: test_frexp_bf16_i32:
+; WIN32: # %bb.0:
+; WIN32-NEXT: pushl %esi
+; WIN32-NEXT: subl $28, %esp
+; WIN32-NEXT: flds {{[0-9]+}}(%esp)
+; WIN32-NEXT: fstps (%esp)
+; WIN32-NEXT: calll ___truncsfbf2
+; WIN32-NEXT: # kill: def $ax killed $ax def $eax
+; WIN32-NEXT: leal {{[0-9]+}}(%esp), %ecx
+; WIN32-NEXT: movl %ecx, {{[0-9]+}}(%esp)
+; WIN32-NEXT: shll $16, %eax
+; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
+; WIN32-NEXT: flds {{[0-9]+}}(%esp)
+; WIN32-NEXT: fstpl (%esp)
+; WIN32-NEXT: calll _frexp
+; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT: flds {{[0-9]+}}(%esp)
+; WIN32-NEXT: fstps (%esp)
+; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; WIN32-NEXT: calll ___truncsfbf2
+; WIN32-NEXT: # kill: def $ax killed $ax def $eax
+; WIN32-NEXT: shll $16, %eax
+; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
+; WIN32-NEXT: flds {{[0-9]+}}(%esp)
+; WIN32-NEXT: movl %esi, %eax
+; WIN32-NEXT: addl $28, %esp
+; WIN32-NEXT: popl %esi
+; WIN32-NEXT: retl
+ %result = call { bfloat, i32 } @llvm.frexp.bf16.i32(bfloat %a)
+ ret { bfloat, i32 } %result
+}
+
define { float, i32 } @test_frexp_f32_i32(float %a) nounwind {
; X64-LABEL: test_frexp_f32_i32:
; X64: # %bb.0:
@@ -616,17 +662,4 @@ define { float, i32 } @pr160981() {
; ret <2 x i32> %result.1
; }
-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
-
-declare { half, i32 } @llvm.frexp.f16.i32(half) #0
-declare { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half>) #0
-
-declare { double, i32 } @llvm.frexp.f64.i32(double) #0
-declare { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double>) #0
-
-declare { half, i16 } @llvm.frexp.f16.i16(half) #0
-declare { <2 x half>, <2 x i16> } @llvm.frexp.v2f16.v2i16(<2 x half>) #0
-
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
>From 6dfb7e563027c04ee282a09c1b844fd8e165f2d5 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Thu, 9 Jul 2026 17:42:00 +0200
Subject: [PATCH 3/3] [X86] promote f16 frexp
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 1 +
.../test/CodeGen/X86/float-to-arbitrary-fp.ll | 531 ++++++++----------
llvm/test/CodeGen/X86/llvm.frexp.ll | 82 +--
3 files changed, 256 insertions(+), 358 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 97a406d176a55..bb71d022081c9 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -645,6 +645,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::FROUNDEVEN, VT, Action);
setOperationAction(ISD::FTRUNC, VT, Action);
setOperationAction(ISD::FLDEXP, VT, Action);
+ setOperationAction(ISD::FFREXP, VT, Action);
setOperationAction(ISD::FSINCOSPI, VT, Action);
};
diff --git a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
index 1cdccaf110d30..8076f0a11762c 100644
--- a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
+++ b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
@@ -1858,215 +1858,182 @@ define <2 x i8> @to_f8e4m3fn_v2f16(<2 x half> %x) {
; CHECK-NEXT: .cfi_def_cfa_offset 48
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: .cfi_def_cfa_offset 56
-; CHECK-NEXT: subq $72, %rsp
-; CHECK-NEXT: .cfi_def_cfa_offset 128
+; CHECK-NEXT: subq $88, %rsp
+; CHECK-NEXT: .cfi_def_cfa_offset 144
; CHECK-NEXT: .cfi_offset %rbx, -56
; CHECK-NEXT: .cfi_offset %r12, -48
; CHECK-NEXT: .cfi_offset %r13, -40
; CHECK-NEXT: .cfi_offset %r14, -32
; CHECK-NEXT: .cfi_offset %r15, -24
; CHECK-NEXT: .cfi_offset %rbp, -16
-; CHECK-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
; CHECK-NEXT: callq __extendhfsf2 at PLT
-; CHECK-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill
+; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT: callq frexpf at PLT
+; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
+; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT: movl $2, %ebx
+; CHECK-NEXT: movl $2, %ebp
+; CHECK-NEXT: subl %eax, %ebp
+; CHECK-NEXT: cmpw $15, %bp
+; CHECK-NEXT: movl $15, %eax
+; CHECK-NEXT: cmovael %eax, %ebp
+; CHECK-NEXT: cmpw $1, %bp
+; CHECK-NEXT: movl %ebp, %r14d
+; CHECK-NEXT: adcl $-1, %r14d
; CHECK-NEXT: callq __truncsfhf2 at PLT
-; CHECK-NEXT: pextrw $0, %xmm0, %r12d
-; CHECK-NEXT: movl %r12d, %eax
-; CHECK-NEXT: andl $31744, %eax # imm = 0x7C00
+; CHECK-NEXT: pextrw $0, %xmm0, %r13d
+; CHECK-NEXT: movl %r13d, %eax
+; CHECK-NEXT: andl $1023, %eax # imm = 0x3FF
+; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT: leal 1024(%rax), %edi
+; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: movl %r14d, %ecx
+; CHECK-NEXT: shrl %cl, %eax
+; CHECK-NEXT: movl $1, %r15d
+; CHECK-NEXT: movl $1, %edx
+; CHECK-NEXT: shll %cl, %edx
+; CHECK-NEXT: decl %edx
+; CHECK-NEXT: xorl %esi, %esi
+; CHECK-NEXT: movl %edi, %r14d
+; CHECK-NEXT: testw %dx, %r14w
+; CHECK-NEXT: setne %sil
+; CHECK-NEXT: movl %ebp, %ecx
+; CHECK-NEXT: shrl %cl, %r14d
+; CHECK-NEXT: movl %r14d, %r12d
+; CHECK-NEXT: andl $1, %r12d
+; CHECK-NEXT: orl %esi, %r12d
+; CHECK-NEXT: andl %eax, %r12d
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: cmpw $1, %bp
; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT: pextrw $0, %xmm0, %r15d
-; CHECK-NEXT: movl %r15d, %ecx
-; CHECK-NEXT: andl $32767, %ecx # imm = 0x7FFF
-; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400
-; CHECK-NEXT: cmovael %r15d, %r12d
-; CHECK-NEXT: cmovael %ecx, %eax
-; CHECK-NEXT: shrl $10, %eax
-; CHECK-NEXT: leal -12(%rax), %edx
-; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400
; CHECK-NEXT: psrld $16, %xmm0
; CHECK-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; CHECK-NEXT: cmovael %eax, %edx
-; CHECK-NEXT: addl $-14, %edx
-; CHECK-NEXT: andl $33791, %r12d # imm = 0x83FF
-; CHECK-NEXT: orl $14336, %r12d # imm = 0x3800
-; CHECK-NEXT: addl $-31744, %ecx # imm = 0x8400
-; CHECK-NEXT: movzwl %cx, %eax
-; CHECK-NEXT: xorl %ecx, %ecx
-; CHECK-NEXT: cmpl $33792, %eax # imm = 0x8400
-; CHECK-NEXT: cmovbel %ecx, %edx
-; CHECK-NEXT: movq %rdx, %r14
-; CHECK-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT: cmovbel %r15d, %r12d
+; CHECK-NEXT: cmovbl %eax, %r12d
; CHECK-NEXT: callq __extendhfsf2 at PLT
-; CHECK-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill
+; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT: callq frexpf at PLT
+; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
+; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT: subl %eax, %ebx
+; CHECK-NEXT: cmpw $15, %bx
+; CHECK-NEXT: movl $15, %eax
+; CHECK-NEXT: cmovael %eax, %ebx
+; CHECK-NEXT: cmpw $1, %bx
+; CHECK-NEXT: movl %ebx, %ebp
+; CHECK-NEXT: adcl $-1, %ebp
; CHECK-NEXT: callq __truncsfhf2 at PLT
-; CHECK-NEXT: pextrw $0, %xmm0, %ebp
-; CHECK-NEXT: movl %ebp, %eax
-; CHECK-NEXT: andl $31744, %eax # imm = 0x7C00
-; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT: pextrw $0, %xmm0, %ebx
-; CHECK-NEXT: movl %ebx, %r9d
-; CHECK-NEXT: andl $32767, %r9d # imm = 0x7FFF
-; CHECK-NEXT: cmpl $1024, %r9d # imm = 0x400
-; CHECK-NEXT: cmovael %ebx, %ebp
-; CHECK-NEXT: cmovael %r9d, %eax
-; CHECK-NEXT: shrl $10, %eax
-; CHECK-NEXT: leal -12(%rax), %esi
-; CHECK-NEXT: cmpl $1024, %r9d # imm = 0x400
-; CHECK-NEXT: cmovael %eax, %esi
-; CHECK-NEXT: movl $2, %eax
-; CHECK-NEXT: movl $2, %edx
-; CHECK-NEXT: subl %r14d, %edx
-; CHECK-NEXT: cmpw $15, %dx
-; CHECK-NEXT: movl $15, %r13d
-; CHECK-NEXT: cmovael %r13d, %edx
-; CHECK-NEXT: cmpw $1, %dx
-; CHECK-NEXT: movl %edx, %ecx
-; CHECK-NEXT: adcl $-1, %ecx
-; CHECK-NEXT: movl %r12d, %r10d
-; CHECK-NEXT: andl $1023, %r10d # imm = 0x3FF
-; CHECK-NEXT: leal 1024(%r10), %edi
-; CHECK-NEXT: movl %edi, %r14d
-; CHECK-NEXT: shrl %cl, %r14d
-; CHECK-NEXT: movl $1, %r8d
-; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT: shll %cl, %r8d
-; CHECK-NEXT: decl %r8d
-; CHECK-NEXT: xorl %r11d, %r11d
-; CHECK-NEXT: testw %r8w, %di
-; CHECK-NEXT: setne %r11b
-; CHECK-NEXT: movl %edx, %ecx
-; CHECK-NEXT: shrl %cl, %edi
-; CHECK-NEXT: movl %edi, %r8d
-; CHECK-NEXT: andl $1, %r8d
-; CHECK-NEXT: orl %r11d, %r8d
-; CHECK-NEXT: movl $1, %r11d
-; CHECK-NEXT: andl %r14d, %r8d
-; CHECK-NEXT: cmpw $1, %dx
-; CHECK-NEXT: movl $0, %edx
-; CHECK-NEXT: cmovbl %edx, %r8d
-; CHECK-NEXT: addl $-14, %esi
-; CHECK-NEXT: andl $33791, %ebp # imm = 0x83FF
-; CHECK-NEXT: orl $14336, %ebp # imm = 0x3800
-; CHECK-NEXT: addl $-31744, %r9d # imm = 0x8400
-; CHECK-NEXT: movzwl %r9w, %ecx
-; CHECK-NEXT: cmpl $33792, %ecx # imm = 0x8400
-; CHECK-NEXT: cmovbel %edx, %esi
-; CHECK-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT: cmovbel %ebx, %ebp
-; CHECK-NEXT: subl %esi, %eax
-; CHECK-NEXT: cmpw $15, %ax
-; CHECK-NEXT: cmovael %r13d, %eax
-; CHECK-NEXT: cmpw $1, %ax
-; CHECK-NEXT: movl %eax, %ecx
-; CHECK-NEXT: adcl $-1, %ecx
-; CHECK-NEXT: movl %ebp, %edx
+; CHECK-NEXT: pextrw $0, %xmm0, %eax
+; CHECK-NEXT: movl %eax, %edx
; CHECK-NEXT: andl $1023, %edx # imm = 0x3FF
-; CHECK-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT: leal 1024(%rdx), %r13d
-; CHECK-NEXT: movl %r13d, %edx
-; CHECK-NEXT: shrl %cl, %edx
-; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT: shll %cl, %r11d
-; CHECK-NEXT: decl %r11d
-; CHECK-NEXT: xorl %r9d, %r9d
-; CHECK-NEXT: testw %r11w, %r13w
-; CHECK-NEXT: setne %r9b
-; CHECK-NEXT: movl %eax, %ecx
-; CHECK-NEXT: shrl %cl, %r13d
-; CHECK-NEXT: movl %r13d, %r14d
-; CHECK-NEXT: andl $1, %r14d
-; CHECK-NEXT: orl %r9d, %r14d
-; CHECK-NEXT: andl %edx, %r14d
-; CHECK-NEXT: cmpw $1, %ax
-; CHECK-NEXT: movl $0, %ecx
-; CHECK-NEXT: cmovbl %ecx, %r14d
-; CHECK-NEXT: addl %edi, %r8d
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: cmpw $8, %r8w
-; CHECK-NEXT: cmovgel %ecx, %r8d
-; CHECK-NEXT: movl $0, %esi
-; CHECK-NEXT: setge %al
-; CHECK-NEXT: shrl $8, %r15d
-; CHECK-NEXT: andl $128, %r15d
-; CHECK-NEXT: leal (%r15,%rax,8), %eax
-; CHECK-NEXT: orl %r8d, %eax
-; CHECK-NEXT: shrl $7, %r10d
-; CHECK-NEXT: movl %r10d, %ecx
+; CHECK-NEXT: leal 1024(%rdx), %esi
+; CHECK-NEXT: movl %esi, %edi
+; CHECK-NEXT: movl %ebp, %ecx
+; CHECK-NEXT: shrl %cl, %edi
+; CHECK-NEXT: shll %cl, %r15d
+; CHECK-NEXT: decl %r15d
+; CHECK-NEXT: xorl %r8d, %r8d
+; CHECK-NEXT: testw %r15w, %si
+; CHECK-NEXT: setne %r8b
+; CHECK-NEXT: movl %ebx, %ecx
+; CHECK-NEXT: shrl %cl, %esi
+; CHECK-NEXT: movl %esi, %ecx
; CHECK-NEXT: andl $1, %ecx
-; CHECK-NEXT: xorl %edx, %edx
-; CHECK-NEXT: testb $63, %r12b
-; CHECK-NEXT: setne %dl
-; CHECK-NEXT: orl %ecx, %edx
-; CHECK-NEXT: shrl $6, %r12d
-; CHECK-NEXT: andl %edx, %r12d
-; CHECK-NEXT: addl %r10d, %r12d
-; CHECK-NEXT: xorl %ecx, %ecx
+; CHECK-NEXT: orl %r8d, %ecx
+; CHECK-NEXT: andl %edi, %ecx
+; CHECK-NEXT: cmpw $1, %bx
+; CHECK-NEXT: movl $0, %r8d
+; CHECK-NEXT: cmovbl %r8d, %ecx
+; CHECK-NEXT: addl %r14d, %r12d
+; CHECK-NEXT: xorl %edi, %edi
; CHECK-NEXT: cmpw $8, %r12w
-; CHECK-NEXT: cmovgel %esi, %r12d
-; CHECK-NEXT: setge %cl
-; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload
-; CHECK-NEXT: leal (%rsi,%rcx), %edx
-; CHECK-NEXT: leal 48(,%rdx,8), %edx
-; CHECK-NEXT: orl %r15d, %r12d
-; CHECK-NEXT: orl %edx, %r12d
-; CHECK-NEXT: leal 6(%rsi,%rcx), %ecx
-; CHECK-NEXT: testw %cx, %cx
-; CHECK-NEXT: cmovlel %eax, %r12d
-; CHECK-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT: callq __extendhfsf2 at PLT
-; CHECK-NEXT: xorps %xmm1, %xmm1
-; CHECK-NEXT: ucomiss %xmm1, %xmm0
-; CHECK-NEXT: cmovnel %r12d, %r15d
-; CHECK-NEXT: cmovpl %r12d, %r15d
-; CHECK-NEXT: movl $127, %r12d
-; CHECK-NEXT: cmovpl %r12d, %r15d
-; CHECK-NEXT: movzbl %r15b, %r15d
-; CHECK-NEXT: addl %r13d, %r14d
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: cmpw $8, %r14w
-; CHECK-NEXT: movl $0, %edi
-; CHECK-NEXT: cmovgel %edi, %r14d
-; CHECK-NEXT: setge %al
-; CHECK-NEXT: shrl $8, %ebx
-; CHECK-NEXT: andl $128, %ebx
-; CHECK-NEXT: leal (%rbx,%rax,8), %eax
-; CHECK-NEXT: orl %r14d, %eax
-; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload
+; CHECK-NEXT: cmovgel %r8d, %r12d
+; CHECK-NEXT: movl $0, %r11d
+; CHECK-NEXT: setge %dil
+; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT: pextrw $0, %xmm0, %r8d
+; CHECK-NEXT: shrl $8, %r8d
+; CHECK-NEXT: andl $128, %r8d
+; CHECK-NEXT: leal (%r8,%rdi,8), %edi
+; CHECK-NEXT: orl %r12d, %edi
+; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload
+; CHECK-NEXT: shrl $7, %r10d
+; CHECK-NEXT: movl %r10d, %r9d
+; CHECK-NEXT: movq %r10, %rbx
+; CHECK-NEXT: andl $1, %r9d
+; CHECK-NEXT: xorl %r10d, %r10d
+; CHECK-NEXT: testb $63, %r13b
+; CHECK-NEXT: setne %r10b
+; CHECK-NEXT: orl %r9d, %r10d
+; CHECK-NEXT: shrl $6, %r13d
+; CHECK-NEXT: andl %r10d, %r13d
+; CHECK-NEXT: addl %ebx, %r13d
+; CHECK-NEXT: xorl %r9d, %r9d
+; CHECK-NEXT: cmpw $8, %r13w
+; CHECK-NEXT: cmovgel %r11d, %r13d
+; CHECK-NEXT: setge %r9b
+; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload
+; CHECK-NEXT: leal (%rbx,%r9), %r10d
+; CHECK-NEXT: leal 48(,%r10,8), %r10d
+; CHECK-NEXT: orl %r8d, %r13d
+; CHECK-NEXT: orl %r10d, %r13d
+; CHECK-NEXT: leal 6(%rbx,%r9), %r9d
+; CHECK-NEXT: testw %r9w, %r9w
+; CHECK-NEXT: cmovlel %edi, %r13d
+; CHECK-NEXT: pxor %xmm0, %xmm0
+; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Reload
+; CHECK-NEXT: # xmm1 = mem[0],zero,zero,zero
+; CHECK-NEXT: ucomiss %xmm0, %xmm1
+; CHECK-NEXT: cmovnel %r13d, %r8d
+; CHECK-NEXT: cmovpl %r13d, %r8d
+; CHECK-NEXT: movl $127, %edi
+; CHECK-NEXT: cmovpl %edi, %r8d
+; CHECK-NEXT: movzbl %r8b, %r8d
+; CHECK-NEXT: addl %esi, %ecx
+; CHECK-NEXT: xorl %r9d, %r9d
+; CHECK-NEXT: cmpw $8, %cx
+; CHECK-NEXT: cmovgel %r11d, %ecx
+; CHECK-NEXT: setge %r9b
+; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT: pextrw $0, %xmm1, %esi
+; CHECK-NEXT: shrl $8, %esi
+; CHECK-NEXT: andl $128, %esi
+; CHECK-NEXT: leal (%rsi,%r9,8), %r9d
+; CHECK-NEXT: orl %ecx, %r9d
; CHECK-NEXT: shrl $7, %edx
; CHECK-NEXT: movl %edx, %ecx
-; CHECK-NEXT: movq %rdx, %rsi
; CHECK-NEXT: andl $1, %ecx
-; CHECK-NEXT: xorl %edx, %edx
-; CHECK-NEXT: testb $63, %bpl
-; CHECK-NEXT: setne %dl
-; CHECK-NEXT: orl %ecx, %edx
-; CHECK-NEXT: shrl $6, %ebp
-; CHECK-NEXT: andl %edx, %ebp
-; CHECK-NEXT: addl %esi, %ebp
+; CHECK-NEXT: xorl %r10d, %r10d
+; CHECK-NEXT: testb $63, %al
+; CHECK-NEXT: setne %r10b
+; CHECK-NEXT: orl %ecx, %r10d
+; CHECK-NEXT: shrl $6, %eax
+; CHECK-NEXT: andl %r10d, %eax
+; CHECK-NEXT: addl %edx, %eax
; CHECK-NEXT: xorl %ecx, %ecx
-; CHECK-NEXT: cmpw $8, %bp
-; CHECK-NEXT: cmovgel %edi, %ebp
+; CHECK-NEXT: cmpw $8, %ax
+; CHECK-NEXT: cmovgel %r11d, %eax
; CHECK-NEXT: setge %cl
-; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload
-; CHECK-NEXT: leal (%rsi,%rcx), %edx
+; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload
+; CHECK-NEXT: leal (%r10,%rcx), %edx
; CHECK-NEXT: leal 48(,%rdx,8), %edx
-; CHECK-NEXT: orl %ebx, %ebp
-; CHECK-NEXT: orl %edx, %ebp
-; CHECK-NEXT: leal 6(%rsi,%rcx), %ecx
+; CHECK-NEXT: orl %esi, %eax
+; CHECK-NEXT: orl %edx, %eax
+; CHECK-NEXT: leal 6(%r10,%rcx), %ecx
; CHECK-NEXT: testw %cx, %cx
-; CHECK-NEXT: cmovlel %eax, %ebp
-; CHECK-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT: callq __extendhfsf2 at PLT
-; CHECK-NEXT: xorps %xmm1, %xmm1
-; CHECK-NEXT: ucomiss %xmm1, %xmm0
-; CHECK-NEXT: cmovnel %ebp, %ebx
-; CHECK-NEXT: cmovpl %ebp, %ebx
-; CHECK-NEXT: cmovpl %r12d, %ebx
-; CHECK-NEXT: shll $8, %ebx
-; CHECK-NEXT: orl %r15d, %ebx
-; CHECK-NEXT: movd %ebx, %xmm0
-; CHECK-NEXT: addq $72, %rsp
+; CHECK-NEXT: cmovlel %r9d, %eax
+; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Reload
+; CHECK-NEXT: # xmm1 = mem[0],zero,zero,zero
+; CHECK-NEXT: ucomiss %xmm0, %xmm1
+; CHECK-NEXT: cmovnel %eax, %esi
+; CHECK-NEXT: cmovpl %eax, %esi
+; CHECK-NEXT: cmovpl %edi, %esi
+; CHECK-NEXT: shll $8, %esi
+; CHECK-NEXT: orl %r8d, %esi
+; CHECK-NEXT: movd %esi, %xmm0
+; CHECK-NEXT: addq $88, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 56
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: .cfi_def_cfa_offset 48
@@ -2102,121 +2069,105 @@ define i8 @to_f8e5m2_from_f16(half %x) {
; CHECK-NEXT: .cfi_offset %rbx, -32
; CHECK-NEXT: .cfi_offset %r14, -24
; CHECK-NEXT: .cfi_offset %rbp, -16
-; CHECK-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
; CHECK-NEXT: callq __extendhfsf2 at PLT
-; CHECK-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill
+; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT: callq frexpf at PLT
+; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r14d
+; CHECK-NEXT: movl $-5, %eax
+; CHECK-NEXT: subl %r14d, %eax
+; CHECK-NEXT: cmpw $15, %ax
+; CHECK-NEXT: movl $15, %ebx
+; CHECK-NEXT: cmovbl %eax, %ebx
+; CHECK-NEXT: cmpw $1, %bx
+; CHECK-NEXT: movl %ebx, %ebp
+; CHECK-NEXT: adcl $-1, %ebp
; CHECK-NEXT: callq __truncsfhf2 at PLT
-; CHECK-NEXT: pextrw $0, %xmm0, %edx
-; CHECK-NEXT: movl %edx, %eax
-; CHECK-NEXT: andl $31744, %eax # imm = 0x7C00
-; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT: pextrw $0, %xmm0, %ebx
-; CHECK-NEXT: movl %ebx, %ecx
-; CHECK-NEXT: andl $32767, %ecx # imm = 0x7FFF
-; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400
-; CHECK-NEXT: cmovael %ebx, %edx
-; CHECK-NEXT: cmovael %ecx, %eax
-; CHECK-NEXT: shrl $10, %eax
-; CHECK-NEXT: leal -12(%rax), %esi
-; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400
-; CHECK-NEXT: cmovael %eax, %esi
-; CHECK-NEXT: addl $-14, %esi
-; CHECK-NEXT: andl $33791, %edx # imm = 0x83FF
-; CHECK-NEXT: orl $14336, %edx # imm = 0x3800
-; CHECK-NEXT: addl $-31744, %ecx # imm = 0x8400
-; CHECK-NEXT: movzwl %cx, %eax
-; CHECK-NEXT: xorl %edi, %edi
-; CHECK-NEXT: cmpl $33792, %eax # imm = 0x8400
-; CHECK-NEXT: cmovbel %edi, %esi
-; CHECK-NEXT: cmovbel %ebx, %edx
-; CHECK-NEXT: movl $-5, %ecx
-; CHECK-NEXT: subl %esi, %ecx
-; CHECK-NEXT: cmpw $15, %cx
-; CHECK-NEXT: movl $15, %eax
-; CHECK-NEXT: cmovbl %ecx, %eax
-; CHECK-NEXT: cmpw $1, %ax
-; CHECK-NEXT: movl %eax, %ecx
-; CHECK-NEXT: adcl $-1, %ecx
-; CHECK-NEXT: movl %edx, %r8d
-; CHECK-NEXT: andl $1023, %r8d # imm = 0x3FF
-; CHECK-NEXT: leal 1024(%r8), %r9d
-; CHECK-NEXT: movl %r9d, %r10d
-; CHECK-NEXT: shrl %cl, %r10d
-; CHECK-NEXT: movl $1, %r11d
-; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT: shll %cl, %r11d
-; CHECK-NEXT: decl %r11d
-; CHECK-NEXT: xorl %ebp, %ebp
-; CHECK-NEXT: testw %r11w, %r9w
-; CHECK-NEXT: setne %bpl
-; CHECK-NEXT: movl %eax, %ecx
-; CHECK-NEXT: shrl %cl, %r9d
-; CHECK-NEXT: movl %r9d, %ecx
-; CHECK-NEXT: andl $1, %ecx
-; CHECK-NEXT: orl %ebp, %ecx
-; CHECK-NEXT: andl %r10d, %ecx
-; CHECK-NEXT: cmpw $1, %ax
-; CHECK-NEXT: cmovbl %edi, %ecx
-; CHECK-NEXT: addl %r9d, %ecx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: cmpw $4, %cx
-; CHECK-NEXT: cmovgel %edi, %ecx
-; CHECK-NEXT: setge %al
-; CHECK-NEXT: shrl $8, %ebx
-; CHECK-NEXT: andl $128, %ebx
-; CHECK-NEXT: leal (%rbx,%rax,4), %eax
-; CHECK-NEXT: orl %ecx, %eax
-; CHECK-NEXT: shrl $8, %r8d
-; CHECK-NEXT: movl %r8d, %ecx
-; CHECK-NEXT: andl $1, %ecx
+; CHECK-NEXT: pextrw $0, %xmm0, %eax
+; CHECK-NEXT: movl %eax, %edx
+; CHECK-NEXT: andl $1023, %edx # imm = 0x3FF
+; CHECK-NEXT: leal 1024(%rdx), %esi
+; CHECK-NEXT: movl %esi, %edi
+; CHECK-NEXT: movl %ebp, %ecx
+; CHECK-NEXT: shrl %cl, %edi
+; CHECK-NEXT: movl $1, %r8d
+; CHECK-NEXT: shll %cl, %r8d
+; CHECK-NEXT: decl %r8d
; CHECK-NEXT: xorl %r9d, %r9d
-; CHECK-NEXT: testb $127, %dl
+; CHECK-NEXT: testw %r8w, %si
; CHECK-NEXT: setne %r9b
-; CHECK-NEXT: orl %ecx, %r9d
-; CHECK-NEXT: shrl $7, %edx
-; CHECK-NEXT: andl %r9d, %edx
-; CHECK-NEXT: addl %r8d, %edx
+; CHECK-NEXT: movl %ebx, %ecx
+; CHECK-NEXT: shrl %cl, %esi
+; CHECK-NEXT: movl %esi, %r8d
+; CHECK-NEXT: andl $1, %r8d
+; CHECK-NEXT: orl %r9d, %r8d
+; CHECK-NEXT: andl %edi, %r8d
; CHECK-NEXT: xorl %ecx, %ecx
-; CHECK-NEXT: cmpw $4, %dx
-; CHECK-NEXT: cmovgel %edi, %edx
-; CHECK-NEXT: setge %cl
-; CHECK-NEXT: leal (%rsi,%rcx), %edi
-; CHECK-NEXT: leal 56(,%rdi,4), %edi
-; CHECK-NEXT: movl %ebx, %ebp
-; CHECK-NEXT: orl %edx, %ebp
-; CHECK-NEXT: orl %edi, %ebp
-; CHECK-NEXT: leal 14(%rsi,%rcx), %ecx
-; CHECK-NEXT: testw %cx, %cx
-; CHECK-NEXT: cmovlel %eax, %ebp
-; CHECK-NEXT: cmpw $4, %dx
+; CHECK-NEXT: cmpw $1, %bx
+; CHECK-NEXT: cmovbl %ecx, %r8d
+; CHECK-NEXT: addl %esi, %r8d
+; CHECK-NEXT: xorl %esi, %esi
+; CHECK-NEXT: cmpw $4, %r8w
+; CHECK-NEXT: cmovgel %ecx, %r8d
+; CHECK-NEXT: setge %sil
+; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT: pextrw $0, %xmm1, %ebx
+; CHECK-NEXT: shrl $8, %ebx
+; CHECK-NEXT: andl $128, %ebx
+; CHECK-NEXT: leal (%rbx,%rsi,4), %esi
+; CHECK-NEXT: orl %r8d, %esi
+; CHECK-NEXT: shrl $8, %edx
+; CHECK-NEXT: movl %edx, %edi
+; CHECK-NEXT: andl $1, %edi
+; CHECK-NEXT: xorl %r8d, %r8d
+; CHECK-NEXT: testb $127, %al
+; CHECK-NEXT: setne %r8b
+; CHECK-NEXT: orl %edi, %r8d
+; CHECK-NEXT: shrl $7, %eax
+; CHECK-NEXT: andl %r8d, %eax
+; CHECK-NEXT: addl %edx, %eax
+; CHECK-NEXT: xorl %edx, %edx
+; CHECK-NEXT: cmpw $4, %ax
+; CHECK-NEXT: cmovgel %ecx, %eax
+; CHECK-NEXT: setge %dl
+; CHECK-NEXT: leal (%r14,%rdx), %ecx
+; CHECK-NEXT: leal 56(,%rcx,4), %edi
+; CHECK-NEXT: movl %ebx, %ecx
+; CHECK-NEXT: orl %eax, %ecx
+; CHECK-NEXT: orl %edi, %ecx
+; CHECK-NEXT: leal 14(%r14,%rdx), %edx
+; CHECK-NEXT: testw %dx, %dx
+; CHECK-NEXT: cmovlel %esi, %ecx
+; CHECK-NEXT: cmpw $4, %ax
; CHECK-NEXT: setge %al
-; CHECK-NEXT: cmpw $30, %cx
-; CHECK-NEXT: sete %dl
-; CHECK-NEXT: andb %al, %dl
-; CHECK-NEXT: cmpw $31, %cx
+; CHECK-NEXT: cmpw $30, %dx
+; CHECK-NEXT: sete %sil
+; CHECK-NEXT: andb %al, %sil
+; CHECK-NEXT: cmpw $31, %dx
; CHECK-NEXT: setge %al
-; CHECK-NEXT: orb %dl, %al
-; CHECK-NEXT: leal 124(%rbx), %r14d
+; CHECK-NEXT: orb %sil, %al
+; CHECK-NEXT: leal 124(%rbx), %ebp
; CHECK-NEXT: testb %al, %al
-; CHECK-NEXT: cmovnel %r14d, %ebp
-; CHECK-NEXT: callq __extendhfsf2 at PLT
-; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill
-; CHECK-NEXT: xorps %xmm1, %xmm1
-; CHECK-NEXT: ucomiss %xmm1, %xmm0
-; CHECK-NEXT: cmovnel %ebp, %ebx
-; CHECK-NEXT: cmovpl %ebp, %ebx
-; CHECK-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT: cmovnel %ebp, %ecx
+; CHECK-NEXT: xorps %xmm2, %xmm2
+; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload
+; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT: ucomiss %xmm2, %xmm0
+; CHECK-NEXT: cmovnel %ecx, %ebx
+; CHECK-NEXT: cmovpl %ecx, %ebx
+; CHECK-NEXT: movdqa %xmm1, %xmm0
+; CHECK-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
; CHECK-NEXT: callq __extendhfsf2 at PLT
; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; CHECK-NEXT: cmovnel %ebx, %r14d
-; CHECK-NEXT: cmovpl %ebx, %r14d
-; CHECK-NEXT: xorps %xmm0, %xmm0
-; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Reload
-; CHECK-NEXT: # xmm1 = mem[0],zero,zero,zero
-; CHECK-NEXT: ucomiss %xmm0, %xmm1
+; CHECK-NEXT: cmovnel %ebx, %ebp
+; CHECK-NEXT: cmovpl %ebx, %ebp
+; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload
+; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT: pxor %xmm1, %xmm1
+; CHECK-NEXT: ucomiss %xmm1, %xmm0
; CHECK-NEXT: movl $126, %eax
-; CHECK-NEXT: cmovnpl %r14d, %eax
+; CHECK-NEXT: cmovnpl %ebp, %eax
; CHECK-NEXT: # kill: def $al killed $al killed $eax
; CHECK-NEXT: addq $32, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 32
diff --git a/llvm/test/CodeGen/X86/llvm.frexp.ll b/llvm/test/CodeGen/X86/llvm.frexp.ll
index d14d737a5ca29..3410fd5169c9a 100644
--- a/llvm/test/CodeGen/X86/llvm.frexp.ll
+++ b/llvm/test/CodeGen/X86/llvm.frexp.ll
@@ -5,36 +5,13 @@
define { half, i32 } @test_frexp_f16_i32(half %a) nounwind {
; X64-LABEL: test_frexp_f16_i32:
; X64: # %bb.0:
-; X64-NEXT: subq $24, %rsp
-; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
+; X64-NEXT: pushq %rax
; X64-NEXT: callq __extendhfsf2 at PLT
-; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
+; X64-NEXT: callq frexpf at PLT
; X64-NEXT: callq __truncsfhf2 at PLT
-; X64-NEXT: pextrw $0, %xmm0, %ecx
-; X64-NEXT: movl %ecx, %eax
-; X64-NEXT: andl $31744, %eax # imm = 0x7C00
-; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload
-; X64-NEXT: pextrw $0, %xmm0, %edx
-; X64-NEXT: movl %edx, %esi
-; X64-NEXT: andl $32767, %esi # imm = 0x7FFF
-; X64-NEXT: cmpl $1024, %esi # imm = 0x400
-; X64-NEXT: cmovael %edx, %ecx
-; X64-NEXT: cmovael %esi, %eax
-; X64-NEXT: shrl $10, %eax
-; X64-NEXT: leal -12(%rax), %edi
-; X64-NEXT: cmpl $1024, %esi # imm = 0x400
-; X64-NEXT: cmovael %eax, %edi
-; X64-NEXT: addl $-14, %edi
-; X64-NEXT: andl $33791, %ecx # imm = 0x83FF
-; X64-NEXT: orl $14336, %ecx # imm = 0x3800
-; X64-NEXT: addl $-31744, %esi # imm = 0x8400
-; X64-NEXT: movzwl %si, %esi
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpl $33792, %esi # imm = 0x8400
-; X64-NEXT: cmoval %edi, %eax
-; X64-NEXT: cmovbel %edx, %ecx
-; X64-NEXT: pinsrw $0, %ecx, %xmm0
-; X64-NEXT: addq $24, %rsp
+; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax
+; X64-NEXT: popq %rcx
; X64-NEXT: retq
;
; WIN32-LABEL: test_frexp_f16_i32:
@@ -64,26 +41,12 @@ define { half, i32 } @test_frexp_f16_i32(half %a) nounwind {
define half @test_frexp_f16_i32_only_use_fract(half %a) nounwind {
; X64-LABEL: test_frexp_f16_i32_only_use_fract:
; X64: # %bb.0:
-; X64-NEXT: subq $24, %rsp
-; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
+; X64-NEXT: pushq %rax
; X64-NEXT: callq __extendhfsf2 at PLT
-; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
+; X64-NEXT: callq frexpf at PLT
; X64-NEXT: callq __truncsfhf2 at PLT
-; X64-NEXT: pextrw $0, %xmm0, %eax
-; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload
-; X64-NEXT: pextrw $0, %xmm0, %ecx
-; X64-NEXT: movl %ecx, %edx
-; X64-NEXT: andl $32767, %edx # imm = 0x7FFF
-; X64-NEXT: cmpl $1024, %edx # imm = 0x400
-; X64-NEXT: cmovael %ecx, %eax
-; X64-NEXT: andl $33791, %eax # imm = 0x83FF
-; X64-NEXT: orl $14336, %eax # imm = 0x3800
-; X64-NEXT: addl $-31744, %edx # imm = 0x8400
-; X64-NEXT: movzwl %dx, %edx
-; X64-NEXT: cmpl $33792, %edx # imm = 0x8400
-; X64-NEXT: cmovbel %ecx, %eax
-; X64-NEXT: pinsrw $0, %eax, %xmm0
-; X64-NEXT: addq $24, %rsp
+; X64-NEXT: popq %rax
; X64-NEXT: retq
;
; WIN32-LABEL: test_frexp_f16_i32_only_use_fract:
@@ -110,29 +73,12 @@ define half @test_frexp_f16_i32_only_use_fract(half %a) nounwind {
define i32 @test_frexp_f16_i32_only_use_exp(half %a) nounwind {
; X64-LABEL: test_frexp_f16_i32_only_use_exp:
; X64: # %bb.0:
-; X64-NEXT: subq $24, %rsp
-; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
+; X64-NEXT: pushq %rax
; X64-NEXT: callq __extendhfsf2 at PLT
-; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; X64-NEXT: callq __truncsfhf2 at PLT
-; X64-NEXT: pextrw $0, %xmm0, %eax
-; X64-NEXT: andl $31744, %eax # imm = 0x7C00
-; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload
-; X64-NEXT: pextrw $0, %xmm0, %ecx
-; X64-NEXT: andl $32767, %ecx # imm = 0x7FFF
-; X64-NEXT: cmpl $1024, %ecx # imm = 0x400
-; X64-NEXT: cmovael %ecx, %eax
-; X64-NEXT: shrl $10, %eax
-; X64-NEXT: leal -12(%rax), %edx
-; X64-NEXT: cmpl $1024, %ecx # imm = 0x400
-; X64-NEXT: cmovael %eax, %edx
-; X64-NEXT: addl $-14, %edx
-; X64-NEXT: addl $-31744, %ecx # imm = 0x8400
-; X64-NEXT: movzwl %cx, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpl $33792, %ecx # imm = 0x8400
-; X64-NEXT: cmoval %edx, %eax
-; X64-NEXT: addq $24, %rsp
+; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
+; X64-NEXT: callq frexpf at PLT
+; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax
+; X64-NEXT: popq %rcx
; X64-NEXT: retq
;
; WIN32-LABEL: test_frexp_f16_i32_only_use_exp:
More information about the llvm-commits
mailing list