> 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
> 

Reply via email to