This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/23522] [3.4/4.0/4.1 Regression] fold_widened_comparison bug
- From: "alexey dot starovoytov at sun dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 23 Aug 2005 23:35:08 -0000
- Subject: [Bug middle-end/23522] [3.4/4.0/4.1 Regression] fold_widened_comparison bug
- References: <20050823011700.23522.alexey.starovoytov@sun.com>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From alexey dot starovoytov at sun dot com 2005-08-23 23:35 -------
Actually I think 3.x versions are fine.
Here is the snipper from 3.4.3:
else if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
&& TREE_CODE (arg0) == NOP_EXPR
&& (tem = get_unwidened (arg0, NULL_TREE)) != arg0
&& (code == EQ_EXPR || code == NE_EXPR
|| TREE_UNSIGNED (TREE_TYPE (arg0))
== TREE_UNSIGNED (TREE_TYPE (tem)))
&& (t1 = get_unwidened (arg1, TREE_TYPE (tem))) != 0
&& (TREE_TYPE (t1) == TREE_TYPE (tem)
|| (TREE_CODE (t1) == INTEGER_CST
&& int_fits_type_p (t1, TREE_TYPE (tem)))))
return fold (build (code, type, tem,
fold_convert (TREE_TYPE (tem), t1)));
the (t1 = get_unwidened (arg1, TREE_TYPE (tem))) != 0 line
may look suspicious, but it's actually just redundant.
If it's changed to t1 != arg1, then probably int_fits_type_p() condition
will never be called.
The real problem is in 4.0 and 4.1.
The snipper from 4.0.1:
if (TREE_CODE (arg1_unw) != INTEGER_CST)
return NULL_TREE;
/* If we are comparing with the integer that does not fit into the range
of the shorter type, the result is known. */
outer_type = TREE_TYPE (arg1_unw);
min = lower_bound_in_type (outer_type, shorter_type);
max = upper_bound_in_type (outer_type, shorter_type);
above = integer_nonzerop (fold_relational_const (LT_EXPR, type,
max, arg1_unw));
below = integer_nonzerop (fold_relational_const (LT_EXPR, type,
arg1_unw, min));
switch (code)
{
case EQ_EXPR:
if (above || below)
return omit_one_operand (type, integer_zero_node, arg0);
break;
This optimization is incorrect if unwidening of arg1 didn't happen.
So I think the proper new fix would be to remove lines 6104,6105
and add the check that unwidening happened to line 6115:
------- fold-const.c -------
*** /tmp/geta16407 Tue Aug 23 16:21:18 2005
--- /tmp/getb16407 Tue Aug 23 16:21:18 2005
***************
*** 6101,6108 ****
return NULL_TREE;
arg1_unw = get_unwidened (arg1, shorter_type);
- if (!arg1_unw)
- return NULL_TREE;
/* If possible, express the comparison in the shorter mode. */
if ((code == EQ_EXPR || code == NE_EXPR
--- 6101,6106 ----
***************
*** 6114,6120 ****
return fold (build (code, type, arg0_unw,
fold_convert (shorter_type, arg1_unw)));
! if (TREE_CODE (arg1_unw) != INTEGER_CST)
return NULL_TREE;
/* If we are comparing with the integer that does not fit into the range
--- 6112,6118 ----
return fold (build (code, type, arg0_unw,
fold_convert (shorter_type, arg1_unw)));
! if (arg1_unw == arg1 || TREE_CODE (arg1_unw) != INTEGER_CST)
return NULL_TREE;
/* If we are comparing with the integer that does not fit into the range
My previous suggested fix accidentally disabled vectorization in
gcc.dg/vect/vect-87.c and gcc.dg/vect/vect-88.c on 64-bit targets.
New fix seems to be fine.
Alex.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23522