The following code, compiled with -O2 for powerpc64le-linux-gnu, produces the following ICE. This is a regression from GCC 7 (note you need -mfloat128 to build with older compilers), reduced from glibc test-tgmath3, and probably postdates the change to enable _Float128 support by default for powerpc64le (since the glibc test built before then, then glibc build for powerpc64le was broken for a while, and by the time it was fixed this ICE appeared). Note, you need both the _Complex long double functions and the apparently independent _Complex _Float128 functions for this ICE to appear. _Complex long double vld; _Complex _Float128 vf128; _Complex long double fld (_Complex long double arg0) { return 0; } _Complex _Float128 ff128 (_Complex _Float128 arg0) { return 0; } void tld (void) { vld = fld (vld); } void tf128 (void) { vf128 = ff128 (vf128); } during RTL pass: expand test-tgmath3.i: In function 'tf128': test-tgmath3.i:25:9: internal compiler error: in as_a, at machmode.h:345 vf128 = ff128 (vf128); ~~~~~~^~~~~~~~~~~~~~~ 0x839dec scalar_mode as_a<scalar_mode>(machine_mode) /scratch/jmyers/glibc/many8/src/gcc/gcc/machmode.h:345 0x839dec convert_mode_scalar /scratch/jmyers/glibc/many8/src/gcc/gcc/expr.c:281 0x839dec convert_move(rtx_def*, rtx_def*, int) /scratch/jmyers/glibc/many8/src/gcc/gcc/expr.c:271 0x84091e store_expr_with_bounds(tree_node*, rtx_def*, int, bool, bool, tree_node*) /scratch/jmyers/glibc/many8/src/gcc/gcc/expr.c:5628 0x8424f0 expand_assignment(tree_node*, tree_node*, bool) /scratch/jmyers/glibc/many8/src/gcc/gcc/expr.c:5319 0x71ff95 expand_gimple_stmt_1 /scratch/jmyers/glibc/many8/src/gcc/gcc/cfgexpand.c:3655 0x71ff95 expand_gimple_stmt /scratch/jmyers/glibc/many8/src/gcc/gcc/cfgexpand.c:3751 0x722796 expand_gimple_basic_block /scratch/jmyers/glibc/many8/src/gcc/gcc/cfgexpand.c:5750 0x7281a6 execute /scratch/jmyers/glibc/many8/src/gcc/gcc/cfgexpand.c:6357 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions.
This occurs because both fld and ff128 return the same constant (0), one using it as a long double and the other as a _Float128. Having a 0 constant is not important. If we return 1 in both functions, it will still trap. If we change the constant so each function (fld and ff128) returns a different value, it works. If we suppress inlining, it works.
Author: meissner Date: Thu Nov 9 20:01:29 2017 New Revision: 254607 URL: https://gcc.gnu.org/viewcvs?rev=254607&root=gcc&view=rev Log: fix pr 82333 Added: branches/ibm/ieee/gcc/testsuite/gcc.target/powerpc/pr82333.c Modified: branches/ibm/ieee/gcc/ChangeLog.meissner branches/ibm/ieee/gcc/builtins.c branches/ibm/ieee/gcc/builtins.def branches/ibm/ieee/gcc/c/c-decl.c branches/ibm/ieee/gcc/config/rs6000/rs6000.md branches/ibm/ieee/gcc/convert.c branches/ibm/ieee/gcc/fold-const-call.c branches/ibm/ieee/gcc/fold-const.c branches/ibm/ieee/gcc/internal-fn.def branches/ibm/ieee/gcc/testsuite/ChangeLog.meissner branches/ibm/ieee/gcc/testsuite/gcc.target/powerpc/float128-hw2.c branches/ibm/ieee/gcc/varasm.c
The bug is due to compare_constant thinking two floating point constants are the same if the floating point size and the internal value are the same. On the PowerPC, long double and _Float128 both are 128-bits, but they have different internal representations. The bug shows up when you try to inline two functions, one that returns 0 converted to long double _Complex and the other that returns 0 converted to _Float128 _Complex. The function compare_constant in varasm.c thinks that these two constants are the same, and assigns them to the same hash. When inliner tries to replace the inline function (that returns 0) with the constant, it does moves of the real part and the imaginary part. In the second function, the real/imaginary parts have type KFmode, while the first function (that has the saved constant) the real/imaginary parts have type TFmode. The fix is to consider the type along with the precision when doing hash of the constants.
Note the checkin message in note 2 was for a private branch, that included other patches that have been submitted.
*** Bug 82928 has been marked as a duplicate of this bug. ***
Fixed in subversion id 255177.