llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29k stars 11.95k forks source link

`std::exp()` produces infinite loop on Windows with `-Ofast` #31745

Open llvmbot opened 7 years ago

llvmbot commented 7 years ago
Bugzilla Link 32398
Version trunk
OS Windows XP
Attachments Demonstration of the bug
Reporter LLVM Bugzilla Contributor
CC @rnk

Extended Description

When cross compiling for Windows (I haven't tested native compile on Windows), std::exp() is miscompiled as an infinite loop if -Ofast is used. exp() works correctly, and std::exp() works correctly on Linux.

Clang version: 297935 (Also tried a 4.0.0 pre-release with similar results) OS: Arch Linux

Steps to reproduce: see build.sh in the tarball

Expected result: No infinite loop should be produced. Actual result: The produced IR has a branch to a branch to itself (i.e: an infinite loop).

Contents of the tarball:

build.sh
    Shows how I produced all the files in the out directory.
exp.cpp
    A minimal reproducer that demonstrates the bug.
out/windows_ofast/exp_expanded.cpp
    The preprocessed version of exp.cpp on my system for -Ofast on Windows
out/windows_ofast/exp.bc
    The generated IR bitcode for exp.cpp

The remaining files are analogous for -O3 and for native build.

rnk commented 7 years ago

-Ofast enables -ffast-math, which enables this libcall simplification as part of instcombine:

define linkonce_odr float @expf(float %_X) local_unnamed_addr #4 comdat {
entry:
  %conv = fpext float %_X to double
  %call = call fast double @exp(double %conv) #5
  %conv1 = fptrunc double %call to float
  ret float %conv1
}

->

define linkonce_odr float @expf(float %_X) local_unnamed_addr #4 comdat {
entry:
  %expf = call fast float @expf(float %_X) #3
  ret float %expf
}

And things go south from there, as we have infinite tail recursion. The solution is probably to say that expf is not available on mingw targets (modify TargetLibraryInfo), so we don't think we can materialize new calls to it.