From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 65800 invoked by alias); 12 Feb 2018 15:30:22 -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 65731 invoked by uid 89); 12 Feb 2018 15:30:18 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-6.1 required=5.0 tests=BAYES_00,GIT_PATCH_2,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,SPF_PASS,TIME_LIMIT_EXCEEDED autolearn=unavailable version=3.3.2 spammy= X-HELO: mail-wr0-f180.google.com Received: from mail-wr0-f180.google.com (HELO mail-wr0-f180.google.com) (209.85.128.180) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 12 Feb 2018 15:30:03 +0000 Received: by mail-wr0-f180.google.com with SMTP id q11so3828533wre.8 for ; Mon, 12 Feb 2018 07:30:03 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:date:message-id :user-agent:mime-version; bh=1h5enVTjx+Rvp/+aP/gBdHVDllQX3mP5fgHw17VirCo=; b=P7ucFh+BTuk7mwAT5jDKodFhwZQ7SoR+z/RotPCawUtKQaAmjGmU/3EvbB+5IUPLKF xGHl52AlPg9q1uKweFPtJ8Uv7j4N9fldAXGNIiwOMJGh5TKaGYNzmgjX1qOGmxeKYY2O +Ovk7oL4KD6sJbvoABPsKyq7gLdfn9WQeZ2DqCN9bguoupslcawL+XxLKmQAd+x1AP/Q APDffO+MlsNuhREYXBnDEZMvlGifjxhb3BksKkA+D1wpjVwT9vQx/XU18gFGZwmIYqq7 gk/FFN+rRF8WrMIaz61zVNsawe1QiDXDRWUUsvJydrfjOi/VLmF29oUXn0Pd+c3gp0su l+1Q== X-Gm-Message-State: APf1xPDAse60xTyp6tmJukIuyhUTcQBPeEt5N1TPMfXfqe2sKTD9nER+ CvgrhMONWDerf9Cm3L4XF1XhLwVSDKA= X-Google-Smtp-Source: AH8x22585Mhp8p2XRzD76wIjUSHOMStj5DXtRgdhps0wUHnlwpjhgIfoIndzYeIv47iDZbAnX+7M2Q== X-Received: by 10.223.178.206 with SMTP id g72mr3091710wrd.135.1518449401464; Mon, 12 Feb 2018 07:30:01 -0800 (PST) Received: from localhost ([95.144.14.158]) by smtp.gmail.com with ESMTPSA id b79sm5444845wmb.18.2018.02.12.07.30.00 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 12 Feb 2018 07:30:00 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: Fix VR_ANTI_RANGE handling in intersect_range_with_nonzero_bits (PR 84321) Date: Mon, 12 Feb 2018 15:30:00 -0000 Message-ID: <87sha69qfc.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2018-02/txt/msg00651.txt.bz2 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? 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]; + }