https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128436

            Bug ID: 128436
           Summary: ICE in fold_convert_const_int_from_real when IPA-CP
                    substitutes a float vector constant for a load of the
                    same bytes as an integer vector
           Product: gcc
           Version: 16.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: ipa
          Assignee: unassigned at gcc dot gnu.org
          Reporter: willcode4 at gmail dot com
  Target Milestone: ---

Known to fail: 14.2.0 (aarch64-linux-gnu), 15.3.1, 16.2.1
(x86_64-redhat-linux).

pr.c:

```c
typedef float v4f __attribute__((vector_size(16)));
typedef int v4i __attribute__((vector_size(16)));
union U { v4f f; v4i i; };
v4i h(v4i);
__attribute__((noinline)) v4i f(union U u) { return h(u.i); }
v4i g1(void) { union U u = { .f = { 0.7f, 0.7f, 0.7f, 0.7f } }; return f(u); }
v4i g2(void) { union U u = { .f = { 0.7f, 0.7f, 0.7f, 0.7f } }; return f(u); }
```

```
$ gcc -O3 --param=ipa-cp-eval-threshold=1 -c pr.c
during IPA pass: cp
pr.c: In function 'f.constprop':
pr.c:5:31: internal compiler error: in fold_convert_const_int_from_real, at
fold-const.cc:2234
```

The same happens with `-O2 -fipa-cp-clone --param=ipa-cp-eval-threshold=1`.
Plain `-O3` hits it in larger code without the parameter: a C++ SIMD library
whose functions take a vector class by value and read its bits as an integer
vector, called twice with the same constant vector.

IPA-CP knows the aggregate value of `u` at offset 0 as a `v4f` constant and
clones `f`. In `ipcp_modif_dom_walker::before_dom_children` (ipa-prop.cc) the
load `u.i` has type `v4i`. `fold_convertible_p (v4i, v4f constant)` holds for
vectors of the same size, so the replacement is built as `NOP_EXPR`. Folding it
converts each `REAL_CST` element to `int` with `NOP_EXPR`, and
`fold_convert_const_int_from_real` accepts only `FIX_TRUNC_EXPR`. For a load
the replacement has to reinterpret the bytes, as the `VIEW_CONVERT_EXPR` branch
beside it does. A value conversion of the vector would also give the wrong
result if it did not stop.

PR 127842 reaches the same `gcc_unreachable` from C++ constant evaluation. PR
105250 notes that `fold_convertible_p` accepts vector conversions that
`fold_convert` does not.

Reply via email to