Commit fba2c0cd by Jakub Jelinek Committed by Jakub Jelinek

fold-const.c (extract_muldiv): If not MULT_EXPR, check if either operand is divisible by C.

	* fold-const.c (extract_muldiv) [case PLUS_EXPR]: If not MULT_EXPR,
	check if either operand is divisible by C.
	(multiple_of_p): Handle LSHIFT_EXPR with small constant shift.
	If type is signed, consider negative numbers as well.

	* gcc.c-torture/execute/20010222-1.c: New test.

From-SVN: r39996
parent 487f1450
2001-02-23 Jakub Jelinek <jakub@redhat.com>
* fold-const.c (extract_muldiv) [case PLUS_EXPR]: If not MULT_EXPR,
check if either operand is divisible by C.
(multiple_of_p): Handle LSHIFT_EXPR with small constant shift.
If type is signed, consider negative numbers as well.
2001-02-22 Richard Henderson <rth@redhat.com>
* config/ia64/crtbegin.asm (.fini): Use pc-relative relocs to
......
......@@ -4487,7 +4487,12 @@ extract_muldiv (t, c, code, wide_type)
constant. */
t1 = extract_muldiv (op0, c, code, wide_type);
t2 = extract_muldiv (op1, c, code, wide_type);
if (t1 != 0 && t2 != 0)
if (t1 != 0 && t2 != 0
&& (code == MULT_EXPR
/* If not multiplication, we can only do this if either operand
is divisible by c. */
|| multiple_of_p (ctype, op0, c)
|| multiple_of_p (ctype, op1, c)))
return fold (build (tcode, ctype, convert (ctype, t1),
convert (ctype, t2)));
......@@ -7280,6 +7285,25 @@ multiple_of_p (type, top, bottom)
return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
&& multiple_of_p (type, TREE_OPERAND (top, 1), bottom));
case LSHIFT_EXPR:
if (TREE_CODE (TREE_OPERAND (top, 1)) == INTEGER_CST)
{
tree op1, t1;
op1 = TREE_OPERAND (top, 1);
/* const_binop may not detect overflow correctly,
so check for it explicitly here. */
if (TYPE_PRECISION (TREE_TYPE (size_one_node))
> TREE_INT_CST_LOW (op1)
&& TREE_INT_CST_HIGH (op1) == 0
&& 0 != (t1 = convert (type,
const_binop (LSHIFT_EXPR, size_one_node,
op1, 0)))
&& ! TREE_OVERFLOW (t1))
return multiple_of_p (type, t1, bottom);
}
return 0;
case NOP_EXPR:
/* Can't handle conversions from non-integral or wider integral type. */
if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (top, 0))) != INTEGER_TYPE)
......@@ -7293,9 +7317,10 @@ multiple_of_p (type, top, bottom)
return multiple_of_p (type, TREE_OPERAND (top, 0), bottom);
case INTEGER_CST:
if ((TREE_CODE (bottom) != INTEGER_CST)
|| (tree_int_cst_sgn (top) < 0)
|| (tree_int_cst_sgn (bottom) < 0))
if (TREE_CODE (bottom) != INTEGER_CST
|| (TREE_UNSIGNED (type)
&& (tree_int_cst_sgn (top) < 0
|| tree_int_cst_sgn (bottom) < 0)))
return 0;
return integer_zerop (const_binop (TRUNC_MOD_EXPR,
top, bottom, 0));
......
2001-02-23 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/20010222-1.c: New test.
2001-02-22 Jakub Jelinek <jakub@redhat.com>
* g++.old-deja/g++.other/inline20.C: New test.
......
int a[2] = { 18, 6 };
int main ()
{
int b = (-3 * a[0] -3 * a[1]) / 12;
if (b != -6)
abort ();
exit (0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment