From patchwork Mon Mar 2 23:04:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 1247916 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-520498-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha1 header.s=default header.b=kB/WmmZe; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=E2sZ8A3/; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48WbMG0zwSz9sQt for ; Tue, 3 Mar 2020 10:04:56 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; q=dns; s= default; b=l3oKgnQmJ11cvjoh8X1xJ4euuchKsQ6VEhiSJtUFIgo5Ho+jnFK3c tSQ7i/25p0bMrRimK3nWXvpiJyLyVYq03/4WsbIpTgBX/HSjg7v90rvYRpbYkDyt 7o+OxiIcY1Nr1VZHWboLVIf2QWlOfXbWuP7USesPrVcsL+1ksKGLps= 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:from :subject:to:message-id:date:mime-version:content-type; s= default; bh=G/iTPHsJ3KaonHwL2e2BUPdKybs=; b=kB/WmmZeCgvyRTvJmCJW XJI24e1gz3ORbvo3j24dBQlM5E+prekSuzZezPa8YxZXL9weXIljxJ4zXA/DaujB fQsqMQ5R5SAipxYsR5RKAdobddrlC1EMT/lEDrfdCHIdJUH00akKaPHtAui8engb X93xyttVJhoMNOJvBXZEQlg= Received: (qmail 122745 invoked by alias); 2 Mar 2020 23:04:48 -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 122737 invoked by uid 89); 2 Mar 2020 23:04:47 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=diagnosed, 20037 X-HELO: mail-qk1-f174.google.com Received: from mail-qk1-f174.google.com (HELO mail-qk1-f174.google.com) (209.85.222.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 02 Mar 2020 23:04:45 +0000 Received: by mail-qk1-f174.google.com with SMTP id 145so1593336qkl.2 for ; Mon, 02 Mar 2020 15:04:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:message-id:date:user-agent:mime-version :content-language; bh=sKoID7MpU9/bQQCYJEBT835jwJH0sMhubWbhY2OqPDo=; b=E2sZ8A3/VkS3MLox7NqLAcbV/N2C7qRSYsHUHVSfohznGUJ3hBtmzhunj6yiN2izYl kFO8MMHTyUULhPypP+MF7LomhiBWS17hox/0w8XK+GTo8A59ZiRUCviuOAZ2KVJ9k92o EwyyvwlA8mtlJgaQpf6vryxrmHPXaAZVp5W2xulq8kfWFEibqzgifkfHjlZR27YtBuQv GDInZE0lqin+NMHoIAHLBUoDOFUpf+jMMLKlhS2Nf/+eX1zvaKgk049zN8+6CpOY4w/q S378N/CbJVTecGwn0ISB26Ctyya2vAD4tCT10VBvciZ8ensNf4HbkTrFNI2pSxaaRvOF zpXg== Received: from [192.168.0.41] (97-118-124-45.hlrn.qwest.net. [97.118.124.45]) by smtp.gmail.com with ESMTPSA id p16sm10829460qkp.12.2020.03.02.15.04.42 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 02 Mar 2020 15:04:43 -0800 (PST) From: Martin Sebor Subject: [PATCH] use all same precision in wide_int arguments (PR 93986) To: gcc-patches Message-ID: <8bc7e8b7-c6c4-5ab7-8995-54093ef96676@gmail.com> Date: Mon, 2 Mar 2020 16:04:42 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 X-IsSubscribed: yes The wide_int APIs expect operands to have the same precision and abort when they don't. This is especially insidious in code where the operands normally do have the same precision but where mixed precision arguments can come up as a result of unusual combinations optimization options. That is also what precipitated pr93986. The attached patch adjusts the code to extend all wide_int operands to the same precision to avoid the ICE. Besides the usual bootstrap/testing I also compiled all string tests in gcc.dg with the same options as in the test case in pr93986 in an effort to weed out any lingering bugs like it (found none). Martin PR tree-optimization/93986 - ICE on mixed-precision wide_int arguments gcc/testsuite/ChangeLog: PR tree-optimization/93986 * gcc.dg/pr93986.c: New test. gcc/ChangeLog: PR tree-optimization/93986 * tree-ssa-strlen.c (maybe_warn_overflow): Convert all wide_int operands to the same precision to avoid ICEs. diff --git a/gcc/testsuite/gcc.dg/pr93986.c b/gcc/testsuite/gcc.dg/pr93986.c new file mode 100644 index 00000000000..bdbc192a01d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr93986.c @@ -0,0 +1,16 @@ +/* PR tree-optimization/93986 - ICE in decompose, at wide-int.h:984 + { dg-do compile } + { dg-options "-O1 -foptimize-strlen -ftree-slp-vectorize" } */ + +int dd (void); + +void ya (int cm) +{ + char s2[cm]; + + s2[cm-12] = s2[cm-11] = s2[cm-10] = s2[cm-9] + = s2[cm-8] = s2[cm-7] = s2[cm-6] = s2[cm-5] = ' '; + + if (dd ()) + __builtin_exit (0); +} diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index b76b54efbd8..136a72700d9 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -1924,11 +1924,22 @@ maybe_warn_overflow (gimple *stmt, tree len, if (TREE_NO_WARNING (dest)) return; + /* Use maximum precision to avoid overflow in the addition below. + Make sure all operands have the same precision to keep wide_int + from ICE'ing. */ + const int prec = ADDR_MAX_PRECISION; + /* Convenience constants. */ + const wide_int diff_min + = wi::to_wide (TYPE_MIN_VALUE (ptrdiff_type_node), prec); + const wide_int diff_max + = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node), prec); + const wide_int size_max + = wi::to_wide (TYPE_MAX_VALUE (size_type_node), prec); + /* The offset into the destination object computed below and not reflected in DESTSIZE. */ wide_int offrng[2]; - const int off_prec = TYPE_PRECISION (ptrdiff_type_node); - offrng[0] = offrng[1] = wi::zero (off_prec); + offrng[0] = offrng[1] = wi::zero (prec); if (!si) { @@ -1943,13 +1954,14 @@ maybe_warn_overflow (gimple *stmt, tree len, ref = TREE_OPERAND (ref, 0); if (get_range (off, offrng, rvals)) { - offrng[0] = offrng[0].from (offrng[0], off_prec, SIGNED); - offrng[1] = offrng[1].from (offrng[1], off_prec, SIGNED); + /* Convert offsets to the expected precision. */ + offrng[0] = wide_int::from (offrng[0], prec, SIGNED); + offrng[1] = wide_int::from (offrng[1], prec, SIGNED); } else { - offrng[0] = wi::to_wide (TYPE_MIN_VALUE (ptrdiff_type_node)); - offrng[1] = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)); + offrng[0] = diff_min; + offrng[1] = diff_max; } } @@ -1960,13 +1972,13 @@ maybe_warn_overflow (gimple *stmt, tree len, wide_int memoffrng[2]; if (get_range (mem_off, memoffrng, rvals)) { - offrng[0] += memoffrng[0]; - offrng[1] += memoffrng[1]; + offrng[0] += wide_int::from (memoffrng[0], prec, SIGNED); + offrng[1] += wide_int::from (memoffrng[1], prec, SIGNED); } else { - offrng[0] = wi::to_wide (TYPE_MIN_VALUE (ptrdiff_type_node)); - offrng[1] = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)); + offrng[0] = diff_min; + offrng[1] = diff_max; } } @@ -1974,8 +1986,8 @@ maybe_warn_overflow (gimple *stmt, tree len, if (int idx = get_stridx (ref, stroffrng, rvals)) { si = get_strinfo (idx); - offrng[0] += stroffrng[0]; - offrng[1] += stroffrng[1]; + offrng[0] += wide_int::from (stroffrng[0], prec, SIGNED); + offrng[1] += wide_int::from (stroffrng[1], prec, SIGNED); } } @@ -1995,7 +2007,6 @@ maybe_warn_overflow (gimple *stmt, tree len, /* Compute the range of sizes of the destination object. The range is constant for declared objects but may be a range for allocated objects. */ - const int siz_prec = TYPE_PRECISION (size_type_node); wide_int sizrng[2]; if (si) { @@ -2003,7 +2014,7 @@ maybe_warn_overflow (gimple *stmt, tree len, alloc_call = si->alloc; } else - offrng[0] = offrng[1] = wi::zero (off_prec); + offrng[0] = offrng[1] = wi::zero (prec); if (!destsize) { @@ -2014,7 +2025,7 @@ maybe_warn_overflow (gimple *stmt, tree len, { /* Remember OFF but clear OFFRNG that may have been set above. */ destoff = off; - offrng[0] = offrng[1] = wi::zero (off_prec); + offrng[0] = offrng[1] = wi::zero (prec); if (destdecl && TREE_CODE (destdecl) == SSA_NAME) { @@ -2030,20 +2041,20 @@ maybe_warn_overflow (gimple *stmt, tree len, so that overflow in allocated objects whose size depends on the strlen of the source can still be diagnosed below. */ - sizrng[0] = wi::zero (siz_prec); - sizrng[1] = wi::to_wide (TYPE_MAX_VALUE (sizetype)); + sizrng[0] = wi::zero (prec); + sizrng[1] = size_max; } } } if (!destsize) { - sizrng[0] = wi::zero (siz_prec); - sizrng[1] = wi::to_wide (TYPE_MAX_VALUE (sizetype)); + sizrng[0] = wi::zero (prec); + sizrng[1] = size_max; }; - sizrng[0] = sizrng[0].from (sizrng[0], siz_prec, UNSIGNED); - sizrng[1] = sizrng[1].from (sizrng[1], siz_prec, UNSIGNED); + sizrng[0] = wide_int::from (sizrng[0], prec, UNSIGNED); + sizrng[1] = wide_int::from (sizrng[1], prec, UNSIGNED); /* Return early if the DESTSIZE size expression is the same as LEN and the offset into the destination is zero. This might happen @@ -2056,6 +2067,9 @@ maybe_warn_overflow (gimple *stmt, tree len, if (!get_range (len, lenrng, rvals)) return; + lenrng[0] = wide_int::from (lenrng[0], prec, SIGNED); + lenrng[1] = wide_int::from (lenrng[1], prec, SIGNED); + if (plus_one) { lenrng[0] += 1; @@ -2259,8 +2273,7 @@ maybe_warn_overflow (gimple *stmt, tree len, else if (sizrng[0] == 0) { /* Avoid printing impossible sizes. */ - if (wi::ltu_p (sizrng[1], - wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)) - 2)) + if (wi::ltu_p (sizrng[1], diff_max - 2)) inform (gimple_location (alloc_call), "at offset %s to an object with size at most %wu " "declared here", @@ -2284,8 +2297,7 @@ maybe_warn_overflow (gimple *stmt, tree len, else if (sizrng[0] == 0) { /* Avoid printing impossible sizes. */ - if (wi::ltu_p (sizrng[1], - wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)) - 2)) + if (wi::ltu_p (sizrng[1], diff_max - 2)) inform (gimple_location (alloc_call), "at offset %s to an object with size at most %wu allocated " "by %qD here",