From 70582b3afe47248d2b70c5731fb7cf44fa17dc16 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 27 Feb 2008 09:50:04 +0000 Subject: re PR middle-end/34971 (bitfield rotates are folded and expanded wrong) 2008-02-27 Richard Guenther 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 --- gcc/fold-const.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'gcc/fold-const.c') diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 1ecd225..f6a73ef 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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) -- cgit v1.1