X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ffold-const.c;h=292b89f94961274532569b11c99ab4093131f246;hb=41ad616dd2b78a0c53a488448d00ad7a20c35153;hp=d754bee25817da8aa925a6ba25ec3abe800c4d73;hpb=03a7d9e96c2162143894318f0a6a9f48a8adda71;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/fold-const.c b/gcc/fold-const.c index d754bee2581..292b89f9496 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -206,15 +206,9 @@ fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, { unsigned HOST_WIDE_INT low0 = l1; HOST_WIDE_INT high0 = h1; - unsigned int prec; + unsigned int prec = TYPE_PRECISION (type); int sign_extended_type; - if (POINTER_TYPE_P (type) - || TREE_CODE (type) == OFFSET_TYPE) - prec = POINTER_SIZE; - else - prec = TYPE_PRECISION (type); - /* Size types *are* sign extended. */ sign_extended_type = (!TYPE_UNSIGNED (type) || (TREE_CODE (type) == INTEGER_TYPE @@ -332,13 +326,17 @@ add_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, HOST_WIDE_INT h; l = l1 + l2; - h = h1 + h2 + (l < l1); + h = (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) h1 + + (unsigned HOST_WIDE_INT) h2 + + (l < l1)); *lv = l; *hv = h; if (unsigned_p) - return (unsigned HOST_WIDE_INT) h < (unsigned HOST_WIDE_INT) h1; + return ((unsigned HOST_WIDE_INT) h < (unsigned HOST_WIDE_INT) h1 + || (h == h1 + && l < l1)); else return OVERFLOW_SUM_SIGN (h1, h2, h); } @@ -887,22 +885,18 @@ div_if_zero_remainder (enum tree_code code, const_tree arg1, const_tree arg2) HOST_WIDE_INT int1h, int2h; unsigned HOST_WIDE_INT quol, reml; HOST_WIDE_INT quoh, remh; - tree type = TREE_TYPE (arg1); - int uns = TYPE_UNSIGNED (type); + int uns; + + /* The sign of the division is according to operand two, that + does the correct thing for POINTER_PLUS_EXPR where we want + a signed division. */ + uns = TYPE_UNSIGNED (TREE_TYPE (arg2)); + if (TREE_CODE (TREE_TYPE (arg2)) == INTEGER_TYPE + && TYPE_IS_SIZETYPE (TREE_TYPE (arg2))) + uns = false; int1l = TREE_INT_CST_LOW (arg1); int1h = TREE_INT_CST_HIGH (arg1); - /* &obj[0] + -128 really should be compiled as &obj[-8] rather than - &obj[some_exotic_number]. */ - if (POINTER_TYPE_P (type)) - { - uns = false; - type = signed_type_for (type); - fit_double_type (int1l, int1h, &int1l, &int1h, - type); - } - else - fit_double_type (int1l, int1h, &int1l, &int1h, type); int2l = TREE_INT_CST_LOW (arg2); int2h = TREE_INT_CST_HIGH (arg2); @@ -911,7 +905,7 @@ div_if_zero_remainder (enum tree_code code, const_tree arg1, const_tree arg2) if (remh != 0 || reml != 0) return NULL_TREE; - return build_int_cst_wide (type, quol, quoh); + return build_int_cst_wide (TREE_TYPE (arg1), quol, quoh); } /* This is nonzero if we should defer warnings about undefined @@ -1070,7 +1064,7 @@ negate_mathfn_p (enum built_in_function code) CASE_FLT_FN (BUILT_IN_NEARBYINT): CASE_FLT_FN (BUILT_IN_RINT): return !flag_rounding_math; - + default: break; } @@ -1135,10 +1129,14 @@ negate_expr_p (tree t) && TYPE_OVERFLOW_WRAPS (type)); case FIXED_CST: - case REAL_CST: case NEGATE_EXPR: return true; + case REAL_CST: + /* We want to canonicalize to positive real constants. Pretend + that only negative ones can be easily negated. */ + return REAL_VALUE_NEGATIVE (TREE_REAL_CST (t)); + case COMPLEX_CST: return negate_expr_p (TREE_REALPART (t)) && negate_expr_p (TREE_IMAGPART (t)); @@ -1250,7 +1248,7 @@ fold_negate_expr (location_t loc, tree t) return fold_build2_loc (loc, PLUS_EXPR, type, TREE_OPERAND (t, 0), build_int_cst (type, 1)); break; - + case INTEGER_CST: tem = fold_negate_const (t, type); if (TREE_OVERFLOW (tem) == TREE_OVERFLOW (t) @@ -1288,7 +1286,7 @@ fold_negate_expr (location_t loc, tree t) fold_negate_expr (loc, TREE_OPERAND (t, 0)), fold_negate_expr (loc, TREE_OPERAND (t, 1))); break; - + case CONJ_EXPR: if (negate_expr_p (t)) return fold_build1_loc (loc, CONJ_EXPR, type, @@ -1972,12 +1970,10 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) break; case MULT_EXPR: -#ifdef HAVE_mpc if (COMPLEX_FLOAT_TYPE_P (type)) return do_mpc_arg2 (arg1, arg2, type, /* do_nonfinite= */ folding_initializer, mpc_mul); -#endif real = const_binop (MINUS_EXPR, const_binop (MULT_EXPR, r1, r2, notrunc), @@ -1990,14 +1986,11 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) break; case RDIV_EXPR: -#ifdef HAVE_mpc if (COMPLEX_FLOAT_TYPE_P (type)) return do_mpc_arg2 (arg1, arg2, type, /* do_nonfinite= */ folding_initializer, mpc_div); /* Fallthru ... */ -#endif - case TRUNC_DIV_EXPR: case CEIL_DIV_EXPR: case FLOOR_DIV_EXPR: @@ -2037,10 +2030,10 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) Expand complex division to scalars, modified algorithm to minimize overflow with wide input ranges. */ - tree inner_type = TREE_TYPE (type); - tree absr2 = fold_build1 (ABS_EXPR, inner_type, r2); - tree absi2 = fold_build1 (ABS_EXPR, inner_type, i2); - tree compare = fold_build2 (LT_EXPR, boolean_type_node, absr2, absi2); + tree compare = fold_build2 (LT_EXPR, boolean_type_node, + fold_abs_const (r2, TREE_TYPE (type)), + fold_abs_const (i2, TREE_TYPE (type))); + if (integer_nonzerop (compare)) { /* In the TRUE branch, we compute @@ -2050,17 +2043,18 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) ti = (ai * ratio) - ar; tr = tr / div; ti = ti / div; */ - tree ratio = fold_build2 (code, inner_type, r2, i2); - tree div = fold_build2 (PLUS_EXPR, inner_type, i2, - fold_build2 (MULT_EXPR, inner_type, - r2, ratio)); - real = fold_build2 (MULT_EXPR, inner_type, r1, ratio); - real = fold_build2 (PLUS_EXPR, inner_type, real, i1); - real = fold_build2 (code, inner_type, real, div); - - imag = fold_build2 (MULT_EXPR, inner_type, i1, ratio); - imag = fold_build2 (MINUS_EXPR, inner_type, imag, r1); - imag = fold_build2 (code, inner_type, imag, div); + tree ratio = const_binop (code, r2, i2, notrunc); + tree div = const_binop (PLUS_EXPR, i2, + const_binop (MULT_EXPR, r2, ratio, + notrunc), + notrunc); + real = const_binop (MULT_EXPR, r1, ratio, notrunc); + real = const_binop (PLUS_EXPR, real, i1, notrunc); + real = const_binop (code, real, div, notrunc); + + imag = const_binop (MULT_EXPR, i1, ratio, notrunc); + imag = const_binop (MINUS_EXPR, imag, r1, notrunc); + imag = const_binop (code, imag, div, notrunc); } else { @@ -2071,18 +2065,19 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) ti = b - (a * ratio); tr = tr / div; ti = ti / div; */ - tree ratio = fold_build2 (code, inner_type, i2, r2); - tree div = fold_build2 (PLUS_EXPR, inner_type, r2, - fold_build2 (MULT_EXPR, inner_type, - i2, ratio)); - - real = fold_build2 (MULT_EXPR, inner_type, i1, ratio); - real = fold_build2 (PLUS_EXPR, inner_type, real, r1); - real = fold_build2 (code, inner_type, real, div); - - imag = fold_build2 (MULT_EXPR, inner_type, r1, ratio); - imag = fold_build2 (MINUS_EXPR, inner_type, i1, imag); - imag = fold_build2 (code, inner_type, imag, div); + tree ratio = const_binop (code, i2, r2, notrunc); + tree div = const_binop (PLUS_EXPR, r2, + const_binop (MULT_EXPR, i2, ratio, + notrunc), + notrunc); + + real = const_binop (MULT_EXPR, i1, ratio, notrunc); + real = const_binop (PLUS_EXPR, real, r1, notrunc); + real = const_binop (code, real, div, notrunc); + + imag = const_binop (MULT_EXPR, r1, ratio, notrunc); + imag = const_binop (MINUS_EXPR, i1, imag, notrunc); + imag = const_binop (code, imag, div, notrunc); } } break; @@ -2100,17 +2095,17 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) tree type = TREE_TYPE(arg1); int count = TYPE_VECTOR_SUBPARTS (type), i; tree elements1, elements2, list = NULL_TREE; - + if(TREE_CODE(arg2) != VECTOR_CST) return NULL_TREE; - + elements1 = TREE_VECTOR_CST_ELTS (arg1); elements2 = TREE_VECTOR_CST_ELTS (arg2); for (i = 0; i < count; i++) { tree elem1, elem2, elem; - + /* The trailing elements can be empty and should be treated as 0 */ if(!elements1) elem1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node); @@ -2118,8 +2113,8 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) { elem1 = TREE_VALUE(elements1); elements1 = TREE_CHAIN (elements1); - } - + } + if(!elements2) elem2 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node); else @@ -2127,17 +2122,17 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) elem2 = TREE_VALUE(elements2); elements2 = TREE_CHAIN (elements2); } - + elem = const_binop (code, elem1, elem2, notrunc); - + /* It is possible that const_binop cannot handle the given code and return NULL_TREE */ if(elem == NULL_TREE) return NULL_TREE; - + list = tree_cons (NULL_TREE, elem, list); } - return build_vector(type, nreverse(list)); + return build_vector(type, nreverse(list)); } return NULL_TREE; } @@ -2577,7 +2572,7 @@ build_zero_vector (tree type) elem = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node); units = TYPE_VECTOR_SUBPARTS (type); - + list = NULL_TREE; for (i = 0; i < units; i++) list = tree_cons (NULL_TREE, elem, list); @@ -2647,8 +2642,16 @@ fold_convert_loc (location_t loc, tree type, tree arg) switch (TREE_CODE (type)) { + case POINTER_TYPE: + case REFERENCE_TYPE: + /* Handle conversions between pointers to different address spaces. */ + if (POINTER_TYPE_P (orig) + && (TYPE_ADDR_SPACE (TREE_TYPE (type)) + != TYPE_ADDR_SPACE (TREE_TYPE (orig)))) + return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, arg); + /* fall through */ + case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: - case POINTER_TYPE: case REFERENCE_TYPE: case OFFSET_TYPE: if (TREE_CODE (arg) == INTEGER_CST) { @@ -2830,8 +2833,6 @@ maybe_lvalue_p (const_tree x) case TARGET_EXPR: case COND_EXPR: case BIND_EXPR: - case MIN_EXPR: - case MAX_EXPR: break; default: @@ -3164,7 +3165,9 @@ int operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) { /* If either is ERROR_MARK, they aren't equal. */ - if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK) + if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK + || TREE_TYPE (arg0) == error_mark_node + || TREE_TYPE (arg1) == error_mark_node) return 0; /* Check equality of integer constants before bailing out due to @@ -3181,6 +3184,12 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) || POINTER_TYPE_P (TREE_TYPE (arg0)) != POINTER_TYPE_P (TREE_TYPE (arg1))) return 0; + /* We cannot consider pointers to different address space equal. */ + if (POINTER_TYPE_P (TREE_TYPE (arg0)) && POINTER_TYPE_P (TREE_TYPE (arg1)) + && (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0))) + != TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg1))))) + return 0; + /* If both types don't have the same precision, then it is not safe to strip NOPs. */ if (TYPE_PRECISION (TREE_TYPE (arg0)) != TYPE_PRECISION (TREE_TYPE (arg1))) @@ -3242,7 +3251,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) TREE_REAL_CST (arg1))) return 1; - + if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))) { /* If we do not distinguish between signed and unsigned zero, @@ -3401,7 +3410,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) case COND_EXPR: return OP_SAME (0) && OP_SAME (1) && OP_SAME (2); - + default: return 0; } @@ -4118,7 +4127,7 @@ make_bit_field_ref (location_t loc, tree inner, tree type, tree size = TYPE_SIZE (TREE_TYPE (inner)); if ((INTEGRAL_TYPE_P (TREE_TYPE (inner)) || POINTER_TYPE_P (TREE_TYPE (inner))) - && host_integerp (size, 0) + && host_integerp (size, 0) && tree_low_cst (size, 0) == bitsize) return fold_convert_loc (loc, type, inner); } @@ -5528,7 +5537,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type, tem = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (arg00), arg00, fold_convert_loc (loc, TREE_TYPE (arg00), arg2)); - return pedantic_non_lvalue_loc (loc, + return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, tem)); } break; @@ -6512,7 +6521,19 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, /* If this was a subtraction, negate OP1 and set it to be an addition. This simplifies the logic below. */ if (tcode == MINUS_EXPR) - tcode = PLUS_EXPR, op1 = negate_expr (op1); + { + tcode = PLUS_EXPR, op1 = negate_expr (op1); + /* If OP1 was not easily negatable, the constant may be OP0. */ + if (TREE_CODE (op0) == INTEGER_CST) + { + tree tem = op0; + op0 = op1; + op1 = tem; + tem = t1; + t1 = t2; + t2 = tem; + } + } if (TREE_CODE (op1) != INTEGER_CST) break; @@ -7251,7 +7272,7 @@ fold_single_bit_test (location_t loc, enum tree_code code, operations as unsigned. If we must use the AND, we have a choice. Normally unsigned is faster, but for some machines signed is. */ #ifdef LOAD_EXTEND_OP - ops_unsigned = (LOAD_EXTEND_OP (operand_mode) == SIGN_EXTEND + ops_unsigned = (LOAD_EXTEND_OP (operand_mode) == SIGN_EXTEND && !flag_syntax_only) ? 0 : 1; #else ops_unsigned = 1; @@ -7536,7 +7557,7 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1) STRIP_NOPS (arg0); STRIP_NOPS (arg1); - + if (TREE_CODE (arg0) == INTEGER_CST) { s = arg0; @@ -7566,13 +7587,16 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1) { if (TREE_CODE (ref) == ARRAY_REF) { + tree domain; + /* Remember if this was a multi-dimensional array. */ if (TREE_CODE (TREE_OPERAND (ref, 0)) == ARRAY_REF) mdim = true; - itype = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0))); - if (! itype) + domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0))); + if (! domain) continue; + itype = TREE_TYPE (domain); step = array_ref_element_size (ref); if (TREE_CODE (step) != INTEGER_CST) @@ -7599,18 +7623,17 @@ try_move_mult_to_index (location_t loc, tree addr, tree op1) tree tmp; if (TREE_CODE (TREE_OPERAND (ref, 1)) != INTEGER_CST - || !INTEGRAL_TYPE_P (itype) - || !TYPE_MAX_VALUE (itype) - || TREE_CODE (TYPE_MAX_VALUE (itype)) != INTEGER_CST) + || !TYPE_MAX_VALUE (domain) + || TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST) continue; tmp = fold_binary_loc (loc, PLUS_EXPR, itype, - fold_convert_loc (loc, itype, - TREE_OPERAND (ref, 1)), - fold_convert_loc (loc, itype, delta)); + fold_convert_loc (loc, itype, + TREE_OPERAND (ref, 1)), + fold_convert_loc (loc, itype, delta)); if (!tmp || TREE_CODE (tmp) != INTEGER_CST - || tree_int_cst_lt (TYPE_MAX_VALUE (itype), tmp)) + || tree_int_cst_lt (TYPE_MAX_VALUE (domain), tmp)) continue; } @@ -8425,7 +8448,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) case FIX_TRUNC_EXPR: if (TREE_TYPE (op0) == type) return op0; - + /* If we have (type) (a CMP b) and type is an integral type, return new expression involving the new type. */ if (COMPARISON_CLASS_P (op0) && INTEGRAL_TYPE_P (type)) @@ -8672,6 +8695,11 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) tem = fold_convert_const (code, type, op0); return tem ? tem : NULL_TREE; + case ADDR_SPACE_CONVERT_EXPR: + if (integer_zerop (arg0)) + return fold_convert_const (code, type, arg0); + return NULL_TREE; + case FIXED_CONVERT_EXPR: tem = fold_convert_const (code, type, arg0); return tem ? tem : NULL_TREE; @@ -8924,6 +8952,19 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) } return NULL_TREE; + case INDIRECT_REF: + /* Fold *&X to X if X is an lvalue. */ + if (TREE_CODE (op0) == ADDR_EXPR) + { + tree op00 = TREE_OPERAND (op0, 0); + if ((TREE_CODE (op00) == VAR_DECL + || TREE_CODE (op00) == PARM_DECL + || TREE_CODE (op00) == RESULT_DECL) + && !TREE_READONLY (op00)) + return op00; + } + return NULL_TREE; + default: return NULL_TREE; } /* switch (code) */ @@ -9352,7 +9393,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type, && (code == EQ_EXPR || code == NE_EXPR || POINTER_TYPE_OVERFLOW_UNDEFINED)) - + { if (code != EQ_EXPR && code != NE_EXPR @@ -9627,7 +9668,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type, /* Likewise, we can simplify a comparison of a real constant with a MINUS_EXPR whose first operand is also a real constant, i.e. - (c1 - x) < c2 becomes x > c1-c2. Reordering is allowed on + (c1 - x) < c2 becomes x > c1-c2. Reordering is allowed on floating-point types only if -fassociative-math is set. */ if (flag_associative_math && TREE_CODE (arg1) == REAL_CST @@ -9951,7 +9992,7 @@ get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue, tree op0, op1; unsigned HOST_WIDE_INT modulus; enum tree_code inner_code; - + op0 = TREE_OPERAND (expr, 0); STRIP_NOPS (op0); modulus = get_pointer_modulus_and_residue (op0, residue, @@ -9971,7 +10012,7 @@ get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue, if (TREE_CODE (op1) == INTEGER_CST) { unsigned HOST_WIDE_INT align; - + /* Compute the greatest power-of-2 divisor of op1. */ align = TREE_INT_CST_LOW (op1); align &= -align; @@ -10124,7 +10165,6 @@ fold_binary_loc (location_t loc, tem = fold_build2_loc (loc, code, type, fold_convert_loc (loc, TREE_TYPE (op0), TREE_OPERAND (arg0, 1)), op1); - protected_set_expr_location (tem, loc); tem = build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0), tem); goto fold_binary_exit; } @@ -10134,7 +10174,6 @@ fold_binary_loc (location_t loc, tem = fold_build2_loc (loc, code, type, op0, fold_convert_loc (loc, TREE_TYPE (op1), TREE_OPERAND (arg1, 1))); - protected_set_expr_location (tem, loc); tem = build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0), tem); goto fold_binary_exit; } @@ -10142,7 +10181,7 @@ fold_binary_loc (location_t loc, if (TREE_CODE (arg0) == COND_EXPR || COMPARISON_CLASS_P (arg0)) { tem = fold_binary_op_with_conditional_arg (loc, code, type, op0, op1, - arg0, arg1, + arg0, arg1, /*cond_first_p=*/1); if (tem != NULL_TREE) return tem; @@ -10151,7 +10190,7 @@ fold_binary_loc (location_t loc, if (TREE_CODE (arg1) == COND_EXPR || COMPARISON_CLASS_P (arg1)) { tem = fold_binary_op_with_conditional_arg (loc, code, type, op0, op1, - arg1, arg0, + arg1, arg0, /*cond_first_p=*/0); if (tem != NULL_TREE) return tem; @@ -10433,7 +10472,7 @@ fold_binary_loc (location_t loc, return fold_build2_loc (loc, MULT_EXPR, type, arg0, build_real (type, dconst2)); - /* Convert a + (b*c + d*e) into (a + b*c) + d*e. + /* Convert a + (b*c + d*e) into (a + b*c) + d*e. We associate floats only if the user has specified -fassociative-math. */ if (flag_associative_math @@ -10450,7 +10489,7 @@ fold_binary_loc (location_t loc, return fold_build2_loc (loc, PLUS_EXPR, type, tree0, tree11); } } - /* Convert (b*c + d*e) + a into b*c + (d*e +a). + /* Convert (b*c + d*e) + a into b*c + (d*e +a). We associate floats only if the user has specified -fassociative-math. */ if (flag_associative_math @@ -10886,7 +10925,7 @@ fold_binary_loc (location_t loc, tree diff = build2 (MINUS_EXPR, type, op0, op1); return fold_build2_loc (loc, MULT_EXPR, type, diff, fold_convert_loc (loc, type, esz)); - + } } @@ -11265,7 +11304,7 @@ fold_binary_loc (location_t loc, if (width > HOST_BITS_PER_WIDE_INT) { - mhi = (unsigned HOST_WIDE_INT) -1 + mhi = (unsigned HOST_WIDE_INT) -1 >> (2 * HOST_BITS_PER_WIDE_INT - width); mlo = -1; } @@ -11452,7 +11491,7 @@ fold_binary_loc (location_t loc, fold_convert_loc (loc, type, t1)); return t1; } - + /* Convert ~X ^ ~Y to X ^ Y. */ if (TREE_CODE (arg0) == BIT_NOT_EXPR && TREE_CODE (arg1) == BIT_NOT_EXPR) @@ -11482,7 +11521,7 @@ fold_binary_loc (location_t loc, && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0)) { tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); - return fold_build2_loc (loc, BIT_AND_EXPR, type, + return fold_build2_loc (loc, BIT_AND_EXPR, type, fold_build1_loc (loc, BIT_NOT_EXPR, type, tem), fold_convert_loc (loc, type, arg1)); } @@ -11601,7 +11640,7 @@ fold_binary_loc (location_t loc, && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0)) { tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); - return fold_build2_loc (loc, BIT_AND_EXPR, type, + return fold_build2_loc (loc, BIT_AND_EXPR, type, fold_build1_loc (loc, BIT_NOT_EXPR, type, tem), fold_convert_loc (loc, type, arg1)); } @@ -11866,7 +11905,7 @@ fold_binary_loc (location_t loc, } } } - /* Convert A/B/C to A/(B*C). */ + /* Convert A/B/C to A/(B*C). */ if (flag_reciprocal_math && TREE_CODE (arg0) == RDIV_EXPR) return fold_build2_loc (loc, RDIV_EXPR, type, TREE_OPERAND (arg0, 0), @@ -12604,6 +12643,11 @@ fold_binary_loc (location_t loc, return fold_build1_loc (loc, TRUTH_NOT_EXPR, type, fold_convert_loc (loc, type, arg0)); + /* !exp != 0 becomes !exp */ + if (TREE_CODE (arg0) == TRUTH_NOT_EXPR && integer_zerop (arg1) + && code == NE_EXPR) + return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0)); + /* If this is an equality comparison of the address of two non-weak, unaliased symbols neither of which are extern (since we do not have access to attributes for externs), then we know the result. */ @@ -14194,7 +14238,7 @@ fold_checksum_tree (const_tree expr, struct md5_ctx *ctx, htab_t ht) enum tree_code code; union tree_node buf; int i, len; - + recursive_label: gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree) @@ -14304,7 +14348,7 @@ recursive_label: } if (CODE_CONTAINS_STRUCT (TREE_CODE (expr), TS_DECL_WITH_VIS)) fold_checksum_tree (DECL_SECTION_NAME (expr), ctx, ht); - + if (CODE_CONTAINS_STRUCT (TREE_CODE (expr), TS_DECL_NON_COMMON)) { fold_checksum_tree (DECL_VINDEX (expr), ctx, ht); @@ -14349,7 +14393,7 @@ debug_fold_checksum (const_tree t) unsigned char checksum[16]; struct md5_ctx ctx; htab_t ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL); - + md5_init_ctx (&ctx); fold_checksum_tree (t, &ctx, ht); md5_finish_ctx (&ctx, checksum); @@ -14384,14 +14428,14 @@ fold_build1_stat_loc (location_t loc, md5_finish_ctx (&ctx, checksum_before); htab_empty (ht); #endif - + tem = fold_unary_loc (loc, code, type, op0); if (!tem) { tem = build1_stat (code, type, op0 PASS_MEM_STAT); SET_EXPR_LOCATION (tem, loc); } - + #ifdef ENABLE_FOLD_CHECKING md5_init_ctx (&ctx); fold_checksum_tree (op0, &ctx, ht); @@ -14442,7 +14486,7 @@ fold_build2_stat_loc (location_t loc, tem = build2_stat (code, type, op0, op1 PASS_MEM_STAT); SET_EXPR_LOCATION (tem, loc); } - + #ifdef ENABLE_FOLD_CHECKING md5_init_ctx (&ctx); fold_checksum_tree (op0, &ctx, ht); @@ -14451,7 +14495,7 @@ fold_build2_stat_loc (location_t loc, if (memcmp (checksum_before_op0, checksum_after_op0, 16)) fold_check_failed (op0, tem); - + md5_init_ctx (&ctx); fold_checksum_tree (op1, &ctx, ht); md5_finish_ctx (&ctx, checksum_after_op1); @@ -14507,7 +14551,7 @@ fold_build3_stat_loc (location_t loc, enum tree_code code, tree type, tem = build3_stat (code, type, op0, op1, op2 PASS_MEM_STAT); SET_EXPR_LOCATION (tem, loc); } - + #ifdef ENABLE_FOLD_CHECKING md5_init_ctx (&ctx); fold_checksum_tree (op0, &ctx, ht); @@ -14516,7 +14560,7 @@ fold_build3_stat_loc (location_t loc, enum tree_code code, tree type, if (memcmp (checksum_before_op0, checksum_after_op0, 16)) fold_check_failed (op0, tem); - + md5_init_ctx (&ctx); fold_checksum_tree (op1, &ctx, ht); md5_finish_ctx (&ctx, checksum_after_op1); @@ -14524,7 +14568,7 @@ fold_build3_stat_loc (location_t loc, enum tree_code code, tree type, if (memcmp (checksum_before_op1, checksum_after_op1, 16)) fold_check_failed (op1, tem); - + md5_init_ctx (&ctx); fold_checksum_tree (op2, &ctx, ht); md5_finish_ctx (&ctx, checksum_after_op2); @@ -14569,7 +14613,7 @@ fold_build_call_array_loc (location_t loc, tree type, tree fn, #endif tem = fold_builtin_call_array (loc, type, fn, nargs, argarray); - + #ifdef ENABLE_FOLD_CHECKING md5_init_ctx (&ctx); fold_checksum_tree (fn, &ctx, ht); @@ -14578,7 +14622,7 @@ fold_build_call_array_loc (location_t loc, tree type, tree fn, if (memcmp (checksum_before_fn, checksum_after_fn, 16)) fold_check_failed (fn, tem); - + md5_init_ctx (&ctx); for (i = 0; i < nargs; i++) fold_checksum_tree (argarray[i], &ctx, ht); @@ -14924,10 +14968,10 @@ tree_binary_nonnegative_warnv_p (enum tree_code code, tree type, tree op0, && (TREE_CODE (op0) == NOP_EXPR || TREE_CODE (op0) == INTEGER_CST) && (TREE_CODE (op1) == NOP_EXPR || TREE_CODE (op1) == INTEGER_CST)) { - tree inner0 = (TREE_CODE (op0) == NOP_EXPR) + tree inner0 = (TREE_CODE (op0) == NOP_EXPR) ? TREE_TYPE (TREE_OPERAND (op0, 0)) : TREE_TYPE (op0); - tree inner1 = (TREE_CODE (op1) == NOP_EXPR) + tree inner1 = (TREE_CODE (op1) == NOP_EXPR) ? TREE_TYPE (TREE_OPERAND (op1, 0)) : TREE_TYPE (op1); @@ -15975,7 +16019,7 @@ fold_build_cleanup_point_expr (tree type, tree expr) if (!TREE_SIDE_EFFECTS (op)) return expr; } - + return build1 (CLEANUP_POINT_EXPR, type, expr); } @@ -16039,17 +16083,17 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF */ if (TREE_CODE (sub) == POINTER_PLUS_EXPR && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST) - { + { tree op00 = TREE_OPERAND (sub, 0); tree op01 = TREE_OPERAND (sub, 1); tree op00type; - + STRIP_NOPS (op00); op00type = TREE_TYPE (op00); if (TREE_CODE (op00) == ADDR_EXPR && TREE_CODE (TREE_TYPE (op00type)) == VECTOR_TYPE && type == TREE_TYPE (TREE_TYPE (op00type))) - { + { HOST_WIDE_INT offset = tree_low_cst (op01, 0); tree part_width = TYPE_SIZE (type); unsigned HOST_WIDE_INT part_widthi = tree_low_cst (part_width, 0)/BITS_PER_UNIT; @@ -16060,7 +16104,7 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) return fold_build3_loc (loc, BIT_FIELD_REF, type, TREE_OPERAND (op00, 0), part_width, index); - + } } @@ -16085,7 +16129,7 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) TREE_OPERAND (op00, 0)); } } - + /* *(foo *)fooarrptr => (*fooarrptr)[0] */ if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE && type == TREE_TYPE (TREE_TYPE (subtype))) @@ -16409,7 +16453,7 @@ fold_strip_sign_ops (tree exp) if (arg1) return fold_build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (exp), arg0, arg1); break; - + case COND_EXPR: arg0 = fold_strip_sign_ops (TREE_OPERAND (exp, 1)); arg1 = fold_strip_sign_ops (TREE_OPERAND (exp, 2)); @@ -16419,7 +16463,7 @@ fold_strip_sign_ops (tree exp) arg0 ? arg0 : TREE_OPERAND (exp, 1), arg1 ? arg1 : TREE_OPERAND (exp, 2)); break; - + case CALL_EXPR: { const enum built_in_function fcode = builtin_mathfn_code (exp);