https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94261
--- Comment #1 from rguenther at suse dot de <rguenther at suse dot de> --- On March 22, 2020 12:46:45 PM GMT+01:00, "rsandifo at gcc dot gnu.org" <gcc-bugzi...@gcc.gnu.org> wrote: >https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94261 > > Bug ID: 94261 > Summary: [10 Regression] ICE in vect_get_vec_def_for_operand_1 > for 3-element condition reduction > Product: gcc > Version: unknown > Status: UNCONFIRMED > Keywords: ice-on-valid-code > Severity: normal > Priority: P3 > Component: tree-optimization > Assignee: unassigned at gcc dot gnu.org > Reporter: rsandifo at gcc dot gnu.org > CC: rguenth at gcc dot gnu.org > Target Milestone: --- > Target: aarch64*-*-* > >The following test ICEs when compiled with >-O3 -ffinite-math-only -march=armv8.2-a+sve >on aarch64: > >void >f (float *x, float *y, float z) >{ > float res0 = 0, res1 = 1, res2 = 2; > for (int i = 0; i < 100; ++i) > { > res0 = 100 <= y[i * 3] ? res0 : z; > res1 = 101 <= y[i * 3 + 1] ? res1 : z; > res2 = y[i * 3 + 2] < 102 ? z : res2; > } > x[0] = res0; > x[1] = res1; > x[2] = res2; >} > >The ICE is: > >b.c:2:1: internal compiler error: in vect_get_vec_def_for_operand_1, at >tree-vect-stmts.c:1555 > 2 | f (float *x, float *y, float z) > | ^ >0x10a86c3 vect_get_vec_def_for_operand_1(_stmt_vec_info*, >vect_def_type) > gcc/tree-vect-stmts.c:1555 >0x10af8e1 vect_get_vec_def_for_operand(tree_node*, _stmt_vec_info*, >tree_node*) > gcc/tree-vect-stmts.c:1617 >0x10b258f vectorizable_condition > gcc/tree-vect-stmts.c:10213 >0x10d01ea vect_transform_stmt(_stmt_vec_info*, gimple_stmt_iterator*, >_slp_tree*, _slp_instance*) > gcc/tree-vect-stmts.c:11012 >0x10d4226 vect_transform_loop_stmt > gcc/tree-vect-loop.c:8307 >0x10ec31a vect_transform_loop(_loop_vec_info*, gimple*) > gcc/tree-vect-loop.c:8707 >0x110f797 try_vectorize_loop_1 > gcc/tree-vectorizer.c:990 >0x1110319 vectorize_loops() > gcc/tree-vectorizer.c:1126 > >The problem comes from trying both SVE and Advanced SIMD and >eventually picking SVE. The SVE version can't treat the loop >as a single 3-element SLP reduction because we don't yet >support loading { 100, 101, 102 } repeating for variable-length >vectors. We therefore fail the SLP build before doing anything >about the awkward comparison arrangement. With this version, >each ?: is a separate reduction and each one has its own, >correct, STMT_VINFO_REDUC_IDX. > >But then we try the Advanced SIMD version. This doesn't have >a problem with loading the constants, so we get as far as >dealing with mismatched comparisons: > > /* Swap. */ > if (*swap == 1) > { > swap_ssa_operands (stmt, &TREE_OPERAND (cond, 0), > &TREE_OPERAND (cond, 1)); > TREE_SET_CODE (cond, swap_tree_comparison (code)); > } > /* Invert. */ > else > { > swap_ssa_operands (stmt, gimple_assign_rhs2_ptr (stmt), > gimple_assign_rhs3_ptr (stmt)); > if (STMT_VINFO_REDUC_IDX (stmt_info) == 1) > STMT_VINFO_REDUC_IDX (stmt_info) = 2; > else if (STMT_VINFO_REDUC_IDX (stmt_info) == 2) > STMT_VINFO_REDUC_IDX (stmt_info) = 1; > bool honor_nans = HONOR_NANS (TREE_OPERAND (cond, 0)); > code = invert_tree_comparison (TREE_CODE (cond), honor_nans); > gcc_assert (code != ERROR_MARK); > TREE_SET_CODE (cond, code); > } > >But these changes to the gimple stmt persist even if the SLP build >fails later, or if the SLP build succeeds and we decide not to >vectorise that way. That doesn't matter too much for the current >loop_vinfo, because the STMT_VINFO_REDUC_IDXs are still consistent >with the gimple stmt. But it means that the STMT_VINFO_REDUC_IDXs >for the older SVE loop_vinfo are now no longer correct. > >The ICE triggers when we go back to the SVE loop_vinfo as the >cheapest implementation and try to code-generate the reduction. > >The testcase is reduced from 481.wrf compiled with LTO. Stmt modifications considered harmful.. I've pondered with using alternate Gimple stmts for the slp node here, similar to patterns but of course not registered with the main stmt_info as that would get us back to the very same issue. But only pondered, not actually tried implementing this.