Richard Guenther wrote:
> On Fri, Jul 6, 2012 at 6:36 PM, Tom de Vries <tom_devr...@mentor.com> wrote:
> > Bootstrapped and reg-tested (ada inclusive) on x86_64.
> >
> > OK for trunk?
> 
> Ok.
> Thanks,
> Richard.
> 
> > 2012-07-06  Tom de Vries  <t...@codesourcery.com>
> >             Richard Guenther  <rguent...@suse.de>
> >
> >         * tree-ssa-ccp.c (optimize_unreachable): New function.
> >         (execute_fold_all_builtins): Use optimize_unreachable to optimize
> >         BUILT_IN_UNREACHABLE.  Don't optimize after BUILT_IN_UNREACHABLE.
> >
> >         * gcc.dg/builtin-unreachable-6.c: New test.
> >         * gcc.dg/builtin-unreachable-5.c: New test.


When attempting to backport this patch to our 4.7 branch, I ran into
segmentation faults.  It turns out that at least in 4.7, gsi_stmt
crashes when passed an empty gsi (for which gsi_end_p is true);
on mainline, gsi_stmt simply returns NULL instead.

Now I understand that even on mainline, we're still supposed to check
gsi_end_p before calling gsi_stmt.  The patch below updates
tree-ssa-ccp.c:optimize_unreachable to do that.  In the backport
this fixes the crashes.

This doesn't really have any effect on behaviour on mainline.  Should
it be installed anyway?

(Tested on mainline on i386-linux with no regressions.)

In addition, I was wondering whether we should backport Tom's patch
(including the fix below) to the FSF 4.7 branch: it does fix a
(performance) regression, in the sense that the original testcase
calling __builtin_unreachable multiple times was optimized well
until 4.6, and is now again optimized well on mainline, but it
generates quite bad code on 4.7 at the moment ...

Bye,
Ulrich


ChangeLog:

        * tree-ssa-ccp.c (optimize_unreachable): Check gsi_end_p
        before calling gsi_stmt.

Index: gcc/tree-ssa-ccp.c
===================================================================
*** gcc/tree-ssa-ccp.c  (revision 189459)
--- gcc/tree-ssa-ccp.c  (working copy)
*************** optimize_unreachable (gimple_stmt_iterat
*** 2358,2366 ****
    FOR_EACH_EDGE (e, ei, bb->preds)
      {
        gsi = gsi_last_bb (e->src);
!       stmt = gsi_stmt (gsi);
  
!       if (stmt && gimple_code (stmt) == GIMPLE_COND)
        {
          if (e->flags & EDGE_TRUE_VALUE)
            gimple_cond_make_false (stmt);
--- 2358,2368 ----
    FOR_EACH_EDGE (e, ei, bb->preds)
      {
        gsi = gsi_last_bb (e->src);
!       if (gsi_end_p (gsi))
!       continue;
  
!       stmt = gsi_stmt (gsi);
!       if (gimple_code (stmt) == GIMPLE_COND)
        {
          if (e->flags & EDGE_TRUE_VALUE)
            gimple_cond_make_false (stmt);


-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  ulrich.weig...@de.ibm.com

Reply via email to