From patchwork Tue May 27 20:29:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 353101 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 8C56C1400D3 for ; Wed, 28 May 2014 06:31:15 +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:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=EHvEmYAxCfY1ZftR UzpKZVH6XfWsgQEvu3DoJGqJtaPskQLBb7qLERIpeGaNBQMOFQ/FsbGilFfUlYdG xgruvYcu1GKfQZGeeOAxxl7+jQYKtpGWwX6BGb9B+4rx49aM/MXI4JhySIcRWdzh F0N1NSrwYXohkvFHhgNfcRwHDuM= 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 :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=9L9v/JA5om8g5h5x4EMeXq Imzws=; b=mOxaqhFosaRSA5xu0Ol3UFX/nUY/7Tsmkwp9eWUuqnD2BIbmQuouOj CETllb6sSaiTeUgP4PTiF3u9dxiK5Co6UWK9ohlAiOhyoduyQV3lVRi4VUbgEaU4 QKWzw28hrNoxGS30Ay7QFB1i/RFc8hOMrVCs0b5k3Q7Hq5CeN+MQc= Received: (qmail 11679 invoked by alias); 27 May 2014 20:31:07 -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 11665 invoked by uid 89); 27 May 2014 20:31:07 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 27 May 2014 20:31:05 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 9F35A2746A33 for ; Tue, 27 May 2014 22:31:02 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5dg-C-5cblsE for ; Tue, 27 May 2014 22:31:02 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 7BCAA2746721 for ; Tue, 27 May 2014 22:31:02 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: Fix old bug in div_and_round_double Date: Tue, 27 May 2014 22:29:57 +0200 Message-ID: <3615860.z70LMau7zY@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.29-desktop; KDE/4.7.2; x86_64; ; ) MIME-Version: 1.0 This is an old bug in div_and_round_double for ROUND_DIV_EXPR: when the code detects that it needs to adjust the quotient, it needs to decide whether it increases or decreases it by 1. This only depends on the expected sign of the quotient, but the test reads: if (*hquo < 0) So if the quotient is 0, the code will always bump it, thus yielding 1, even if the expected quotient is negative. This causes the attached Ada testcase to fail at -O on all active branches... except for mainline, because of the correct implementation of the same test in wi::div_round: if (wi::neg_p (x, sgn) != wi::neg_p (y, sgn)) return quotient - 1; else return quotient + 1; It turns out that div_and_round_double has a predicate quo_neg that implements the same test as the wide-int one and ought to be used here. Tested on x86_64-suse-linux (of course this probably doesn't mean anything on the mainline, but it was also test with 4.7 and 4.9 compilers) and applied on the mainline as obvious. 2014-05-27 Eric Botcazou * double-int.c (div_and_round_double) : Use the proper predicate to detect a negative quotient. 2014-05-27 Eric Botcazou * gnat.dg/overflow_fixed.adb: New test. Index: double-int.c =================================================================== --- double-int.c (revision 210911) +++ double-int.c (working copy) @@ -588,7 +588,7 @@ div_and_round_double (unsigned code, int == (unsigned HOST_WIDE_INT) htwice) && (labs_den <= ltwice))) { - if (*hquo < 0) + if (quo_neg) /* quo = quo - 1; */ add_double (*lquo, *hquo, (HOST_WIDE_INT) -1, (HOST_WIDE_INT) -1, lquo, hquo);