> Am 23.12.2025 um 11:02 schrieb Arsen Arsenović <[email protected]>:
>
> Okay, I did that.
>
> It seems somewhat odd to me to fail the whole procedure due to one use
> stmt, but I couldn't come up with a scenario where that'd be a problem,
> so, fair enough.
>
> I can push after testing if that seems fine to you.
> ---------- >8 ----------
> With the following testcase, on AMDGCN with -Ofast:
>
> void
> foo (float* output, float* input)
> {
> for (int i = 0; i < 1024 * 1024; i++) {
> output[i] = __builtin_sinf (input[i]) + __builtin_cosf (input[i]);
> }
> }
>
> ... the following ICE happens:
>
> during GIMPLE pass: sincos
> test.cpp: In function 'void foo(float*, float*)':
> test.cpp:2:1: internal compiler error: Segmentation fault
> 2 | foo (float* output, float* input)
> | ^~~
> [... snipped ...]
> 0x17befb8 types_compatible_p(tree_node*, tree_node*)
> gcc/gimple-expr.h:67
> 0x17befb8 execute_cse_sincos_1
> gcc/tree-ssa-math-opts.cc:1299
> 0x17befb8 execute
> gcc/tree-ssa-math-opts.cc:2248
>
> This happens because the vect pass converted the testcase into:
>
> vect__4.6_40 = MEM <vector(64) float> [(float *)vectp_input.4_38];
> vect__6.8_42 = .COS (vect__4.6_40);
> vect__5.7_41 = .SIN (vect__4.6_40);
> vect__8.9_43 = vect__5.7_41 + vect__6.8_42;
>
> Then, sincos attempts to find the type of the IFN_SIN/IFN_COS via
> mathfn_built_in_type. This fails, so the compiler crashes.
>
> For these IFNs, their input type is the same as their output type, so
> we can fall back to that.
>
> Note that, currently, GCC can't seem to handle vector sincos/cexpi
> operations, so any attempt to CSE these will fail quickly after. This
> patch does not fix that, only the ICE that happens in the attempt.
Ok
Richard
> gcc/ChangeLog:
>
> * tree-ssa-math-opts.cc (execute_cse_sincos_1): If
> mathfn_built_in_type fails to determine a type for our
> operation, presume that it is the same as the input type.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/tree-ssa/sincos-ice-on-ifn_sin-call.c: New test.
> * gcc.target/gcn/sincos-ice-on-ifn_sin-call-1.c: New test.
> ---
> .../tree-ssa/sincos-ice-on-ifn_sin-call.c | 19 +++++++++++++++++++
> .../gcn/sincos-ice-on-ifn_sin-call-1.c | 13 +++++++++++++
> gcc/tree-ssa-math-opts.cc | 13 ++++++++++++-
> 3 files changed, 44 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/sincos-ice-on-ifn_sin-call.c
> create mode 100644 gcc/testsuite/gcc.target/gcn/sincos-ice-on-ifn_sin-call-1.c
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sincos-ice-on-ifn_sin-call.c
> b/gcc/testsuite/gcc.dg/tree-ssa/sincos-ice-on-ifn_sin-call.c
> new file mode 100644
> index 000000000000..3a8c047502e0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/sincos-ice-on-ifn_sin-call.c
> @@ -0,0 +1,19 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-O -fgimple" } */
> +typedef float V __attribute__ ((vector_size (16)));
> +
> +void __GIMPLE (ssa, startwith ("sincos"))
> +foo (float * output, const float * input)
> +{
> + V a;
> + V b;
> + V c;
> + V d;
> +
> + __BB(2):
> + a = __MEM <const V> (input);
> + b = .COS (a);
> + c = .SIN (a);
> + d = a + b;
> + return;
> +}
> diff --git a/gcc/testsuite/gcc.target/gcn/sincos-ice-on-ifn_sin-call-1.c
> b/gcc/testsuite/gcc.target/gcn/sincos-ice-on-ifn_sin-call-1.c
> new file mode 100644
> index 000000000000..b787a49fb0e8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/gcn/sincos-ice-on-ifn_sin-call-1.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-Ofast" } */
> +#include <math.h>
> +
> +/* This test is the original, platform-specific, version of
> + gcc.dg/tree-ssa/sincos-ice-on-ifn_sin-call.c. */
> +void
> +foo (float output[1024 * 1024], const float input[1024 * 1024])
> +{
> + for (int i = 0; i < 1024 * 1024; i++) {
> + output[i] = __builtin_sinf (input[i]) + __builtin_cosf (input[i]);
> + }
> +}
> diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
> index 04c9f2c07e92..02e194ae06f3 100644
> --- a/gcc/tree-ssa-math-opts.cc
> +++ b/gcc/tree-ssa-math-opts.cc
> @@ -1287,7 +1287,18 @@ execute_cse_sincos_1 (tree name)
> continue;
> }
>
> - tree t = mathfn_built_in_type (gimple_call_combined_fn (use_stmt));
> + auto stmt_cfn = gimple_call_combined_fn (use_stmt);
> + tree t = mathfn_built_in_type (stmt_cfn);
> + if (!t)
> + {
> + /* It is possible to get IFN_{SIN,COS} calls, for which
> + mathfn_built_in_type will return NULL. Those are normally only
> + present for vector operations. We won't be able to CSE those
> + at the moment. */
> + gcc_checking_assert (internal_fn_p (stmt_cfn));
> + return false;
> + }
> +
> if (!type)
> {
> type = t;
> --
> 2.52.0
>