Command line: gcc -fno-trapping-math testcase.c ------ testcase.c ------ int foo(_Decimal64 x[2]) { return !(x[0] < x[1]); } ------------------------ Tested revisions: r157877 - crash r153685 - crash 4.4 r157895 - OK Compiler output: $ /mnt/svn/gcc-trunk/binary-157877-lto/bin/gcc -fno-trapping-math testcase.c testcase.c: In function 'foo': testcase.c:3:3: internal compiler error: in prepare_float_lib_cmp, at optabs.c:4392 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions.
Because we only have an optab for LT (reversed UNGE), but FLOAT_LIB_COMPARE_RETURNS_BOOL is false. Without -fno-trapping-math we use LT from the start which works. I suppose FLOAT_LIB_COMPARE_RETURNS_BOOL should return true for decimal float modes on x86?
And I believe the regression is because of either cond-optab or expand-from-SSA which causes us no longer to fallback to expand a UNORD b || a >= b.
(In reply to comment #1) > Because we only have an optab for LT (reversed UNGE), but > FLOAT_LIB_COMPARE_RETURNS_BOOL is false. > > Without -fno-trapping-math we use LT from the start which works. > > I suppose FLOAT_LIB_COMPARE_RETURNS_BOOL should return true for decimal > float modes on x86? > I don't think so.
It is caused by revision 149031: http://gcc.gnu.org/ml/gcc-cvs/2009-06/msg01016.html
Created attachment 20279 [details] patch Here is a totally untested patch...
Patch looks a bit big for 4.5.0.
GCC 4.5.0 is being released. Deferring to 4.5.1.
The patch is mostly splitting an if statement in two parts. If anyone can test it for 4.5.1/4.6 that would be nice.
Thank you for the patch. I tested it in trunk r158150 at x86_64-unix, it bootstrapped fine (languages=c,c++,lto,fortran). check with RUNTESTFLAGS="--target_board=unix/-fno-trapping-math" fixed following FAILs (compared to clean r158150): FAIL: c-c++-common/dfp/compare-rel-d128.c (internal compiler error) FAIL: c-c++-common/dfp/compare-rel-d128.c (test for excess errors) FAIL: c-c++-common/dfp/compare-rel-d32.c (internal compiler error) FAIL: c-c++-common/dfp/compare-rel-d32.c (test for excess errors) FAIL: c-c++-common/dfp/compare-rel-d64.c (internal compiler error) FAIL: c-c++-common/dfp/compare-rel-d64.c (test for excess errors) FAIL: c-c++-common/dfp/compare-rel-dfp.c (internal compiler error) FAIL: c-c++-common/dfp/compare-rel-dfp.c (test for excess errors) FAIL: c-c++-common/dfp/compare-special-d128.c (internal compiler error) FAIL: c-c++-common/dfp/compare-special-d128.c (test for excess errors) FAIL: c-c++-common/dfp/compare-special-d32.c (internal compiler error) FAIL: c-c++-common/dfp/compare-special-d32.c (test for excess errors) FAIL: c-c++-common/dfp/compare-special-d64.c (internal compiler error) FAIL: c-c++-common/dfp/compare-special-d64.c (test for excess errors) FAIL: c-c++-common/dfp/convert-dfp.c (internal compiler error) FAIL: c-c++-common/dfp/convert-dfp.c (test for excess errors) FAIL: c-c++-common/dfp/nan-2.c (internal compiler error) FAIL: c-c++-common/dfp/nan-2.c (test for excess errors) FAIL: c-c++-common/dfp/compare-rel-d128.c (internal compiler error) FAIL: c-c++-common/dfp/compare-rel-d128.c (test for excess errors) FAIL: c-c++-common/dfp/compare-rel-d32.c (internal compiler error) FAIL: c-c++-common/dfp/compare-rel-d32.c (test for excess errors) FAIL: c-c++-common/dfp/compare-rel-d64.c (internal compiler error) FAIL: c-c++-common/dfp/compare-rel-d64.c (test for excess errors) FAIL: c-c++-common/dfp/compare-rel-dfp.c (internal compiler error) FAIL: c-c++-common/dfp/compare-rel-dfp.c (test for excess errors) FAIL: c-c++-common/dfp/compare-special-d128.c (internal compiler error) FAIL: c-c++-common/dfp/compare-special-d128.c (test for excess errors) FAIL: c-c++-common/dfp/compare-special-d32.c (internal compiler error) FAIL: c-c++-common/dfp/compare-special-d32.c (test for excess errors) FAIL: c-c++-common/dfp/compare-special-d64.c (internal compiler error) FAIL: c-c++-common/dfp/compare-special-d64.c (test for excess errors) FAIL: c-c++-common/dfp/convert-dfp.c (internal compiler error) FAIL: c-c++-common/dfp/convert-dfp.c (test for excess errors) FAIL: c-c++-common/dfp/nan-2.c (internal compiler error) FAIL: c-c++-common/dfp/nan-2.c (test for excess errors) and didn't add any new FAIL The testcase works fine too. I didn't verify if the generated code is correct.
I hope my comment wasn't misunderstood - the patch from comment #5 fixes several FAILs and doesn't introduce any regressions (at least in r158150)
Patch posted now. Sorry, I was busy.
Subject: Bug 43610 Author: bonzini Date: Tue May 25 09:19:37 2010 New Revision: 159813 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=159813 Log: 2010-05-09 Paolo Bonzini <bonzini@gnu.org> PR target/43610 * optabs.c (prepare_float_lib_cmp): Allow reversing the comparison even if !FLOAT_LIB_COMPARE_RETURNS_BOOL. Always compute true_rtx and false_rtx. Use false_rtx to compute the correct *ptest for reversed comparisons for which !FLOAT_LIB_COMPARE_RETURNS_BOOL. Modified: trunk/gcc/ChangeLog trunk/gcc/optabs.c
Fixed on the trunk, unfixed on the branch.
GCC 4.5.1 is being released, adjusting target milestone.
GCC 4.5.2 is being released, adjusting target milestone.
GCC 4.5.3 is being released, adjusting target milestone.
Fixed in 4.6.0, the 4.5 branch is being closed.