re PR middle-end/34971 (bitfield rotates are folded and expanded wrong)
2008-02-27 Richard Guenther <rguenther@suse.de> PR middle-end/34971 * expr.c (expand_expr_real_1): Assert on rotates that operate on partial modes. * fold-const.c (fold_binary): Use the types precision, not the bitsize of the mode if folding rotate expressions. Build rotates only for full modes. * gcc.c-torture/execute/pr34971.c: New testcase. From-SVN: r132706
This commit is contained in:
parent
a15f0fd028
commit
70582b3afe
@ -1,3 +1,12 @@
|
||||
2008-02-27 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/34971
|
||||
* expr.c (expand_expr_real_1): Assert on rotates that operate
|
||||
on partial modes.
|
||||
* fold-const.c (fold_binary): Use the types precision, not the
|
||||
bitsize of the mode if folding rotate expressions. Build rotates
|
||||
only for full modes.
|
||||
|
||||
2008-02-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* c-ppoutput.c (scan_translation_unit): Handle CPP_PRAGMA
|
||||
|
10
gcc/expr.c
10
gcc/expr.c
@ -8898,10 +8898,16 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
|
||||
case BIT_XOR_EXPR:
|
||||
goto binop;
|
||||
|
||||
case LSHIFT_EXPR:
|
||||
case RSHIFT_EXPR:
|
||||
case LROTATE_EXPR:
|
||||
case RROTATE_EXPR:
|
||||
/* The expansion code only handles expansion of mode precision
|
||||
rotates. */
|
||||
gcc_assert (GET_MODE_PRECISION (TYPE_MODE (type))
|
||||
== TYPE_PRECISION (type));
|
||||
|
||||
/* Falltrough. */
|
||||
case LSHIFT_EXPR:
|
||||
case RSHIFT_EXPR:
|
||||
/* If this is a fixed-point operation, then we cannot use the code
|
||||
below because "expand_shift" doesn't support sat/no-sat fixed-point
|
||||
shifts. */
|
||||
|
@ -9886,13 +9886,18 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||
is a rotate of A by B bits. */
|
||||
{
|
||||
enum tree_code code0, code1;
|
||||
tree rtype;
|
||||
code0 = TREE_CODE (arg0);
|
||||
code1 = TREE_CODE (arg1);
|
||||
if (((code0 == RSHIFT_EXPR && code1 == LSHIFT_EXPR)
|
||||
|| (code1 == RSHIFT_EXPR && code0 == LSHIFT_EXPR))
|
||||
&& operand_equal_p (TREE_OPERAND (arg0, 0),
|
||||
TREE_OPERAND (arg1, 0), 0)
|
||||
&& TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
|
||||
&& (rtype = TREE_TYPE (TREE_OPERAND (arg0, 0)),
|
||||
TYPE_UNSIGNED (rtype))
|
||||
/* Only create rotates in complete modes. Other cases are not
|
||||
expanded properly. */
|
||||
&& TYPE_PRECISION (rtype) == GET_MODE_PRECISION (TYPE_MODE (rtype)))
|
||||
{
|
||||
tree tree01, tree11;
|
||||
enum tree_code code01, code11;
|
||||
@ -11636,7 +11641,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||
if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
|
||||
{
|
||||
tree tem = build_int_cst (TREE_TYPE (arg1),
|
||||
GET_MODE_BITSIZE (TYPE_MODE (type)));
|
||||
TYPE_PRECISION (type));
|
||||
tem = const_binop (MINUS_EXPR, tem, arg1, 0);
|
||||
return fold_build2 (RROTATE_EXPR, type, op0, tem);
|
||||
}
|
||||
@ -11655,8 +11660,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||
fold_build2 (code, type,
|
||||
TREE_OPERAND (arg0, 1), arg1));
|
||||
|
||||
/* Two consecutive rotates adding up to the width of the mode can
|
||||
be ignored. */
|
||||
/* Two consecutive rotates adding up to the precision of the
|
||||
type can be ignored. */
|
||||
if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
|
||||
&& TREE_CODE (arg0) == RROTATE_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
|
||||
@ -11664,7 +11669,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||
&& TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0
|
||||
&& ((TREE_INT_CST_LOW (arg1)
|
||||
+ TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)))
|
||||
== (unsigned int) GET_MODE_BITSIZE (TYPE_MODE (type))))
|
||||
== (unsigned int) TYPE_PRECISION (type)))
|
||||
return TREE_OPERAND (arg0, 0);
|
||||
|
||||
/* Fold (X & C2) << C1 into (X << C1) & (C2 << C1)
|
||||
|
@ -1,3 +1,8 @@
|
||||
2008-02-27 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/34971
|
||||
* gcc.c-torture/execute/pr34971.c: New testcase.
|
||||
|
||||
2008-02-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.dg/gomp/preprocess-1.c: New test.
|
||||
|
22
gcc/testsuite/gcc.c-torture/execute/pr34971.c
Normal file
22
gcc/testsuite/gcc.c-torture/execute/pr34971.c
Normal file
@ -0,0 +1,22 @@
|
||||
struct foo
|
||||
{
|
||||
unsigned long long b:40;
|
||||
} x;
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
void test1(unsigned long long res)
|
||||
{
|
||||
/* Build a rotate expression on a 40 bit argument. */
|
||||
if ((x.b<<8) + (x.b>>32) != res)
|
||||
abort ();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
x.b = 0x0100000001;
|
||||
test1(0x0000000101);
|
||||
x.b = 0x0100000000;
|
||||
test1(0x0000000001);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user