Commit 239a625e by Roger Sayle Committed by Roger Sayle

fold-const.c (negate_expr_p): We can optimize -((int)X>>C) where C is an integer…

fold-const.c (negate_expr_p): We can optimize -((int)X>>C) where C is an integer constant one bit less than...


	* fold-const.c (negate_expr_p) <RSHIFT_EXPR>: We can optimize
	-((int)X>>C) where C is an integer constant one bit less than the
	size of X into (unsigned)X>>C.  Similarly for unsigned->signed.
	(negate_expr) <RSHIFT_EXPR>: Implement the above transformations.

	* simplify-rtx.c (simplify_unary_operation): Also implement the
	above transformations at the RTL level.

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

From-SVN: r79334
parent 4b0b51c9
2004-03-11 Roger Sayle <roger@eyesopen.com>
* fold-const.c (negate_expr_p) <RSHIFT_EXPR>: We can optimize
-((int)X>>C) where C is an integer constant one bit less than the
size of X into (unsigned)X>>C. Similarly for unsigned->signed.
(negate_expr) <RSHIFT_EXPR>: Implement the above transformations.
* simplify-rtx.c (simplify_unary_operation): Also implement the
above transformations at the RTL level.
2004-03-11 Alan Modra <amodra@bigpond.net.au>
* real.c (encode_ibm_extended): Do round low word.
......
......@@ -920,6 +920,18 @@ negate_expr_p (tree t)
return negate_expr_p (TREE_VALUE (TREE_OPERAND (t, 1)));
break;
case RSHIFT_EXPR:
/* Optimize -((int)x >> 31) into (unsigned)x >> 31. */
if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
{
tree op1 = TREE_OPERAND (t, 1);
if (TREE_INT_CST_HIGH (op1) == 0
&& (unsigned HOST_WIDE_INT) (TYPE_PRECISION (type) - 1)
== TREE_INT_CST_LOW (op1))
return true;
}
break;
default:
break;
}
......@@ -1065,6 +1077,25 @@ negate_expr (tree t)
}
break;
case RSHIFT_EXPR:
/* Optimize -((int)x >> 31) into (unsigned)x >> 31. */
if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
{
tree op1 = TREE_OPERAND (t, 1);
if (TREE_INT_CST_HIGH (op1) == 0
&& (unsigned HOST_WIDE_INT) (TYPE_PRECISION (type) - 1)
== TREE_INT_CST_LOW (op1))
{
tree ntype = TREE_UNSIGNED (type)
? (*lang_hooks.types.signed_type) (type)
: (*lang_hooks.types.unsigned_type) (type);
tree temp = fold_convert (ntype, TREE_OPERAND (t, 0));
temp = fold (build2 (RSHIFT_EXPR, ntype, temp, op1));
return fold_convert (type, temp);
}
}
break;
default:
break;
}
......
......@@ -1013,6 +1013,22 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
XEXP (op, 1));
}
/* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
C is equal to the width of MODE minus 1. */
if (GET_CODE (op) == ASHIFTRT
&& GET_CODE (XEXP (op, 1)) == CONST_INT
&& INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1)
return simplify_gen_binary (LSHIFTRT, mode,
XEXP (op, 0), XEXP (op, 1));
/* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
C is equal to the width of MODE minus 1. */
if (GET_CODE (op) == LSHIFTRT
&& GET_CODE (XEXP (op, 1)) == CONST_INT
&& INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1)
return simplify_gen_binary (ASHIFTRT, mode,
XEXP (op, 0), XEXP (op, 1));
break;
case SIGN_EXTEND:
......
2004-03-11 Roger Sayle <roger@eyesopen.com>
* gcc.c-torture/execute/20040311-1.c: New test case.
2004-03-11 Mark Mitchell <mark@codesourcery.com>
PR c++/14476
......
/* Copyright (C) 2004 Free Software Foundation.
Check that constant folding and RTL simplification of -(x >> y) doesn't
break anything and produces the expected results.
Written by Roger Sayle, 11th March 2004. */
extern void abort (void);
#define INT_BITS (sizeof(int)*8)
int test1(int x)
{
return -(x >> (INT_BITS-1));
}
int test2(unsigned int x)
{
return -((int)(x >> (INT_BITS-1)));
}
int test3(int x)
{
int y;
y = INT_BITS-1;
return -(x >> y);
}
int test4(unsigned int x)
{
int y;
y = INT_BITS-1;
return -((int)(x >> y));
}
int main()
{
if (test1(0) != 0)
abort ();
if (test1(1) != 0)
abort ();
if (test1(-1) != 1)
abort ();
if (test2(0) != 0)
abort ();
if (test2(1) != 0)
abort ();
if (test2((unsigned int)-1) != -1)
abort ();
if (test3(0) != 0)
abort ();
if (test3(1) != 0)
abort ();
if (test3(-1) != 1)
abort ();
if (test4(0) != 0)
abort ();
if (test4(1) != 0)
abort ();
if (test4((unsigned int)-1) != -1)
abort ();
return 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