Skip to content
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

[X86][clang] 128bit floating-point operations in x86 machines #77401

Open
CoTinker opened this issue Jan 9, 2024 · 18 comments
Open

[X86][clang] 128bit floating-point operations in x86 machines #77401

CoTinker opened this issue Jan 9, 2024 · 18 comments
Labels

Comments

@CoTinker
Copy link
Contributor

CoTinker commented Jan 9, 2024

testcase:

#include <fenv.h>
#include <stdlib.h>
#include <stdio.h>

int main (void)
{
  volatile __float128 a = 0x0.fffp-16382q, b = 0x0.fffp0q, c;
  c = a / b;
  if (fetestexcept (FE_UNDERFLOW | FE_INEXACT))
    printf("Fail1\n");
  if (c != 0x1p-16382q)
    printf("Fail2\n");
  exit (0);
}

compile command:

% clang test.c -o test -lm -m32
% ./test
Fail1
Fail2

compile in x86_64 will return normally, but x86 output Fail.
https://godbolt.org/z/vhdsMhd8d

@github-actions github-actions bot added the clang Clang issues not falling into any other category label Jan 9, 2024
@EugeneZelenko EugeneZelenko added backend:X86 floating-point Floating-point math and removed clang Clang issues not falling into any other category labels Jan 9, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 9, 2024

@llvm/issue-subscribers-backend-x86

Author: Longsheng Mou (CoTinker)

testcase:
#include &lt;fenv.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;

int main (void)
{
  volatile __float128 a = 0x0.fffp-16382q, b = 0x0.fffp0q, c;
  c = a / b;
  if (fetestexcept (FE_UNDERFLOW | FE_INEXACT))
    printf("Fail1\n");
  if (c != 0x1p-16382q)
    printf("Fail2\n");
  exit (0);
}

compile command:

% clang test.c -o test -lm -m32
% ./test
Fail1
Fail2

compile in x86_64 will return normally, but x86 output Fail.
https://godbolt.org/z/vhdsMhd8d

@arsenm
Copy link
Contributor

arsenm commented Jan 9, 2024

Technically you need to enable FENV_ACCESS for this program

@CoTinker
Copy link
Contributor Author

CoTinker commented Jan 9, 2024

Technically you need to enable FENV_ACCESS for this program

#pragma STDC FENV_ACCESS ON
It seems not work.

@CoTinker
Copy link
Contributor Author

CC @RKSimon @phoebewang

@hstk30-hw
Copy link
Contributor

@arsenm Hi, enable FENV_ACCESS still fail. Does FENV_ACCESS supported in m32 ?
https://godbolt.org/z/MsYTe1cPc

@hstk30-hw
Copy link
Contributor

CC @brad0

@hstk30-hw
Copy link
Contributor

hstk30-hw commented Jan 30, 2024

https://godbolt.org/z/4KbaWcvsG

I see the asm, clang x86 with m32 abi is not compatible with libgcc.

@hstk30-hw
Copy link
Contributor

CC @hvdijk

@arsenm
Copy link
Contributor

arsenm commented Feb 1, 2024

@arsenm Hi, enable FENV_ACCESS still fail. Does FENV_ACCESS supported in m32 ? https://godbolt.org/z/MsYTe1cPc

I think it should work the same as x64

@hstk30-hw
Copy link
Contributor

In fact, not work! I guess float128 (long double) not align to 16 in x86-32.
I'm reading the x86 isel dag->dag pass, maybe lowering mir gets mistake in the step.

@hstk30-hw
Copy link
Contributor

Do you have any idea about this problem?
It seems a legacy.
https://lists.llvm.org/pipermail/llvm-dev/2016-December/108033.html
Seems no body care about x86-32? @arsenm

@arsenm
Copy link
Contributor

arsenm commented Feb 1, 2024

Seems no body care about x86-32?

Correct

@hstk30-hw
Copy link
Contributor

So sad :(

@jcranmer-intel
Copy link
Contributor

In fact, not work! I guess float128 (long double) not align to 16 in x86-32. I'm reading the x86 isel dag->dag pass, maybe lowering mir gets mistake in the step.

__float128 in the i386 psABI has a 16-byte alignment, though __float128 is not long double on x86 (that's the 80-bit type in general).

@hstk30-hw
Copy link
Contributor

What Info I get from gdb debug is that

in function SoftenFloatRes_Binary store the TypeListBeforeSoften to CallOptions.OpsVTBeforeSoften

https://github.com/llvm/llvm-project/blob/3bcb1f2bdd5c70b2ac4aff3290996486d9ae0236/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp#L188C1-L207C2

but not used in TargetLowering::LowerCallTo.

In this case,

f128 = fdiv t33, t36

t33, t36 is f128,after GetSoftenedFloat it transfer to i128. So in TargetLowering::LowerCallTo the align is from i128

@hstk30-hw
Copy link
Contributor

https://godbolt.org/z/48GcPM5xM

If we disable sse, it failed in x86-64

@tgross35
Copy link

tgross35 commented May 14, 2024

Just as a note, LLVM and GCC are ABI-incompatible on x86 MinGW. I think it is GCC doing the wrong thing here, opened https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054 (unrelated to this issue, but possibly relevant for testing)

@tgross35
Copy link

@beetrees clarified that this is a stack alignment issue in rust-lang/compiler-builtins#622 (comment):

The i686 issue appears to be an ABI issue: GCC aligns f128 arguments to 16 bytes on the stack, whereas Clang/LLVM does not. Looking at the 32-bit x86 System V ABI specification, GCC's behaviour appears to be correct:

Padding may be needed to increase the size of each parameter to enforce alignment according to the values in Table 2.1.

Table 2.1 specifies __float128 to have both 16 byte size and alignment https://www.uclibc.org/docs/psABI-i386.pdf

tgross35 added a commit to tgross35/rust that referenced this issue Nov 3, 2024
With the `compiler-builtins` update to 0.1.137 [1], we now provide
symbols necessary to work with `f128` everywhere. This means that we are
no longer restricted to 64-bit linux, and can enable tests by default.

There are still a handful of platforms that need to remain disabled
because of bugs. This patch additionally disables the following:

1. MIPS [2]
2. 32-bit x86 [3]

Math support is still off by default since those symbols are not yet
available.

[1]: rust-lang#132433
[2]: llvm/llvm-project#96432
[3]: llvm/llvm-project#77401
tgross35 added a commit to tgross35/rust that referenced this issue Nov 4, 2024
With the `compiler-builtins` update to 0.1.137 [1], we now provide
symbols necessary to work with `f128` everywhere. This means that we are
no longer restricted to 64-bit linux, and can enable tests by default.

There are still a handful of platforms that need to remain disabled
because of bugs. This patch additionally disables the following:

1. MIPS [2]
2. 32-bit x86 [3]

Math support is still off by default since those symbols are not yet
available.

[1]: rust-lang#132433
[2]: llvm/llvm-project#96432
[3]: llvm/llvm-project#77401
tgross35 added a commit to tgross35/rust that referenced this issue Nov 4, 2024
With the `compiler-builtins` update to 0.1.137 [1], we now provide
symbols necessary to work with `f128` everywhere. This means that we are
no longer restricted to 64-bit linux, and can enable tests by default.

There are still a handful of platforms that need to remain disabled
because of bugs. This patch additionally disables the following:

1. MIPS [2]
2. 32-bit x86 [3]

Math support is still off by default since those symbols are not yet
available.

[1]: rust-lang#132433
[2]: llvm/llvm-project#96432
[3]: llvm/llvm-project#77401
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants