From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 57603 invoked by alias); 13 Feb 2018 15:26:32 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 57593 invoked by uid 89); 13 Feb 2018 15:26:31 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-6.1 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,GIT_PATCH_2,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=Hx-languages-length:4871 X-HELO: mail-lf0-f53.google.com Received: from mail-lf0-f53.google.com (HELO mail-lf0-f53.google.com) (209.85.215.53) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 Feb 2018 15:26:30 +0000 Received: by mail-lf0-f53.google.com with SMTP id a204so25551412lfa.2 for ; Tue, 13 Feb 2018 07:26:29 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=3TWclZwWB9gxJejvyrAwEAevSwBPBa/NyyRUT0+O7p4=; b=fba593mDuKtqXuhZfevA+K7RgmOwsbOHMWTcbYBQZe9YdecNNkW2Ixyue5uyepw2mB bZtLSc7Z++D1N2wUOmswBoJym3o6zTUJiKAhbBBo8PcYDaKoi6+n7G1j2IEJRkwy3eN5 lj2425ad+Xoujse7kobYE3XMfd/6tl/PjXFCF7Muz6mJZpeuQmxuBQzKlh31FkxEnwzF /v0ZsyjqIy3ey/9KkdmihDCaW5qx7lQVf6faSB4go7pT+LcgCy4X5tzVntrvBfmMXqhg TmSknUoKru5sCz4Alq4MbOVKD3BBlYUd/HHAmaNwG+AjxY/IRuFK0nuOpIo0kCUKPENj q7tw== X-Gm-Message-State: APf1xPCj6gfakA2wy1X2gjWE5wwv9kKAgv7FWTP6pP0WaWvJSS5s0DB1 Gol7LQQMhPXOz8GepMw5IjJYgTZD82XNxzyCtU2LcA== X-Google-Smtp-Source: AH8x227GsLPBkrMRwNHY9i7/xrLVECzNpKAksl+Yyxu7jA4Mm4tQXfZYxwQfrP7k0CO6xiGmR/LgEkrvd2cMQAEFEyI= X-Received: by 10.46.29.147 with SMTP id w19mr1193920lje.70.1518535587602; Tue, 13 Feb 2018 07:26:27 -0800 (PST) MIME-Version: 1.0 Received: by 10.46.51.21 with HTTP; Tue, 13 Feb 2018 07:26:27 -0800 (PST) In-Reply-To: <87sha69qfc.fsf@linaro.org> References: <87sha69qfc.fsf@linaro.org> From: Richard Biener Date: Tue, 13 Feb 2018 15:26:00 -0000 Message-ID: Subject: Re: Fix VR_ANTI_RANGE handling in intersect_range_with_nonzero_bits (PR 84321) To: GCC Patches , Richard Sandiford Content-Type: text/plain; charset="UTF-8" X-IsSubscribed: yes X-SW-Source: 2018-02/txt/msg00734.txt.bz2 On Mon, Feb 12, 2018 at 4:29 PM, Richard Sandiford wrote: > VR_ANTI_RANGE is basically a union of two ranges, and although > intersect_range_with_nonzero_bits had code to deal with the upper > one being empty, it didn't handle the lower one being empty. > There were also some off-by-one errors. > > This patch rewrites the code in a hopefully clearer way. > > Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Ok. Richard. > Richard > > > 2018-02-12 Richard Sandiford > > gcc/ > PR tree-optimization/84321 > * tree-vrp.c (intersect_range_with_nonzero_bits): Fix VR_ANTI_RANGE > handling. Also check whether the anti-range contains any values > that satisfy the mask; switch to a VR_RANGE if not. > > gcc/testsuite/ > PR tree-optimization/84321 > * gcc.dg/pr84321.c: New test. > > Index: gcc/tree-vrp.c > =================================================================== > *** gcc/tree-vrp.c 2018-02-08 15:16:21.784407397 +0000 > --- gcc/tree-vrp.c 2018-02-12 15:26:13.703500747 +0000 > *************** intersect_range_with_nonzero_bits (enum > *** 184,220 **** > const wide_int &nonzero_bits, > signop sgn) > { > ! if (vr_type == VR_RANGE) > { > ! *max = wi::round_down_for_mask (*max, nonzero_bits); > > ! /* Check that the range contains at least one valid value. */ > ! if (wi::gt_p (*min, *max, sgn)) > ! return VR_UNDEFINED; > > ! *min = wi::round_up_for_mask (*min, nonzero_bits); > ! gcc_checking_assert (wi::le_p (*min, *max, sgn)); > ! } > ! if (vr_type == VR_ANTI_RANGE) > ! { > ! *max = wi::round_up_for_mask (*max, nonzero_bits); > > ! /* If the calculation wrapped, we now have a VR_RANGE whose > ! lower bound is *MAX and whose upper bound is *MIN. */ > ! if (wi::gt_p (*min, *max, sgn)) > { > ! std::swap (*min, *max); > ! *max = wi::round_down_for_mask (*max, nonzero_bits); > gcc_checking_assert (wi::le_p (*min, *max, sgn)); > return VR_RANGE; > } > > ! *min = wi::round_down_for_mask (*min, nonzero_bits); > gcc_checking_assert (wi::le_p (*min, *max, sgn)); > > ! /* Check whether we now have an empty set of values. */ > ! if (*min - 1 == *max) > return VR_UNDEFINED; > } > return vr_type; > } > --- 184,244 ---- > const wide_int &nonzero_bits, > signop sgn) > { > ! if (vr_type == VR_ANTI_RANGE) > { > ! /* The VR_ANTI_RANGE is equivalent to the union of the ranges > ! A: [-INF, *MIN) and B: (*MAX, +INF]. First use NONZERO_BITS > ! to create an inclusive upper bound for A and an inclusive lower > ! bound for B. */ > ! wide_int a_max = wi::round_down_for_mask (*min - 1, nonzero_bits); > ! wide_int b_min = wi::round_up_for_mask (*max + 1, nonzero_bits); > > ! /* If the calculation of A_MAX wrapped, A is effectively empty > ! and A_MAX is the highest value that satisfies NONZERO_BITS. > ! Likewise if the calculation of B_MIN wrapped, B is effectively > ! empty and B_MIN is the lowest value that satisfies NONZERO_BITS. */ > ! bool a_empty = wi::ge_p (a_max, *min, sgn); > ! bool b_empty = wi::le_p (b_min, *max, sgn); > > ! /* If both A and B are empty, there are no valid values. */ > ! if (a_empty && b_empty) > ! return VR_UNDEFINED; > > ! /* If exactly one of A or B is empty, return a VR_RANGE for the > ! other one. */ > ! if (a_empty || b_empty) > { > ! *min = b_min; > ! *max = a_max; > gcc_checking_assert (wi::le_p (*min, *max, sgn)); > return VR_RANGE; > } > > ! /* Update the VR_ANTI_RANGE bounds. */ > ! *min = a_max + 1; > ! *max = b_min - 1; > gcc_checking_assert (wi::le_p (*min, *max, sgn)); > > ! /* Now check whether the excluded range includes any values that > ! satisfy NONZERO_BITS. If not, switch to a full VR_RANGE. */ > ! if (wi::round_up_for_mask (*min, nonzero_bits) == b_min) > ! { > ! unsigned int precision = min->get_precision (); > ! *min = wi::min_value (precision, sgn); > ! *max = wi::max_value (precision, sgn); > ! vr_type = VR_RANGE; > ! } > ! } > ! if (vr_type == VR_RANGE) > ! { > ! *max = wi::round_down_for_mask (*max, nonzero_bits); > ! > ! /* Check that the range contains at least one valid value. */ > ! if (wi::gt_p (*min, *max, sgn)) > return VR_UNDEFINED; > + > + *min = wi::round_up_for_mask (*min, nonzero_bits); > + gcc_checking_assert (wi::le_p (*min, *max, sgn)); > } > return vr_type; > } > Index: gcc/testsuite/gcc.dg/pr84321.c > =================================================================== > *** /dev/null 2018-02-10 09:05:46.714416790 +0000 > --- gcc/testsuite/gcc.dg/pr84321.c 2018-02-12 15:26:13.702500788 +0000 > *************** > *** 0 **** > --- 1,16 ---- > + /* { dg-do compile } */ > + /* { dg-options "-O3 -fwrapv" } */ > + > + int c; > + > + void > + foo (int *a, int b) > + { > + int e; > + if (b == 1) > + return; > + for (e = 0; e < (b & ~7); e += 8) > + ; > + for (++e; e < b;) > + c = a[e]; > + }