From patchwork Wed Nov 19 20:19:08 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Stubbs X-Patchwork-Id: 412498 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 7B8FA140142 for ; Thu, 20 Nov 2014 07:19:27 +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 :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; q=dns; s=default; b=RoQnc/bgj7Xj+U8Fn fYr9uyZ+bw54TyEfWnZYbF1fTDsJeJPTfbZFG2fT1o9sJiIkofiBNudDscyFsleb vQMaS0qEGrhFKO9gmBfF4nalIfHDZVXDnzEXQISiH1N+pQOlrILSGpGYk26y8zcB HduSxDo9NjFjhCoIcn+P9iCaX4= 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 :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; s=default; bh=8R/EVAymkSvIqg+0d2Qbr0U mlLQ=; b=H1d/oxi4EVQ2vNQJlrpJDQpktdP2JD1dbT44EnNMpr8sVibDv1A4otC QwcxDfFZ10ZUyWSrCP2uhOPUvVASGO7RmRS1pwuKsI41WcnqmPrMJqal4NoeQOcC 2OZNfVDvHjjaSNzXFEWudzTlFq0RDOCsk9y7NK+grVi7RLQ+Jfq0= Received: (qmail 3755 invoked by alias); 19 Nov 2014 20:19:20 -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 3744 invoked by uid 89); 19 Nov 2014 20:19:19 -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, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 19 Nov 2014 20:19:17 +0000 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=SVR-IES-FEM-03.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1XrBib-0003At-C9 from Andrew_Stubbs@mentor.com ; Wed, 19 Nov 2014 12:19:13 -0800 Received: from [172.30.3.150] (137.202.0.76) by SVR-IES-FEM-03.mgc.mentorg.com (137.202.0.108) with Microsoft SMTP Server id 14.3.181.6; Wed, 19 Nov 2014 20:19:11 +0000 Message-ID: <546CFB3C.5030307@codesourcery.com> Date: Wed, 19 Nov 2014 20:19:08 +0000 From: Andrew Stubbs User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: Marek Polacek CC: Richard Biener , "gcc-patches@gcc.gnu.org" Subject: Re: [patch] Warn on undefined loop exit References: <545A9A86.1070008@codesourcery.com> <54652425.9070104@codesourcery.com> <546CC62B.1010109@codesourcery.com> <20141119163938.GE29446@redhat.com> In-Reply-To: <20141119163938.GE29446@redhat.com> On 19/11/14 16:39, Marek Polacek wrote: > On Wed, Nov 19, 2014 at 04:32:43PM +0000, Andrew Stubbs wrote: >> + if (warning_at (gimple_location (elt->stmt), >> + OPT_Waggressive_loop_optimizations, >> + "Loop exit may only be reached after undefined behaviour.")) > > Warnings should start with a lowercase and should be without > a fullstop at the end. Fixed, and I spotted a britishism too. Andrew 2014-11-19 Andrew Stubbs gcc/ * tree-ssa-loop-niter.c (maybe_lower_iteration_bound): Warn if a loop condition would be removed due to undefined behaviour. gcc/testsuite/ * gcc.dg/undefined-loop-1.c: New file. * gcc.dg/undefined-loop-2.c: New file. --- gcc/testsuite/gcc.dg/undefined-loop-1.c | 18 ++++++++++++ gcc/testsuite/gcc.dg/undefined-loop-2.c | 22 +++++++++++++++ gcc/tree-ssa-loop-niter.c | 46 +++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/undefined-loop-1.c create mode 100644 gcc/testsuite/gcc.dg/undefined-loop-2.c diff --git a/gcc/testsuite/gcc.dg/undefined-loop-1.c b/gcc/testsuite/gcc.dg/undefined-loop-1.c new file mode 100644 index 0000000..80260cc --- /dev/null +++ b/gcc/testsuite/gcc.dg/undefined-loop-1.c @@ -0,0 +1,18 @@ +/* Check that loops whose final iteration is undefined are detected. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Waggressive-loop-optimizations" } */ + +void doSomething(char); + +char array[5]; + +void +foo (void) +{ + int i; + for (i = 0; + array[i] /* { dg-message "note: possible undefined statement is here" } */ + && i < 5; /* { dg-warning "loop exit may only be reached after undefined behavior" } */ + i++) + doSomething(array[i]); +} diff --git a/gcc/testsuite/gcc.dg/undefined-loop-2.c b/gcc/testsuite/gcc.dg/undefined-loop-2.c new file mode 100644 index 0000000..dbea62c --- /dev/null +++ b/gcc/testsuite/gcc.dg/undefined-loop-2.c @@ -0,0 +1,22 @@ +/* Check that loops whose final iteration is undefined are detected. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Waggressive-loop-optimizations" } */ + +void doSomething(char); + +char array1[5]; +char array2[5]; + +void +foo (int p) +{ + int i; + for (i=0; + (p + ? array1[i] /* { dg-message "note: possible undefined statement is here" } */ + : array2[i]) /* { dg-message "note: possible undefined statement is here" } */ + && i < 5 /* { dg-warning "loop exit may only be reached after undefined behavior" } */ + && i < 100; /* { dg-warning "loop exit may only be reached after undefined behavior" } */ + i++) + doSomething(array1[i]); +} diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index fd32d28..0365505 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -3289,6 +3289,7 @@ maybe_lower_iteration_bound (struct loop *loop) struct nb_iter_bound *elt; bool found_exit = false; vec queue = vNULL; + vec problem_stmts = vNULL; bitmap visited; /* Collect all statements with interesting (i.e. lower than @@ -3334,6 +3335,7 @@ maybe_lower_iteration_bound (struct loop *loop) if (not_executed_last_iteration->contains (stmt)) { stmt_found = true; + problem_stmts.safe_push (stmt); break; } if (gimple_has_side_effects (stmt)) @@ -3377,9 +3379,53 @@ maybe_lower_iteration_bound (struct loop *loop) "undefined statement must be executed at the last iteration.\n"); record_niter_bound (loop, loop->nb_iterations_upper_bound - 1, false, true); + + if (OPT_Waggressive_loop_optimizations) + { + bool exit_warned = false; + for (elt = loop->bounds; elt; elt = elt->next) + { + if (elt->is_exit + && wi::gtu_p (elt->bound, loop->nb_iterations_upper_bound)) + { + basic_block bb = gimple_bb (elt->stmt); + edge exit_edge = EDGE_SUCC (bb, 0); + struct tree_niter_desc niter; + + if (!loop_exit_edge_p (loop, exit_edge)) + exit_edge = EDGE_SUCC (bb, 1); + + if(number_of_iterations_exit (loop, exit_edge, + &niter, false, false) + && integer_onep (niter.assumptions) + && integer_zerop (niter.may_be_zero) + && niter.niter + && TREE_CODE (niter.niter) == INTEGER_CST + && wi::ltu_p (loop->nb_iterations_upper_bound, + wi::to_widest (niter.niter))) + { + if (warning_at (gimple_location (elt->stmt), + OPT_Waggressive_loop_optimizations, + "loop exit may only be reached after undefined behavior")) + exit_warned = true; + } + } + } + + if (exit_warned && problem_stmts != vNULL) + { + gimple stmt; + int index; + FOR_EACH_VEC_ELT (problem_stmts, index, stmt) + inform (gimple_location (stmt), + "possible undefined statement is here"); + } + } } + BITMAP_FREE (visited); queue.release (); + problem_stmts.release (); delete not_executed_last_iteration; }