https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128140
Xionghu Luo (luoxhu at gcc dot gnu.org) <yinyuefengyi at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |yinyuefengyi at gmail dot com
--- Comment #2 from Xionghu Luo (luoxhu at gcc dot gnu.org) <yinyuefengyi at
gmail dot com> ---
Got a fix candidate:
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 7e5a53234ba..ba9daae7b52 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -10993,7 +10993,25 @@ uniform_vector_difference_p (const_tree t1, const_tree
t2)
widest_int diff;
bool diff_p = false;
- if (VECTOR_CST_LOG2_NPATTERNS (t1) == VECTOR_CST_LOG2_NPATTERNS (t2)
+ unsigned HOST_WIDE_INT nelts;
+ bool nelts_constant_p = VECTOR_CST_NELTS (t1).is_constant (&nelts);
+
+ if (nelts_constant_p)
+ {
+ /* Compare every element rather than just the encoded ones whenever
+ the number of elements is known. A stepped vector only
+ encodes the start of the step, which hides a wrap-around:
+ { 253, 254, 255, 0, ... } and { 252, 253, 254, 255, ... }
+ both encode to pairs that differ by one, whereas the lane
+ in which the step wraps differs by -255.
+ PR tree-optimization/128140. */
+ for (unsigned HOST_WIDE_INT i = 0; i < nelts; ++i)
+ if (!record_uniform_integer_difference (vector_cst_elt (t1, i),
+ vector_cst_elt (t2, i),
+ &diff, &diff_p))
+ return NULL_TREE;
+ }
+ else if (VECTOR_CST_LOG2_NPATTERNS (t1) == VECTOR_CST_LOG2_NPATTERNS (t2)
&& (VECTOR_CST_NELTS_PER_PATTERN (t1)
== VECTOR_CST_NELTS_PER_PATTERN (t2)))
{
@@ -11007,17 +11025,7 @@ uniform_vector_difference_p (const_tree t1, const_tree
t2)
return NULL_TREE;
}
else
- {
- unsigned HOST_WIDE_INT nelts;
- if (!VECTOR_CST_NELTS (t1).is_constant (&nelts))
- return NULL_TREE;
-
- for (unsigned HOST_WIDE_INT i = 0; i < nelts; ++i)
- if (!record_uniform_integer_difference (vector_cst_elt (t1, i),
- vector_cst_elt (t2, i),
- &diff, &diff_p))
- return NULL_TREE;
- }
+ return NULL_TREE;
if (!diff_p || !wi::fits_shwi_p (diff))
return NULL_TREE;