diff options
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 53 |
1 files changed, 25 insertions, 28 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 296b7ec24b8..2a5665f1865 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -58,7 +58,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "md5.h" #include "gimple.h" -#include "tree-ssa.h" +#include "tree-dfa.h" /* Nonzero if we are folding constants inside an initializer; zero otherwise. */ @@ -2716,10 +2716,11 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) case COMPONENT_REF: /* Handle operand 2 the same as for ARRAY_REF. Operand 0 may be NULL when we're called to compare MEM_EXPRs. */ - if (!OP_SAME_WITH_NULL (0)) + if (!OP_SAME_WITH_NULL (0) + || !OP_SAME (1)) return 0; flags &= ~OEP_CONSTANT_ADDRESS_OF; - return OP_SAME (1) && OP_SAME_WITH_NULL (2); + return OP_SAME_WITH_NULL (2); case BIT_FIELD_REF: if (!OP_SAME (0)) @@ -3473,11 +3474,6 @@ optimize_bit_field_compare (location_t loc, enum tree_code code, tree mask; tree offset; - /* In the strict volatile bitfields case, doing code changes here may prevent - other optimizations, in particular in a SLOW_BYTE_ACCESS setting. */ - if (flag_strict_volatile_bitfields > 0) - return 0; - /* Get all the information about the extractions being done. If the bit size if the same as the size of the underlying object, we aren't doing an extraction at all and so can do nothing. We also don't want to @@ -3486,7 +3482,7 @@ optimize_bit_field_compare (location_t loc, enum tree_code code, linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode, &lunsignedp, &lvolatilep, false); if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0 - || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR) + || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR || lvolatilep) return 0; if (!const_p) @@ -3498,22 +3494,17 @@ optimize_bit_field_compare (location_t loc, enum tree_code code, if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize || lunsignedp != runsignedp || offset != 0 - || TREE_CODE (rinner) == PLACEHOLDER_EXPR) + || TREE_CODE (rinner) == PLACEHOLDER_EXPR || rvolatilep) return 0; } /* See if we can find a mode to refer to this field. We should be able to, but fail if we can't. */ - if (lvolatilep - && GET_MODE_BITSIZE (lmode) > 0 - && flag_strict_volatile_bitfields > 0) - nmode = lmode; - else - nmode = get_best_mode (lbitsize, lbitpos, 0, 0, - const_p ? TYPE_ALIGN (TREE_TYPE (linner)) - : MIN (TYPE_ALIGN (TREE_TYPE (linner)), - TYPE_ALIGN (TREE_TYPE (rinner))), - word_mode, lvolatilep || rvolatilep); + nmode = get_best_mode (lbitsize, lbitpos, 0, 0, + const_p ? TYPE_ALIGN (TREE_TYPE (linner)) + : MIN (TYPE_ALIGN (TREE_TYPE (linner)), + TYPE_ALIGN (TREE_TYPE (rinner))), + word_mode, false); if (nmode == VOIDmode) return 0; @@ -3602,11 +3593,6 @@ optimize_bit_field_compare (location_t loc, enum tree_code code, appropriate number of bits and mask it with the computed mask (in case this was a signed field). If we changed it, make a new one. */ lhs = make_bit_field_ref (loc, linner, unsigned_type, nbitsize, nbitpos, 1); - if (lvolatilep) - { - TREE_SIDE_EFFECTS (lhs) = 1; - TREE_THIS_VOLATILE (lhs) = 1; - } rhs = const_binop (BIT_AND_EXPR, const_binop (LSHIFT_EXPR, @@ -4954,12 +4940,16 @@ fold_range_test (location_t loc, enum tree_code code, tree type, int in0_p, in1_p, in_p; tree low0, low1, low, high0, high1, high; bool strict_overflow_p = false; - tree lhs = make_range (op0, &in0_p, &low0, &high0, &strict_overflow_p); - tree rhs = make_range (op1, &in1_p, &low1, &high1, &strict_overflow_p); - tree tem; + tree tem, lhs, rhs; const char * const warnmsg = G_("assuming signed overflow does not occur " "when simplifying range test"); + if (!INTEGRAL_TYPE_P (type)) + return 0; + + lhs = make_range (op0, &in0_p, &low0, &high0, &strict_overflow_p); + rhs = make_range (op1, &in1_p, &low1, &high1, &strict_overflow_p); + /* If this is an OR operation, invert both sides; we will invert again at the end. */ if (or_op) @@ -10949,6 +10939,13 @@ fold_binary_loc (location_t loc, fold_build2_loc (loc, MULT_EXPR, type, build_int_cst (type, 2) , arg1)); + /* ((T) (X /[ex] C)) * C cancels out if the conversion is + sign-changing only. */ + if (TREE_CODE (arg1) == INTEGER_CST + && TREE_CODE (arg0) == EXACT_DIV_EXPR + && operand_equal_p (arg1, TREE_OPERAND (arg0, 1), 0)) + return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); + strict_overflow_p = false; if (TREE_CODE (arg1) == INTEGER_CST && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE, |