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

            Bug ID: 126596
           Summary: [16/17 Regression] ICE in
                    aarch64_possible_by_lane_insn_p
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: ice-on-valid-code
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ktkachov at gcc dot gnu.org
  Target Milestone: ---
            Target: aarch64

/* config/aarch64/aarch64.cc:18824 - aarch64_possible_by_lane_insn_p.
   ICE on valid code.

   Flags: gcc -O3 t.c -S

   aarch64_possible_by_lane_insn_p decides the tree code from the *pattern*
   statement

     rep_stmt = STMT_VINFO_STMT (vect_stmt_to_vectorize (lookup_stmt
(new_stmt)))

   but then reads the operand from the *original* statement, new_stmt.  The two
   are different gimple objects exactly when new_stmt is
STMT_VINFO_IN_PATTERN_P.
   vect_recog_pow_pattern replaces the GIMPLE_CALL pow (x, 2.0) by the pattern
   statement "patt = x * x", so rep_stmt has code MULT_EXPR while new_stmt is
   still a GIMPLE_CALL, and gimple_assign_rhs2 (new_stmt) trips the gimple
   check:

     internal compiler error: gimple check: expected gimple_assign(error_mark),
     have gimple_call() in gimple_assign_rhs2, at gimple.h:2786
       aarch64_possible_by_lane_insn_p         config/aarch64/aarch64.cc:18824
       aarch64_vector_costs::add_stmt_cost     config/aarch64/aarch64.cc:19030 
*/

extern double pow (double, double) __attribute__ ((__const__, __nothrow__));

#define N 40
#define M 1024

double in[N + M], coeff[M], out[N];

void
foo (void)
{
  for (int i = 0; i < N; i++)
    {
      double diff = 0.0;
      for (int j = 0; j < M; j++)
        diff += in[j + i] * pow (coeff[j], 2.0);
      out[i] = diff;
    }
}

Reply via email to