------- Comment #4 from ebotcazou at gcc dot gnu dot org 2005-12-06 09:21 ------- Dorit, this is a bad interaction between versioning and reduction.
The compiler segfaults in tree-ssa-dce.c because a PHI node declared as having 2 operands has only 1. It is created by the vectorizer, namely vect_create_epilog_for_reduction here: /*** 2. Create epilog code ***/ /* 2.1 Create new loop-exit-phi to preserve loop-closed form: v_out1 = phi <v_loop> */ exit_bb = loop->single_exit->dest; new_phi = create_phi_node (SSA_NAME_VAR (vect_def), exit_bb); SET_PHI_ARG_DEF (new_phi, loop->single_exit->dest_idx, vect_def); It turns out that exit_bb has 2 predecessors while the code implicitly assumes it has only 1. This is so because versioning has kicked in: <L32>:; vect_p.37_65 = nd.1_55; addr2int0.38_67 = (int) vect_p.37_65; andmask.39_69 = addr2int0.38_67 & 7; if (andmask.39_69 == 0) goto <L33>; else goto <L34>; <L33>:; <L35>:; vect_p.43_87 = nd.1_55; vect_p.41_79 = (vector int *) vect_p.43_87; vect_cst_.46_104 = { 0, 0 }; # ivtmp.48_110 = PHI <ivtmp.48_111(2), 0(19)>; # vect_var_.45_75 = PHI <vect_var_.45_5(2), vect_cst_.46_104(19)>; # ivtmp.44_78 = PHI <ivtmp.44_77(2), vect_p.41_79(19)>; # ivtmp.35_61 = PHI <ivtmp.35_63(2), 4(19)>; # n_18 = PHI <n_58(2), 0(19)>; # s_19 = PHI <s_59(2), 0(19)>; <L0>:; s.0_51 = (unsigned int) s_19; D.1314_52 = s.0_51 * 4; D.1315_53 = (int *) D.1314_52; D.1317_56 = D.1315_53 + nd.1_55; vect_var_.40_76 = *ivtmp.44_78; D.1318_57 = *D.1317_56; vect_var_.45_5 = vect_var_.45_75 + vect_var_.40_76; n_58 = D.1318_57 + n_18; s_59 = s_19 + 1; ivtmp.35_63 = ivtmp.35_61 - 1; ivtmp.44_77 = ivtmp.44_78 + 8B; ivtmp.48_111 = ivtmp.48_110 + 1; if (ivtmp.48_111 < 2) goto <L19>; else goto <L7>; <L19>:; goto <bb 1> (<L0>); <L34>:; # ivtmp.35_2 = PHI <4(18), ivtmp.35_88(15)>; # n_60 = PHI <0(18), n_90(15)>; # s_62 = PHI <0(18), s_89(15)>; <L31>:; s.0_64 = (unsigned int) s_62; D.1314_66 = s.0_64 * 4; D.1315_68 = (int *) D.1314_66; D.1317_92 = D.1315_68 + nd.1_55; D.1318_91 = *D.1317_92; n_90 = n_60 + D.1318_91; s_89 = s_62 + 1; ivtmp.35_88 = ivtmp.35_2 - 1; if (ivtmp.35_88 != 0) goto <L30>; else goto <L7>; <L30>:; goto <bb 14> (<L31>); # vect_var_.45_105 = PHI <vect_var_.45_5(1), (14)>; # n_6 = PHI <n_58(1), n_90(14)>; <L7>:; The bogus PHI node is the last but one. What's the best approach to fixing this? Punting in vectorizable_reduction if we know beforehand that the loop will be versioned? /* Same if the loop is to be versioned. */ if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))) return false; Or can vect_create_epilog_for_reduction be enhanced to cope with versioning? Thanks in advance. -- ebotcazou at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |dorit at il dot ibm dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24378