| Summary: | Clang -O0 on i386 assigns garbage to floats in some cases | ||
|---|---|---|---|
| Product: | Base System | Reporter: | BEC <cebd> |
| Component: | i386 | Assignee: | Dimitry Andric <dim> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | CC: | dim, emaste, kib, rdivacky, rollingbits, tijl |
| Priority: | Normal | ||
| Version: | Unspecified | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->closed incomplete problem report from an invalid email address. Responsible Changed From-To: freebsd-i386->linimon Reopen and assign to toolchain@, although it may be an upstream clang bug. The test program in the report should print 0 twice, but clang doesn't at -O0. I cannot reproduce this, it prints two 0s for me with clang3.4 on freebsd9.3. (In reply to Roman Divacky from comment #4) > I cannot reproduce this, it prints two 0s for me with clang3.4 on freebsd9.3. i386 is important detail. clang generates obviously incorrect code even on amd64 with -m32, first storing zero float, then overriding it with some garbage. The test passes if sse math is used, i.e. '-m32 -mfpmath=sse -march=corei7 -O0' works. Ah, it reproduces with clang3.4 -m32. It seems to be fixed with clang3.5 though. So I guess the solution for this bug is to import clang3.5 A commit references this bug: Author: dim Date: Sun Sep 14 18:50:39 UTC 2014 New revision: 271597 URL: http://svnweb.freebsd.org/changeset/base/271597 Log: Pull in r217410 from upstream llvm trunk (by Bob Wilson): Set trunc store action to Expand for all X86 targets. When compiling without SSE2, isTruncStoreLegal(F64, F32) would return Legal, whereas with SSE2 it would return Expand. And since the Target doesn't seem to actually handle a truncstore for double -> float, it would just output a store of a full double in the space for a float hence overwriting other bits on the stack. Patch by Luqman Aden! This should fix clang -O0 on i386 assigning garbage to floats, in certain scenarios. PR: 187437 Submitted by: cebd@gmail.com Obtained from: http://llvm.org/viewvc/llvm-project?rev=217410&view=rev MFC after: 3 days Changes: head/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp A commit references this bug: Author: dim Date: Thu Sep 18 05:40:34 UTC 2014 New revision: 271737 URL: http://svnweb.freebsd.org/changeset/base/271737 Log: MFC r271597: Pull in r217410 from upstream llvm trunk (by Bob Wilson): Set trunc store action to Expand for all X86 targets. When compiling without SSE2, isTruncStoreLegal(F64, F32) would return Legal, whereas with SSE2 it would return Expand. And since the Target doesn't seem to actually handle a truncstore for double -> float, it would just output a store of a full double in the space for a float hence overwriting other bits on the stack. Patch by Luqman Aden! This should fix clang -O0 on i386 assigning garbage to floats, in certain scenarios. PR: 187437 Submitted by: cebd@gmail.com Obtained from: http://llvm.org/viewvc/llvm-project?rev=217410&view=rev Changes: _U stable/9/contrib/llvm/ stable/9/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp A commit references this bug: Author: dim Date: Thu Sep 18 06:34:27 UTC 2014 New revision: 271739 URL: http://svnweb.freebsd.org/changeset/base/271739 Log: MFC r271597: Pull in r217410 from upstream llvm trunk (by Bob Wilson): Set trunc store action to Expand for all X86 targets. When compiling without SSE2, isTruncStoreLegal(F64, F32) would return Legal, whereas with SSE2 it would return Expand. And since the Target doesn't seem to actually handle a truncstore for double -> float, it would just output a store of a full double in the space for a float hence overwriting other bits on the stack. Patch by Luqman Aden! This should fix clang -O0 on i386 assigning garbage to floats, in certain scenarios. PR: 187437 Submitted by: cebd@gmail.com Approved by: re (marius) Obtained from: http://llvm.org/viewvc/llvm-project?rev=217410&view=rev Changes: _U stable/10/ stable/10/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp Fix applied to head (r271597), stable/10 (r271739) and stable/9 (r271737). |
#include <stdio.h> int main(){ float a,b,c; b=0.; a=25; c=1.293/(1+a/273) ; printf("\n%g",b); double aa,bb,cc; bb=0.; aa=25; cc=1.293/(1+aa/273) ; printf("\n%g",bb); return(0); } 1.89807 0