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>
|
2008-02-27 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* c-ppoutput.c (scan_translation_unit): Handle CPP_PRAGMA
|
* 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:
|
case BIT_XOR_EXPR:
|
||||||
goto binop;
|
goto binop;
|
||||||
|
|
||||||
case LSHIFT_EXPR:
|
|
||||||
case RSHIFT_EXPR:
|
|
||||||
case LROTATE_EXPR:
|
case LROTATE_EXPR:
|
||||||
case RROTATE_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
|
/* 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
|
below because "expand_shift" doesn't support sat/no-sat fixed-point
|
||||||
shifts. */
|
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. */
|
is a rotate of A by B bits. */
|
||||||
{
|
{
|
||||||
enum tree_code code0, code1;
|
enum tree_code code0, code1;
|
||||||
|
tree rtype;
|
||||||
code0 = TREE_CODE (arg0);
|
code0 = TREE_CODE (arg0);
|
||||||
code1 = TREE_CODE (arg1);
|
code1 = TREE_CODE (arg1);
|
||||||
if (((code0 == RSHIFT_EXPR && code1 == LSHIFT_EXPR)
|
if (((code0 == RSHIFT_EXPR && code1 == LSHIFT_EXPR)
|
||||||
|| (code1 == RSHIFT_EXPR && code0 == LSHIFT_EXPR))
|
|| (code1 == RSHIFT_EXPR && code0 == LSHIFT_EXPR))
|
||||||
&& operand_equal_p (TREE_OPERAND (arg0, 0),
|
&& operand_equal_p (TREE_OPERAND (arg0, 0),
|
||||||
TREE_OPERAND (arg1, 0), 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;
|
tree tree01, tree11;
|
||||||
enum tree_code code01, code11;
|
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)
|
if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
|
||||||
{
|
{
|
||||||
tree tem = build_int_cst (TREE_TYPE (arg1),
|
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);
|
tem = const_binop (MINUS_EXPR, tem, arg1, 0);
|
||||||
return fold_build2 (RROTATE_EXPR, type, op0, tem);
|
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,
|
fold_build2 (code, type,
|
||||||
TREE_OPERAND (arg0, 1), arg1));
|
TREE_OPERAND (arg0, 1), arg1));
|
||||||
|
|
||||||
/* Two consecutive rotates adding up to the width of the mode can
|
/* Two consecutive rotates adding up to the precision of the
|
||||||
be ignored. */
|
type can be ignored. */
|
||||||
if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
|
if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
|
||||||
&& TREE_CODE (arg0) == RROTATE_EXPR
|
&& TREE_CODE (arg0) == RROTATE_EXPR
|
||||||
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
|
&& 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_HIGH (TREE_OPERAND (arg0, 1)) == 0
|
||||||
&& ((TREE_INT_CST_LOW (arg1)
|
&& ((TREE_INT_CST_LOW (arg1)
|
||||||
+ TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)))
|
+ 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);
|
return TREE_OPERAND (arg0, 0);
|
||||||
|
|
||||||
/* Fold (X & C2) << C1 into (X << C1) & (C2 << C1)
|
/* 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>
|
2008-02-27 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* gcc.dg/gomp/preprocess-1.c: New test.
|
* 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