From patchwork Wed Oct 20 15:01:32 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 68446 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]) by ozlabs.org (Postfix) with SMTP id 6134AB70A9 for ; Thu, 21 Oct 2010 02:01:53 +1100 (EST) Received: (qmail 2842 invoked by alias); 20 Oct 2010 15:01:51 -0000 Received: (qmail 2827 invoked by uid 22791); 20 Oct 2010 15:01:49 -0000 X-SWARE-Spam-Status: No, hits=0.6 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, KAM_STOCKTIP, SPF_HELO_PASS, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (74.125.121.35) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 20 Oct 2010 15:01:44 +0000 Received: from wpaz9.hot.corp.google.com (wpaz9.hot.corp.google.com [172.24.198.73]) by smtp-out.google.com with ESMTP id o9KF1fGa021180 for ; Wed, 20 Oct 2010 08:01:41 -0700 Received: from pwj2 (pwj2.prod.google.com [10.241.219.66]) by wpaz9.hot.corp.google.com with ESMTP id o9KF1d8N005368 for ; Wed, 20 Oct 2010 08:01:40 -0700 Received: by pwj2 with SMTP id 2so4738pwj.33 for ; Wed, 20 Oct 2010 08:01:39 -0700 (PDT) Received: by 10.142.165.4 with SMTP id n4mr1284670wfe.121.1287586899200; Wed, 20 Oct 2010 08:01:39 -0700 (PDT) Received: from coign.google.com ([67.218.105.113]) by mx.google.com with ESMTPS id w22sm476505wfd.7.2010.10.20.08.01.34 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 20 Oct 2010 08:01:37 -0700 (PDT) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org Subject: Re: PATCH RFC: With -fnon-call-exceptions don't eliminate division by zero References: Date: Wed, 20 Oct 2010 08:01:32 -0700 In-Reply-To: (Ian Lance Taylor's message of "Mon, 11 Oct 2010 14:16:19 -0700") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 X-System-Of-Record: true X-IsSubscribed: yes 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 Ian Lance Taylor writes: > The -fnon-call-exceptions options indicates that certain operations, > including division by zero, should generate an exception. This includes > cases like 0 / 0. This patch ensures that 0 / 0 and any other division > by zero is not eliminated when -fnon-call-exceptions is used. This > includes a test case which fails without the patch and passes with the > patch. > > This patch is entirely in the middle-end so I don't require approval. > However, I would like to see if there are any comments before I commit > this. Thanks. I plan to commit this version of the patch tomorrow unless I receive further comments. gcc/ChangeLog: 2010-10-20 Ian Lance Taylor * tree-vrp.c (extract_range_from_binary_expr): If flag_non_call_exceptions don't eliminate division by zero. * simplify-rtx.c (simplify_binary_operation_1): Likewise. gcc/testsuite/ChangeLog: 2010-10-20 Ian Lance Taylor * gcc.c-torture/execute/20101011-1.c: New test. * gcc.c-torture/execute/20101011-1.x: New test driver. Index: tree-vrp.c =================================================================== --- tree-vrp.c (revision 165727) +++ tree-vrp.c (working copy) @@ -2464,6 +2464,22 @@ extract_range_from_binary_expr (value_ra } } + /* For divisions, if flag_non_call_exceptions is true, we must + not eliminate a division by zero. */ + if ((code == TRUNC_DIV_EXPR + || code == FLOOR_DIV_EXPR + || code == CEIL_DIV_EXPR + || code == EXACT_DIV_EXPR + || code == ROUND_DIV_EXPR) + && cfun->can_throw_non_call_exceptions + && (vr1.type != VR_RANGE + || symbolic_range_p (&vr1) + || range_includes_zero_p (&vr1))) + { + set_value_range_to_varying (vr); + return; + } + /* For divisions, if op0 is VR_RANGE, we can deduce a range even if op1 is VR_VARYING, VR_ANTI_RANGE, symbolic or can include 0. */ Index: simplify-rtx.c =================================================================== --- simplify-rtx.c (revision 165727) +++ simplify-rtx.c (working copy) @@ -2755,7 +2755,8 @@ simplify_binary_operation_1 (enum rtx_co else { /* 0/x is 0 (or x&0 if x has side-effects). */ - if (trueop0 == CONST0_RTX (mode)) + if (trueop0 == CONST0_RTX (mode) + && !cfun->can_throw_non_call_exceptions) { if (side_effects_p (op1)) return simplify_gen_binary (AND, mode, op1, trueop0); Index: testsuite/gcc.c-torture/execute/20101011-1.c =================================================================== --- testsuite/gcc.c-torture/execute/20101011-1.c (revision 0) +++ testsuite/gcc.c-torture/execute/20101011-1.c (revision 0) @@ -0,0 +1,45 @@ +/* With -fnon-call-exceptions 0 / 0 should not be eliminated. The .x + file sets the option. */ + +#ifdef SIGNAL_SUPPRESS +# define DO_TEST 0 +#elif defined (__powerpc__) || defined (__PPC__) || defined (__ppc__) || defined (__POWERPC__) || defined (__ppc) + /* On PPC division by zero does not trap. */ +# define DO_TEST 0 +#elif defined (__SPU__) + /* On SPU division by zero does not trap. */ +# define DO_TEST 0 +#else +# define DO_TEST 1 +#endif + +#if DO_TEST + +#include + +void +sigfpe (int signum __attribute__ ((unused))) +{ + exit (0); +} + +#endif + +/* When optimizing, the compiler is smart enough to constant fold the + static unset variables i and j to produce 0 / 0, but it can't + eliminate the assignment to the global k. */ +static int i; +static int j; +int k; + +int +main () +{ +#ifdef DO_TEST + signal (SIGFPE, sigfpe); + k = i / j; + abort (); +#else + exit (0); +#endif +} Index: testsuite/gcc.c-torture/execute/20101011-1.x =================================================================== --- testsuite/gcc.c-torture/execute/20101011-1.x (revision 0) +++ testsuite/gcc.c-torture/execute/20101011-1.x (revision 0) @@ -0,0 +1,2 @@ +set additional_flags "-fnon-call-exceptions" +return 0