Zonr Chang via llvm-dev
2015-Sep-14 19:11 UTC
[llvm-dev] [LLVMDev] Inconsistent result between GCC and Clang for __builtin_fmodf
Following simple program gives different answers when compiling with GCC (4.8.4) and ToT Clang: $ cat builtin_fmodf_bugpoint.cpp #include <cstdio> int main(int argc, char** argv) { const float a = 1.0f; const float b = 0.1f; printf("%f mod %f = %f\n", a, b, __builtin_fmodf(a, b)); return 0; } $ g++ -o builtin_fmodf_bugpoint_gcc builtin_fmodf_bugpoint.cpp $ ./builtin_fmodf_bugpoint_gcc 1.000000 fmodf 0.100000 = 0.100000 $ clang++ -o builtin_fmodf_bugpoint_clang builtin_fmodf_bugpoint.cpp 1.000000 fmodf 0.100000 = 0.000000 Clang will compile __builtin_fmod() into LLVM's "frem" [1]. Since both operands are constant, it is constant folded by IRBuilder at the time when "frem" was built. The exeuction finally goes to llvm::ConstantFoldBinaryInstruction() which uses APFloat::mod() to compute the result. As you can see from above, it gives us 0.000000 (hex: 0x0) which is different than the answer from std::fmodf() (0.100000, hex: 0x3dcccccb). SelectionDAG also uses APFloat::mod() to fold "frem" when operands are constants. (see SelectionDAG::getNode()). However, lli interprets "frem" to a fmod() and therefore generates the same result as GCC's. $ lli -force-interpreter builtin_fmodf_bugpoint.ll 1.000000 fmodf 0.100000 = 0.100000 (Please refer to attachment for the .ll) Are these expected? Which semantic does LLVM's "frem" stick to? Any idea on how to fix it? [1] http://llvm.org/docs/LangRef.html#i-frem -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150915/a82a8071/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: builtin_fmodf_bugpoint.ll Type: application/octet-stream Size: 1484 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150915/a82a8071/attachment.obj>
David Majnemer via llvm-dev
2015-Sep-14 20:33 UTC
[llvm-dev] [LLVMDev] Inconsistent result between GCC and Clang for __builtin_fmodf
There is a rather unsettling comment above APFloat::mod which states "This is not currently correct in all cases." I wonder if this is a symptom of that. On Mon, Sep 14, 2015 at 12:11 PM, Zonr Chang via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Following simple program gives different answers when compiling with GCC > (4.8.4) and ToT Clang: > > $ cat builtin_fmodf_bugpoint.cpp > #include <cstdio> > > int main(int argc, char** argv) { > const float a = 1.0f; > const float b = 0.1f; > printf("%f mod %f = %f\n", a, b, __builtin_fmodf(a, b)); > return 0; > } > $ g++ -o builtin_fmodf_bugpoint_gcc builtin_fmodf_bugpoint.cpp > $ ./builtin_fmodf_bugpoint_gcc > 1.000000 fmodf 0.100000 = 0.100000 > $ clang++ -o builtin_fmodf_bugpoint_clang builtin_fmodf_bugpoint.cpp > 1.000000 fmodf 0.100000 = 0.000000 > > Clang will compile __builtin_fmod() into LLVM's "frem" [1]. Since both > operands are constant, it is constant folded by IRBuilder at the time when > "frem" was built. The exeuction finally goes to > llvm::ConstantFoldBinaryInstruction() which uses APFloat::mod() to compute > the result. As you can see from above, it gives us 0.000000 (hex: 0x0) > which is different than the answer from std::fmodf() (0.100000, hex: > 0x3dcccccb). > > SelectionDAG also uses APFloat::mod() to fold "frem" when operands are > constants. (see SelectionDAG::getNode()). However, lli interprets "frem" to > a fmod() and therefore generates the same result as GCC's. > > $ lli -force-interpreter builtin_fmodf_bugpoint.ll > 1.000000 fmodf 0.100000 = 0.100000 > > (Please refer to attachment for the .ll) > > Are these expected? Which semantic does LLVM's "frem" stick to? Any idea > on how to fix it? > > [1] http://llvm.org/docs/LangRef.html#i-frem > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150914/917621d4/attachment.html>
Stephen Canon via llvm-dev
2015-Sep-14 20:49 UTC
[llvm-dev] [cfe-dev] [LLVMDev] Inconsistent result between GCC and Clang for __builtin_fmodf
Reading the implementation, that’s the understatement of the century. I’ll take a look at fixing it next weekend if no one else gets to it first. – Steve> On Sep 14, 2015, at 4:33 PM, David Majnemer via cfe-dev <cfe-dev at lists.llvm.org> wrote: > > There is a rather unsettling comment above APFloat::mod which states "This is not currently correct in all cases." > > I wonder if this is a symptom of that. > > On Mon, Sep 14, 2015 at 12:11 PM, Zonr Chang via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: > Following simple program gives different answers when compiling with GCC (4.8.4) and ToT Clang: > > $ cat builtin_fmodf_bugpoint.cpp > #include <cstdio> > > int main(int argc, char** argv) { > const float a = 1.0f; > const float b = 0.1f; > printf("%f mod %f = %f\n", a, b, __builtin_fmodf(a, b)); > return 0; > } > $ g++ -o builtin_fmodf_bugpoint_gcc builtin_fmodf_bugpoint.cpp > $ ./builtin_fmodf_bugpoint_gcc > 1.000000 fmodf 0.100000 = 0.100000 > $ clang++ -o builtin_fmodf_bugpoint_clang builtin_fmodf_bugpoint.cpp > 1.000000 fmodf 0.100000 = 0.000000 > > Clang will compile __builtin_fmod() into LLVM's "frem" [1]. Since both operands are constant, it is constant folded by IRBuilder at the time when "frem" was built. The exeuction finally goes to llvm::ConstantFoldBinaryInstruction() which uses APFloat::mod() to compute the result. As you can see from above, it gives us 0.000000 (hex: 0x0) which is different than the answer from std::fmodf() (0.100000, hex: 0x3dcccccb). > > SelectionDAG also uses APFloat::mod() to fold "frem" when operands are constants. (see SelectionDAG::getNode()). However, lli interprets "frem" to a fmod() and therefore generates the same result as GCC's. > > $ lli -force-interpreter builtin_fmodf_bugpoint.ll > 1.000000 fmodf 0.100000 = 0.100000 > > (Please refer to attachment for the .ll) > > Are these expected? Which semantic does LLVM's "frem" stick to? Any idea on how to fix it? > > [1] http://llvm.org/docs/LangRef.html#i-frem <http://llvm.org/docs/LangRef.html#i-frem> > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev> > > > _______________________________________________ > cfe-dev mailing list > cfe-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150914/af9974f2/attachment.html>
Apparently Analagous Threads
- looking for one-liner for strsplit and regex
- [LLVMdev] [LLVMDev] Clang stopped compiling?
- [LLVMdev] include/Config/config.h discrepancies between CMake and autofoo builds
- [LLVMdev] cmake+ninja build error for compiler-rt sources
- [LLVMdev] include/Config/config.h discrepancies between CMake and autofoo builds