From patchwork Tue May 7 06:14:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 241993 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id E01552C0156 for ; Tue, 7 May 2013 16:14:28 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; q=dns; s=default; b=VlhL8Jwv2oWKD5Yv yid7q2XBooZPFzbK5kJcRwnBcqfRHK/ru+9JBeQREU2MBRy+rJcAeMACuu7qjZ6j PQc6aQuA3ZHXss6VspSx/xifbZ7fynUXIKB0h4iuclNPO4s7mbGlkAblydf3b2AQ Ng4ANKop2WNBjf5zHmZ61/w5gFg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; s=default; bh=Rba3mWfppcs8mYNv0RuNw1 /Wv8s=; b=Q3z5+343mELm/aVjUnQPpvyowkiYQScV/n7B13LyFcUFE0LPqXurX1 HCMyc8D9rxWDVJIhXyBYqGewWx4z4EqkWQ8EYR3KWFosLhXDTFlYs2EO7XdxtNOv YcAuupzM40YwgxoaDC+CdYPI7Y7JkvAsNLnjkM+OUynpjH2yKD9K4= Received: (qmail 25241 invoked by alias); 7 May 2013 06:14:18 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 25196 invoked by uid 89); 7 May 2013 06:14:12 -0000 X-Spam-SWARE-Status: No, score=-6.3 required=5.0 tests=AWL, BAYES_00, KHOP_THREADED, RP_MATCHES_RCVD, TW_CP autolearn=ham version=3.3.1 Received: from mail3-relais-sop.national.inria.fr (HELO mail3-relais-sop.national.inria.fr) (192.134.164.104) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Tue, 07 May 2013 06:14:09 +0000 Received: from stedding.saclay.inria.fr ([193.55.250.194]) by mail3-relais-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES128-SHA; 07 May 2013 08:14:06 +0200 Received: from glisse (helo=localhost) by stedding.saclay.inria.fr with local-esmtp (Exim 4.80) (envelope-from ) id 1UZbA6-0008Cg-Gf; Tue, 07 May 2013 08:14:06 +0200 Date: Tue, 7 May 2013 08:14:06 +0200 (CEST) From: Marc Glisse To: Richard Biener cc: gcc-patches@gcc.gnu.org, Richard Biener Subject: all_ones vs minus_one (was: [PATCH] Loop distribution improvements) In-Reply-To: Message-ID: References: <20130404181758.GV4201@tucnak.redhat.com> <258422fc-fbe2-4dda-b246-93f6d651219e@email.android.com> <20130404185713.GW4201@tucnak.redhat.com> <20130405074406.GZ4201@tucnak.redhat.com> User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 X-Virus-Found: No On Thu, 2 May 2013, Richard Biener wrote: > Can you followup with a patch to do > s/integer_all_onesp/integer_minus_onep/ where it makes sense? This passes bootstrap+testsuite on x86_64-linux-gnu. I kept all_ones for bitmask type of operations (BIT_*_EXPR, VEC_COND_EXPR) and used minus_one for the maximal unsigned value. A few cases were not very clear and chosen rather randomly. There is one place in fold-const where we would actually want instead an integer_zero_or_all_onesp which checks whether each element of a vector (or complex) is 0 or -1, which would accept {-1,0,0,-1} for instance, but I didn't add that. 2013-05-07 Marc Glisse * convert.c (convert_to_integer): Replace integer_all_onesp with integer_minus_onep. * tree-ssa-loop-niter.c (number_of_iterations_lt, number_of_iterations_exit): Likewise. * predict.c (tree_predict_by_opcode): Likewise. * builtins.c (expand_builtin_memory_chk, maybe_emit_chk_warning, maybe_emit_sprintf_chk_warning, fold_builtin_memory_chk, fold_builtin_stxcpy_chk, fold_builtin_stxncpy_chk, fold_builtin_strcat_chk, fold_builtin_strncat_chk, fold_builtin_sprintf_chk_1, fold_builtin_snprintf_chk_1): Likewise. * fold-const.c (optimize_bit_field_compare, fold_unary_loc, fold_binary_loc): Likewise. * expr.c (do_store_flag): Likewise. * tree-ssa-phiopt.c (conditional_replacement): Likewise. Index: gcc/convert.c =================================================================== --- gcc/convert.c (revision 198662) +++ gcc/convert.c (working copy) @@ -643,21 +643,21 @@ convert_to_integer (tree type, tree expr we can't necessarily find a type to compare them in. */ && (TYPE_UNSIGNED (TREE_TYPE (arg0)) == TYPE_UNSIGNED (TREE_TYPE (arg1))) /* Do not change the sign of the division. */ && (TYPE_UNSIGNED (TREE_TYPE (expr)) == TYPE_UNSIGNED (TREE_TYPE (arg0))) /* Either require unsigned division or a division by a constant that is not -1. */ && (TYPE_UNSIGNED (TREE_TYPE (arg0)) || (TREE_CODE (arg1) == INTEGER_CST - && !integer_all_onesp (arg1)))) + && !integer_minus_onep (arg1)))) goto trunc1; break; } case MAX_EXPR: case MIN_EXPR: case MULT_EXPR: { tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type); tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type); Index: gcc/tree-ssa-loop-niter.c =================================================================== --- gcc/tree-ssa-loop-niter.c (revision 198662) +++ gcc/tree-ssa-loop-niter.c (working copy) @@ -1033,21 +1033,21 @@ number_of_iterations_lt (tree type, affi niter->cmp = GT_EXPR; niter->bound = iv0->base; } delta = fold_build2 (MINUS_EXPR, niter_type, fold_convert (niter_type, iv1->base), fold_convert (niter_type, iv0->base)); /* First handle the special case that the step is +-1. */ if ((integer_onep (iv0->step) && integer_zerop (iv1->step)) - || (integer_all_onesp (iv1->step) && integer_zerop (iv0->step))) + || (integer_minus_onep (iv1->step) && integer_zerop (iv0->step))) { /* for (i = iv0->base; i < iv1->base; i++) or for (i = iv1->base; i > iv0->base; i--). In both cases # of iterations is iv1->base - iv0->base, assuming that iv1->base >= iv0->base. @@ -1911,22 +1911,22 @@ number_of_iterations_exit (struct loop * if (warn) { const char *wording; location_t loc = gimple_location (stmt); /* We can provide a more specific warning if one of the operator is constant and the other advances by +1 or -1. */ if (!integer_zerop (iv1.step) ? (integer_zerop (iv0.step) - && (integer_onep (iv1.step) || integer_all_onesp (iv1.step))) - : (integer_onep (iv0.step) || integer_all_onesp (iv0.step))) + && (integer_onep (iv1.step) || integer_minus_onep (iv1.step))) + : (integer_onep (iv0.step) || integer_minus_onep (iv0.step))) wording = flag_unsafe_loop_optimizations ? N_("assuming that the loop is not infinite") : N_("cannot optimize possibly infinite loops"); else wording = flag_unsafe_loop_optimizations ? N_("assuming that the loop counter does not overflow") : N_("cannot optimize loop, the loop counter may overflow"); Index: gcc/predict.c =================================================================== --- gcc/predict.c (revision 198662) +++ gcc/predict.c (working copy) @@ -2025,32 +2025,32 @@ tree_predict_by_opcode (basic_block bb) break; case UNORDERED_EXPR: predict_edge_def (then_edge, PRED_TREE_FPOPCODE, NOT_TAKEN); break; case LE_EXPR: case LT_EXPR: if (integer_zerop (op1) || integer_onep (op1) - || integer_all_onesp (op1) + || integer_minus_onep (op1) || real_zerop (op1) || real_onep (op1) || real_minus_onep (op1)) predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, NOT_TAKEN); break; case GE_EXPR: case GT_EXPR: if (integer_zerop (op1) || integer_onep (op1) - || integer_all_onesp (op1) + || integer_minus_onep (op1) || real_zerop (op1) || real_onep (op1) || real_minus_onep (op1)) predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, TAKEN); break; default: break; } } Index: gcc/builtins.c =================================================================== --- gcc/builtins.c (revision 198662) +++ gcc/builtins.c (working copy) @@ -12475,25 +12475,25 @@ expand_builtin_memory_chk (tree exp, rtx return NULL_RTX; dest = CALL_EXPR_ARG (exp, 0); src = CALL_EXPR_ARG (exp, 1); len = CALL_EXPR_ARG (exp, 2); size = CALL_EXPR_ARG (exp, 3); if (! host_integerp (size, 1)) return NULL_RTX; - if (host_integerp (len, 1) || integer_all_onesp (size)) + if (host_integerp (len, 1) || integer_minus_onep (size)) { tree fn; - if (! integer_all_onesp (size) && tree_int_cst_lt (size, len)) + if (! integer_minus_onep (size) && tree_int_cst_lt (size, len)) { warning_at (tree_nonartificial_location (exp), 0, "%Kcall to %D will always overflow destination buffer", exp, get_callee_fndecl (exp)); return NULL_RTX; } fn = NULL_TREE; /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume mem{cpy,pcpy,move,set} is available. */ @@ -12606,21 +12606,21 @@ maybe_emit_chk_warning (tree exp, enum b len = CALL_EXPR_ARG (exp, 1); size = CALL_EXPR_ARG (exp, 3); break; default: gcc_unreachable (); } if (!len || !size) return; - if (! host_integerp (size, 1) || integer_all_onesp (size)) + if (! host_integerp (size, 1) || integer_minus_onep (size)) return; if (is_strlen) { len = c_strlen (len, 1); if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size)) return; } else if (fcode == BUILT_IN_STRNCAT_CHK) { @@ -12654,21 +12654,21 @@ maybe_emit_sprintf_chk_warning (tree exp const char *fmt_str; int nargs = call_expr_nargs (exp); /* Verify the required arguments in the original call. */ if (nargs < 4) return; size = CALL_EXPR_ARG (exp, 2); fmt = CALL_EXPR_ARG (exp, 3); - if (! host_integerp (size, 1) || integer_all_onesp (size)) + if (! host_integerp (size, 1) || integer_minus_onep (size)) return; /* Check whether the format is a literal string constant. */ fmt_str = c_getstr (fmt); if (fmt_str == NULL) return; if (!init_target_chars ()) return; @@ -12806,21 +12806,21 @@ fold_builtin_memory_chk (location_t loc, else { tree temp = fold_build_pointer_plus_loc (loc, dest, len); return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp); } } if (! host_integerp (size, 1)) return NULL_TREE; - if (! integer_all_onesp (size)) + if (! integer_minus_onep (size)) { if (! host_integerp (len, 1)) { /* If LEN is not constant, try MAXLEN too. For MAXLEN only allow optimizing into non-_ocs function if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) { if (fcode == BUILT_IN_MEMPCPY_CHK && ignore) { @@ -12888,21 +12888,21 @@ fold_builtin_stxcpy_chk (location_t loc, || !validate_arg (size, INTEGER_TYPE)) return NULL_TREE; /* If SRC and DEST are the same (and not volatile), return DEST. */ if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0)) return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest); if (! host_integerp (size, 1)) return NULL_TREE; - if (! integer_all_onesp (size)) + if (! integer_minus_onep (size)) { len = c_strlen (src, 1); if (! len || ! host_integerp (len, 1)) { /* If LEN is not constant, try MAXLEN too. For MAXLEN only allow optimizing into non-_ocs function if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) { if (fcode == BUILT_IN_STPCPY_CHK) @@ -12975,21 +12975,21 @@ fold_builtin_stxncpy_chk (location_t loc /* If return value of __stpncpy_chk is ignored, optimize into __strncpy_chk. */ fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK); if (fn) return build_call_expr_loc (loc, fn, 4, dest, src, len, size); } if (! host_integerp (size, 1)) return NULL_TREE; - if (! integer_all_onesp (size)) + if (! integer_minus_onep (size)) { if (! host_integerp (len, 1)) { /* If LEN is not constant, try MAXLEN too. For MAXLEN only allow optimizing into non-_ocs function if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) return NULL_TREE; } else @@ -13021,21 +13021,21 @@ fold_builtin_strcat_chk (location_t loc, if (!validate_arg (dest, POINTER_TYPE) || !validate_arg (src, POINTER_TYPE) || !validate_arg (size, INTEGER_TYPE)) return NULL_TREE; p = c_getstr (src); /* If the SRC parameter is "", return DEST. */ if (p && *p == '\0') return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src); - if (! host_integerp (size, 1) || ! integer_all_onesp (size)) + if (! host_integerp (size, 1) || ! integer_minus_onep (size)) return NULL_TREE; /* If __builtin_strcat_chk is used, assume strcat is available. */ fn = builtin_decl_explicit (BUILT_IN_STRCAT); if (!fn) return NULL_TREE; return build_call_expr_loc (loc, fn, 2, dest, src); } @@ -13058,21 +13058,21 @@ fold_builtin_strncat_chk (location_t loc p = c_getstr (src); /* If the SRC parameter is "" or if LEN is 0, return DEST. */ if (p && *p == '\0') return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len); else if (integer_zerop (len)) return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src); if (! host_integerp (size, 1)) return NULL_TREE; - if (! integer_all_onesp (size)) + if (! integer_minus_onep (size)) { tree src_len = c_strlen (src, 1); if (src_len && host_integerp (src_len, 1) && host_integerp (len, 1) && ! tree_int_cst_lt (len, src_len)) { /* If LEN >= strlen (SRC), optimize into __strcat_chk. */ fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK); if (!fn) @@ -13150,21 +13150,21 @@ fold_builtin_sprintf_chk_1 (location_t l if (validate_arg (arg, POINTER_TYPE)) { len = c_strlen (arg, 1); if (! len || ! host_integerp (len, 1)) len = NULL_TREE; } } } } - if (! integer_all_onesp (size)) + if (! integer_minus_onep (size)) { if (! len || ! tree_int_cst_lt (len, size)) return NULL_TREE; } /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0 or if format doesn't contain % chars or is "%s". */ if (! integer_zerop (flag)) { if (fmt_str == NULL) @@ -13223,21 +13223,21 @@ fold_builtin_snprintf_chk_1 (location_t size = args[3]; if (!validate_arg (size, INTEGER_TYPE)) return NULL_TREE; fmt = args[4]; if (!validate_arg (fmt, POINTER_TYPE)) return NULL_TREE; if (! host_integerp (size, 1)) return NULL_TREE; - if (! integer_all_onesp (size)) + if (! integer_minus_onep (size)) { if (! host_integerp (len, 1)) { /* If LEN is not constant, try MAXLEN too. For MAXLEN only allow optimizing into non-_ocs function if SIZE is >= MAXLEN, never convert to __ocs_fail (). */ if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1)) return NULL_TREE; } else Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 198662) +++ gcc/fold-const.c (working copy) @@ -3509,21 +3509,21 @@ optimize_bit_field_compare (location_t l warning (0, "comparison is always %d due to width of bit-field", code == NE_EXPR); return constant_boolean_node (code == NE_EXPR, compare_type); } } else { tree tem = const_binop (RSHIFT_EXPR, fold_convert_loc (loc, signed_type, rhs), size_int (lbitsize - 1)); - if (! integer_zerop (tem) && ! integer_all_onesp (tem)) + if (! integer_zerop (tem) && ! integer_minus_onep (tem)) { warning (0, "comparison is always %d due to width of bit-field", code == NE_EXPR); return constant_boolean_node (code == NE_EXPR, compare_type); } } /* Single-bit compares should always be against zero. */ if (lbitsize == 1 && ! integer_zerop (rhs)) { @@ -8235,21 +8235,21 @@ fold_unary_loc (location_t loc, enum tre /* Convert ~ (-A) to A - 1. */ else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR) return fold_build2_loc (loc, MINUS_EXPR, type, fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)), build_int_cst (type, 1)); /* Convert ~ (A - 1) or ~ (A + -1) to -A. */ else if (INTEGRAL_TYPE_P (type) && ((TREE_CODE (arg0) == MINUS_EXPR && integer_onep (TREE_OPERAND (arg0, 1))) || (TREE_CODE (arg0) == PLUS_EXPR - && integer_all_onesp (TREE_OPERAND (arg0, 1))))) + && integer_minus_onep (TREE_OPERAND (arg0, 1))))) return fold_build1_loc (loc, NEGATE_EXPR, type, fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0))); /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify. */ else if (TREE_CODE (arg0) == BIT_XOR_EXPR && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type, fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0))))) return fold_build2_loc (loc, BIT_XOR_EXPR, type, tem, fold_convert_loc (loc, type, @@ -10654,21 +10654,21 @@ fold_binary_loc (location_t loc, if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR && integer_onep (arg1) && !TYPE_OVERFLOW_TRAPS (type)) return fold_build1_loc (loc, BIT_NOT_EXPR, type, fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0))); /* Convert -1 - A to ~A. */ if (INTEGRAL_TYPE_P (type) - && integer_all_onesp (arg0)) + && integer_minus_onep (arg0)) return fold_build1_loc (loc, BIT_NOT_EXPR, type, op1); /* X - (X / CST) * CST is X % CST. */ if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg1) == MULT_EXPR && TREE_CODE (TREE_OPERAND (arg1, 0)) == TRUNC_DIV_EXPR && operand_equal_p (arg0, TREE_OPERAND (TREE_OPERAND (arg1, 0), 0), 0) && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg1, 0), 1), @@ -12390,21 +12390,21 @@ fold_binary_loc (location_t loc, return NULL_TREE; case LROTATE_EXPR: case RROTATE_EXPR: if (integer_all_onesp (arg0)) return omit_one_operand_loc (loc, type, arg0, arg1); goto shift; case RSHIFT_EXPR: /* Optimize -1 >> x for arithmetic right shifts. */ - if (integer_all_onesp (arg0) && !TYPE_UNSIGNED (type) + if (integer_minus_onep (arg0) && !TYPE_UNSIGNED (type) && tree_expr_nonnegative_p (arg1)) return omit_one_operand_loc (loc, type, arg0, arg1); /* ... fall through ... */ case LSHIFT_EXPR: shift: if (integer_zerop (arg1)) return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0)); if (integer_zerop (arg0)) return omit_one_operand_loc (loc, type, arg0, arg1); Index: gcc/expr.c =================================================================== --- gcc/expr.c (revision 198662) +++ gcc/expr.c (working copy) @@ -10771,27 +10771,27 @@ do_store_flag (sepops ops, rtx target, e case NE_EXPR: code = NE; break; case LT_EXPR: if (integer_onep (arg1)) arg1 = integer_zero_node, code = unsignedp ? LEU : LE; else code = unsignedp ? LTU : LT; break; case LE_EXPR: - if (! unsignedp && integer_all_onesp (arg1)) + if (! unsignedp && integer_minus_onep (arg1)) arg1 = integer_zero_node, code = LT; else code = unsignedp ? LEU : LE; break; case GT_EXPR: - if (! unsignedp && integer_all_onesp (arg1)) + if (! unsignedp && integer_minus_onep (arg1)) arg1 = integer_zero_node, code = GE; else code = unsignedp ? GTU : GT; break; case GE_EXPR: if (integer_onep (arg1)) arg1 = integer_zero_node, code = unsignedp ? GTU : GT; else code = unsignedp ? GEU : GE; break; Index: gcc/tree-ssa-phiopt.c =================================================================== --- gcc/tree-ssa-phiopt.c (revision 198662) +++ gcc/tree-ssa-phiopt.c (working copy) @@ -603,22 +603,22 @@ conditional_replacement (basic_block con || POINTER_TYPE_P (TREE_TYPE (arg0))) || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1)) || POINTER_TYPE_P (TREE_TYPE (arg1)))) return false; /* The PHI arguments have the constants 0 and 1, or 0 and -1, then convert it to the conditional. */ if ((integer_zerop (arg0) && integer_onep (arg1)) || (integer_zerop (arg1) && integer_onep (arg0))) neg = false; - else if ((integer_zerop (arg0) && integer_all_onesp (arg1)) - || (integer_zerop (arg1) && integer_all_onesp (arg0))) + else if ((integer_zerop (arg0) && integer_minus_onep (arg1)) + || (integer_zerop (arg1) && integer_minus_onep (arg0))) neg = true; else return false; if (!empty_block_p (middle_bb)) return false; /* At this point we know we have a GIMPLE_COND with two successors. One successor is BB, the other successor is an empty block which falls through into BB.