From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1614 invoked by alias); 4 May 2018 07:24:02 -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 1575 invoked by uid 89); 4 May 2018 07:24:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.6 required=5.0 tests=BAYES_00,GIT_PATCH_2,GIT_PATCH_3,KAM_ASCII_DIVIDERS,KAM_NUMSUBJECT,SPF_PASS autolearn=ham version=3.3.2 spammy=ba, 85574, ab 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; Fri, 04 May 2018 07:23:57 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id BC578AE85 for ; Fri, 4 May 2018 07:23:54 +0000 (UTC) Date: Fri, 04 May 2018 07:24:00 -0000 From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix PR85574 Message-ID: User-Agent: Alpine 2.20 (LSU 67 2015-01-07) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-SW-Source: 2018-05/txt/msg00190.txt.bz2 The PR correctly notices that we cannot transform -((a-b)/c) to (b-a)/c if a-b == b-a == INT_MIN because we are then changing the results sign if c != 1. Thus the following patch restricts this transform/predicate further. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2018-05-04 Richard Biener PR middle-end/85574 * fold-const.c (negate_expr_p): Restrict negation of operand zero of a division to when we know that can happen without overflow. (fold_negate_expr_1): Likewise. * gcc.dg/torture/pr85574.c: New testcase. * gcc.dg/torture/pr57656.c: Use dg-additional-options. Index: gcc/testsuite/gcc.dg/torture/pr85574.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr85574.c (nonexistent) +++ gcc/testsuite/gcc.dg/torture/pr85574.c (working copy) @@ -0,0 +1,4 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fwrapv" } */ + +#include "pr57656.c" Index: gcc/testsuite/gcc.dg/torture/pr57656.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr57656.c (revision 259879) +++ gcc/testsuite/gcc.dg/torture/pr57656.c (working copy) @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-fstrict-overflow" } */ +/* { dg-additional-options "-fstrict-overflow" } */ int main (void) { Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 259879) +++ gcc/fold-const.c (working copy) @@ -474,12 +474,15 @@ negate_expr_p (tree t) case EXACT_DIV_EXPR: if (TYPE_UNSIGNED (type)) break; - if (negate_expr_p (TREE_OPERAND (t, 0))) + /* In general we can't negate A in A / B, because if A is INT_MIN and + B is not 1 we change the sign of the result. */ + if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST + && negate_expr_p (TREE_OPERAND (t, 0))) return true; /* In general we can't negate B in A / B, because if A is INT_MIN and B is 1, we may turn this into INT_MIN / -1 which is undefined and actually traps on some architectures. */ - if (! INTEGRAL_TYPE_P (TREE_TYPE (t)) + if (! ANY_INTEGRAL_TYPE_P (TREE_TYPE (t)) || TYPE_OVERFLOW_WRAPS (TREE_TYPE (t)) || (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST && ! integer_onep (TREE_OPERAND (t, 1)))) @@ -652,14 +655,17 @@ fold_negate_expr_1 (location_t loc, tree case EXACT_DIV_EXPR: if (TYPE_UNSIGNED (type)) break; - if (negate_expr_p (TREE_OPERAND (t, 0))) + /* In general we can't negate A in A / B, because if A is INT_MIN and + B is not 1 we change the sign of the result. */ + if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST + && negate_expr_p (TREE_OPERAND (t, 0))) return fold_build2_loc (loc, TREE_CODE (t), type, negate_expr (TREE_OPERAND (t, 0)), TREE_OPERAND (t, 1)); /* In general we can't negate B in A / B, because if A is INT_MIN and B is 1, we may turn this into INT_MIN / -1 which is undefined and actually traps on some architectures. */ - if ((! INTEGRAL_TYPE_P (TREE_TYPE (t)) + if ((! ANY_INTEGRAL_TYPE_P (TREE_TYPE (t)) || TYPE_OVERFLOW_WRAPS (TREE_TYPE (t)) || (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST && ! integer_onep (TREE_OPERAND (t, 1))))