-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SDAG][X86] Promote float FMODF to double on 32-bit Windows #130636
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
On 32-bit MSVC `modff` is not a defined symbol -- only `modf` (`modff` is an inline function). Promoting FMODF to double in this case ensures we end up calling `modf` -- matching the behaviour of the CRT headers.
@llvm/pr-subscribers-backend-x86 Author: Benjamin Maxwell (MacDue) ChangesOn 32-bit MSVC Full diff: https://github.com/llvm/llvm-project/pull/130636.diff 2 Files Affected:
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index ccd7f2418fcd1..3e02162020302 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2634,7 +2634,9 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
ISD::FSIN, ISD::STRICT_FSIN,
ISD::FSINH, ISD::STRICT_FSINH,
ISD::FTAN, ISD::STRICT_FTAN,
- ISD::FTANH, ISD::STRICT_FTANH})
+ ISD::FTANH, ISD::STRICT_FTANH,
+ // TODO: Add ISD:::STRICT_FMODF too once implemented.
+ ISD::FMODF})
if (isOperationExpand(Op, MVT::f32))
setOperationAction(Op, MVT::f32, Promote);
// clang-format on
diff --git a/llvm/test/CodeGen/X86/llvm.modf-win32.ll b/llvm/test/CodeGen/X86/llvm.modf-win32.ll
new file mode 100644
index 0000000000000..70ce773dda482
--- /dev/null
+++ b/llvm/test/CodeGen/X86/llvm.modf-win32.ll
@@ -0,0 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=i386-pc-win32 < %s | FileCheck -check-prefix=WIN32 %s
+; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck -check-prefixes=X64 %s
+
+; On 32-bit windows this should be promoted to a call to modf (not modff).
+define { float, float } @test_modf_f32(float %a) {
+; WIN32-LABEL: test_modf_f32:
+; WIN32: # %bb.0:
+; WIN32-NEXT: pushl %ebp
+; WIN32-NEXT: movl %esp, %ebp
+; WIN32-NEXT: andl $-8, %esp
+; WIN32-NEXT: subl $32, %esp
+; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
+; WIN32-NEXT: flds 8(%ebp)
+; WIN32-NEXT: fstpl (%esp)
+; WIN32-NEXT: calll _modf
+; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT: fldl {{[0-9]+}}(%esp)
+; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT: flds {{[0-9]+}}(%esp)
+; WIN32-NEXT: flds {{[0-9]+}}(%esp)
+; WIN32-NEXT: fxch %st(1)
+; WIN32-NEXT: movl %ebp, %esp
+; WIN32-NEXT: popl %ebp
+; WIN32-NEXT: retl
+;
+; X64-LABEL: test_modf_f32:
+; X64: # %bb.0:
+; X64-NEXT: pushq %rax
+; X64-NEXT: .cfi_def_cfa_offset 16
+; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
+; X64-NEXT: callq modff@PLT
+; X64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X64-NEXT: popq %rax
+; X64-NEXT: .cfi_def_cfa_offset 8
+; X64-NEXT: retq
+ %result = call { float, float } @llvm.modf.f32(float %a)
+ ret { float, float } %result
+}
|
cc @nico, @zmodem (should solve #129885 (comment)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! This looks like exactly what's needed.
…nsic" (#130761) Reverts llvm/llvm-project@c40f0fe Original description: This updates the existing modf[f|l] builtin to be lowered via the llvm.modf.* intrinsic (rather than directly to a library call). The Windows 32-bit x86 missing `modff` symbol issue should have been solved in: llvm/llvm-project#130636.
…761) Reverts llvm/llvm-project@c40f0fe Original description: This updates the existing modf[f|l] builtin to be lowered via the llvm.modf.* intrinsic (rather than directly to a library call). The Windows 32-bit x86 missing `modff` symbol issue should have been solved in: llvm/llvm-project#130636.
On 32-bit MSVC
modff
is not a defined symbol -- onlymodf
(modff
is an inline function). Promoting FMODF to double in this case ensures we end up callingmodf
-- matching the behaviour of the CRT headers.