From patchwork Thu Dec 1 09:54:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Martin_Li=C5=A1ka?= X-Patchwork-Id: 701434 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tTt1r57nzz9t0t for ; Thu, 1 Dec 2016 20:55:11 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="K5p1f4Oz"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=lqMAKV9tjvOb/iH313S6des5CFHKMEEr9bXug36pAtNtYJcLh/ wZWz21h6fhMO83ngDgaX4vURPkuyjJAmuho4EjgnNGqbErKW3LELgsgRCHgnQNsI 9PZGN2/WO95E06sTZUe8x7nkat9Md2o1Ck1T+UZKAu8PdH/I0LJOHZJDw= 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:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=a2lRBUUgONmmaMp7YC02rP1sQzk=; b=K5p1f4OzhGiOm1MhRL+h B4MZFNrldl4noftWxTgqCOsWRKoh6UScJWf8q+9LtMWL9vlA06LjW9EbRWqi8trE jTd9pwQ6uBnNA471u4XSoUvsDh3ZZFcs1os2ZYdhuSFDp5wjAf5y4qhNxccOSLs3 UFMh4aTy8GpVpxLEnRxJnQY= Received: (qmail 105251 invoked by alias); 1 Dec 2016 09:55:02 -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 105231 invoked by uid 89); 1 Dec 2016 09:55:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, SPF_PASS autolearn=ham version=3.3.2 spammy=1966, Structure X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 01 Dec 2016 09:54:51 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 35D3FAABE; Thu, 1 Dec 2016 09:54:49 +0000 (UTC) To: GCC Patches Cc: markus@trippelsdorf.de From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Subject: [PATCH] Fix runtime error: left shift of negative value (PR, ipa/78555). Message-ID: <0e1ac154-4e1c-d2b7-645d-7a007a9d4e53@suse.cz> Date: Thu, 1 Dec 2016 10:54:48 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.0 MIME-Version: 1.0 X-IsSubscribed: yes As described in the PR, we do couple of shifts of a negative value. Fixed in the patch and couple of new unit tests are added. Patch can bootstrap on ppc64le-redhat-linux and survives regression tests. Ready to be installed? Martin From 61a6b5e0c973bd77341a1053609c7ad331691a9e Mon Sep 17 00:00:00 2001 From: marxin Date: Wed, 30 Nov 2016 15:24:48 +0100 Subject: [PATCH] Fix runtime error: left shift of negative value (PR ipa/78555). gcc/ChangeLog: 2016-11-30 Martin Liska PR ipa/78555 * sreal.c (sreal::to_int): Make absolute value before shifting. (sreal::operator/): Likewise. (sreal_verify_negative_division): New test. (void sreal_c_tests): Call the new test. * sreal.h (sreal::normalize_up): Use new SREAL_ABS and SREAL_SIGN macros. (sreal::normalize_down): Likewise. --- gcc/sreal.c | 20 +++++++++++++++++--- gcc/sreal.h | 9 +++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/gcc/sreal.c b/gcc/sreal.c index 9c43b4e..52e530d 100644 --- a/gcc/sreal.c +++ b/gcc/sreal.c @@ -102,14 +102,14 @@ sreal::shift_right (int s) int64_t sreal::to_int () const { - int64_t sign = m_sig < 0 ? -1 : 1; + int64_t sign = SREAL_SIGN (m_sig); if (m_exp <= -SREAL_BITS) return 0; if (m_exp >= SREAL_PART_BITS) return sign * INTTYPE_MAXIMUM (int64_t); if (m_exp > 0) - return m_sig << m_exp; + return sign * (SREAL_ABS (m_sig) << m_exp); if (m_exp < 0) return m_sig >> -m_exp; return m_sig; @@ -229,7 +229,8 @@ sreal::operator/ (const sreal &other) const { gcc_checking_assert (other.m_sig != 0); sreal r; - r.m_sig = (m_sig << SREAL_PART_BITS) / other.m_sig; + r.m_sig + = SREAL_SIGN (m_sig) * (SREAL_ABS (m_sig) << SREAL_PART_BITS) / other.m_sig; r.m_exp = m_exp - other.m_exp - SREAL_PART_BITS; r.normalize (); return r; @@ -334,6 +335,18 @@ sreal_verify_shifting (void) verify_shifting (values[i]); } +/* Verify division by (of) a negative value. */ + +static void +sreal_verify_negative_division (void) +{ + ASSERT_EQ (sreal (1) / sreal (1), sreal (1)); + ASSERT_EQ (sreal (-1) / sreal (-1), sreal (1)); + ASSERT_EQ (sreal (-1234567) / sreal (-1234567), sreal (1)); + ASSERT_EQ (sreal (-1234567) / sreal (1234567), sreal (-1)); + ASSERT_EQ (sreal (1234567) / sreal (-1234567), sreal (-1)); +} + /* Run all of the selftests within this file. */ void sreal_c_tests () @@ -341,6 +354,7 @@ void sreal_c_tests () sreal_verify_basics (); sreal_verify_arithmetics (); sreal_verify_shifting (); + sreal_verify_negative_division (); } } // namespace selftest diff --git a/gcc/sreal.h b/gcc/sreal.h index ce9cdbb..21f14b0 100644 --- a/gcc/sreal.h +++ b/gcc/sreal.h @@ -31,6 +31,9 @@ along with GCC; see the file COPYING3. If not see #define SREAL_BITS SREAL_PART_BITS +#define SREAL_SIGN(v) (v < 0 ? -1: 1) +#define SREAL_ABS(v) (v < 0 ? -v: v) + /* Structure for holding a simple real number. */ class sreal { @@ -193,7 +196,6 @@ inline sreal operator>> (const sreal &a, int exp) inline void sreal::normalize_up () { - int64_t s = m_sig < 0 ? -1 : 1; unsigned HOST_WIDE_INT sig = absu_hwi (m_sig); int shift = SREAL_PART_BITS - 2 - floor_log2 (sig); @@ -208,7 +210,7 @@ sreal::normalize_up () m_exp = -SREAL_MAX_EXP; sig = 0; } - if (s == -1) + if (SREAL_SIGN (m_sig) == -1) m_sig = -sig; else m_sig = sig; @@ -221,7 +223,6 @@ sreal::normalize_up () inline void sreal::normalize_down () { - int64_t s = m_sig < 0 ? -1 : 1; int last_bit; unsigned HOST_WIDE_INT sig = absu_hwi (m_sig); int shift = floor_log2 (sig) - SREAL_PART_BITS + 2; @@ -246,7 +247,7 @@ sreal::normalize_down () m_exp = SREAL_MAX_EXP; sig = SREAL_MAX_SIG; } - if (s == -1) + if (SREAL_SIGN (m_sig) == -1) m_sig = -sig; else m_sig = sig; -- 2.10.2