This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/64829] [ARM] ICE at -O3 in vect_get_vec_def_for_stmt_copy
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 28 Jan 2015 14:06:33 +0000
- Subject: [Bug tree-optimization/64829] [ARM] ICE at -O3 in vect_get_vec_def_for_stmt_copy
- Auto-submitted: auto-generated
- References: <bug-64829-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64829
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
In fact we recognize a widening shift but it gets dropped on the floor:
t.c:48:2: note: ------>vectorizing statement: result_15 = val0_14 << 4;
t.c:48:2: note: ------>vectorizing statement: _17 = val1_16(D) - val0_14;
huh? The issue that we hit is that we vectorized the def of val0_14
with ncopies == 1 but now require two copies of it when vectorizing
val1_16(D) - val0_14. So maybe the shift issue is unrelated.
Sofar we have
vect__13.17_155 = MEM[(const Uint8 *)vectp_pCornerPoint0.15_153];
_13 = *pCornerPoint0_48;
vect__41.18_156 = [vec_unpack_lo_expr] vect__13.17_155;
vect__41.18_157 = [vec_unpack_hi_expr] vect__13.17_155;
val0_14 = (Sint32) _13;
Thus we widen a char load to an int but the vectorized version widens to
an unsigned short only. That's probably because of the consumer
result_15 = val0_14 << 4;
which was pattern detected as widening shift. But unfortunately that isn't
the only one and we forgot
_17 = val1_16(D) - val0_14;
which then results in the ICE.
Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c (revision 220205)
+++ gcc/tree-vect-patterns.c (working copy)
@@ -1732,9 +1732,11 @@ vect_recog_widen_shift_pattern (vec<gimp
if (TREE_CODE (oprnd0) != SSA_NAME || TREE_CODE (oprnd1) != INTEGER_CST)
return NULL;
- /* Check operand 0: it has to be defined by a type promotion. */
- if (!type_conversion_p (oprnd0, last_stmt, false, &half_type0, &def_stmt0,
- &promotion)
+ /* Check operand 0: it has to be defined by a type promotion and it
+ should be only used by the shift. */
+ if (!has_single_use (oprnd0)
+ || !type_conversion_p (oprnd0, last_stmt, false, &half_type0,
&def_stmt0,
+ &promotion)
|| !promotion)
return NULL;