Re: V2 [PATCH] i386: Handle REG_EH_REGION note

2019-03-14 Thread H.J. Lu
On Thu, Mar 14, 2019 at 4:34 PM Jakub Jelinek  wrote:
>
> On Thu, Mar 14, 2019 at 11:30:21AM +0800, H.J. Lu wrote:
> > We need to split the basic block if we create new insns, which may
> > throw exceptions, in the middle of the basic blocks.
> >
> > Tested on AVX2 and AVX512 machines with and without
> >
> > --with-arch=native
> >
> > OK for trunk?
>
> That looks much better, I see you chose to follow what lower-subreg.c does
> here.  I just wonder if instead of the sbitmap of blocks to check for 
> splitting it
> wouldn't be more efficient to have an auto_vec holding the exact
> set_insns that need splitting after them and just grab the bb using
> BLOCK_FOR_INSN.
>

Good idea.  I will work on it.

Thanks.

-- 
H.J.


Re: V2 [PATCH] i386: Handle REG_EH_REGION note

2019-03-14 Thread Jakub Jelinek
On Thu, Mar 14, 2019 at 11:30:21AM +0800, H.J. Lu wrote:
> We need to split the basic block if we create new insns, which may
> throw exceptions, in the middle of the basic blocks.
> 
> Tested on AVX2 and AVX512 machines with and without
> 
> --with-arch=native
> 
> OK for trunk?

That looks much better, I see you chose to follow what lower-subreg.c does
here.  I just wonder if instead of the sbitmap of blocks to check for splitting 
it
wouldn't be more efficient to have an auto_vec holding the exact
set_insns that need splitting after them and just grab the bb using
BLOCK_FOR_INSN.

Jakub


V2 [PATCH] i386: Handle REG_EH_REGION note

2019-03-13 Thread H.J. Lu
On Thu, Mar 14, 2019 at 1:28 AM Jakub Jelinek  wrote:
>
> On Tue, Mar 12, 2019 at 09:36:32AM +0800, H.J. Lu wrote:
> >   PR target/89650
> >   * config/i386/i386.c (remove_partial_avx_dependency): Handle
> >   REG_EH_REGION note.
> >
> > gcc/testsuite/
> >
> >   PR target/89650
> >   * g++.target/i386/pr89650.C: New test.
> > ---
> >  gcc/config/i386/i386.c  |  6 ++
> >  gcc/testsuite/g++.target/i386/pr89650.C | 19 +++
> >  2 files changed, 25 insertions(+)
> >  create mode 100644 gcc/testsuite/g++.target/i386/pr89650.C
> >
> > diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> > index 896c6f33d40..b702703074c 100644
> > --- a/gcc/config/i386/i386.c
> > +++ b/gcc/config/i386/i386.c
> > @@ -2873,6 +2873,12 @@ remove_partial_avx_dependency (void)
> > /* Generate an XMM vector SET.  */
> > set = gen_rtx_SET (vec, src);
> > set_insn = emit_insn_before (set, insn);
> > +
> > +   /* Handle REG_EH_REGION note.  */
> > +   rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
> > +   if (note)
> > + add_reg_note (insn, REG_EH_REGION, XEXP (note, 0));
> > +
>
> How can this work?  If insn has REG_EH_REGION note, you add that note
> to it once more?  At minimum that should be add_reg_note (set_insn, ...).
> But perhaps better use:
>   copy_reg_eh_region_note_forward (insn, set_insn, insn);
> instead?
>
> That said, with either change the testcase ICEs, as we have control flow
> insn in the middle of a bb.
>
> Tried to do:
> --- gcc/config/i386/i386.c.jj   2019-03-13 09:23:37.138538182 +0100
> +++ gcc/config/i386/i386.c  2019-03-13 18:24:07.773761751 +0100
> @@ -91,6 +91,7 @@ along with GCC; see the file COPYING3.
>  #include "tree-vector-builder.h"
>  #include "debug.h"
>  #include "dwarf2out.h"
> +#include "cfgcleanup.h"
>
>  /* This file should be included last.  */
>  #include "target-def.h"
> @@ -2814,6 +2815,9 @@ remove_partial_avx_dependency (void)
>bitmap_obstack_initialize (NULL);
>bitmap convert_bbs = BITMAP_ALLOC (NULL);
>
> +  auto_sbitmap blocks_with_eh (last_basic_block_for_fn (cfun));
> +  bitmap_clear (blocks_with_eh);
> +
>basic_block bb;
>rtx_insn *insn, *set_insn;
>rtx set;
> @@ -2873,6 +2877,15 @@ remove_partial_avx_dependency (void)
>   /* Generate an XMM vector SET.  */
>   set = gen_rtx_SET (vec, src);
>   set_insn = emit_insn_before (set, insn);
> +
> + /* Handle REG_EH_REGION note.  */
> + rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
> + if (note)
> +   {
> + bitmap_set_bit (blocks_with_eh, bb->index);
> + add_reg_note (set_insn, REG_EH_REGION, XEXP (note, 0));
> +   }
> +
>   df_insn_rescan (set_insn);
>
>   src = gen_rtx_SUBREG (dest_mode, vec, 0);
> @@ -2930,6 +2943,14 @@ remove_partial_avx_dependency (void)
>bitmap_obstack_release (NULL);
>BITMAP_FREE (convert_bbs);
>
> +  if (!bitmap_empty_p (blocks_with_eh))
> +{
> +  find_many_sub_basic_blocks (blocks_with_eh);
> +
> +  /* If we've moved any REG_EH_REGION notes, also cleanup the cfg.  */
> +  cleanup_cfg (0);
> +}
> +
>timevar_pop (TV_MACH_DEP);
>return 0;
>  }
>
> but that still ICEs.
>
> Jakub

We need to split the basic block if we create new insns, which may
throw exceptions, in the middle of the basic blocks.

Tested on AVX2 and AVX512 machines with and without

--with-arch=native

OK for trunk?

Thanks.

-- 
H.J.
From 713d7648c4018f2f08e179c165d0360de8ecb618 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" 
Date: Tue, 12 Mar 2019 08:55:24 +0800
Subject: [PATCH] i386: Handle REG_EH_REGION note

When we split:

(insn 18 17 76 2 (set (reg:SF 88 [ _19 ])
(float:SF (mem/c:SI (symbol_ref:DI ("d") [flags 0x2]  ) [1 d+0 S4 A32]))) "x.ii":4:20 170 {*floatsisf2}
 (expr_list:REG_EH_REGION (const_int 2 [0x2])
(nil)))

to

(insn 94 17 18 2 (set (reg:V4SF 115)
(vec_merge:V4SF (vec_duplicate:V4SF (float:SF (mem/c:SI (symbol_ref:DI ("d") [flags 0x2]  ) [1 d+0 S4 A32])))
(reg:V4SF 114)
(const_int 1 [0x1]))) "x.ii":4:20 -1
 (nil))
(insn 18 94 76 2 (set (reg:SF 88 [ _19 ])
(subreg:SF (reg:V4SF 115) 0)) "x.ii":4:20 112 {*movsf_internal}
 (expr_list:REG_EH_REGION (const_int 2 [0x2])
(nil)))

we must copy the REG_EH_REGION note to the first insn and split the block
after the newly added insn.  The REG_EH_REGION on the second insn will be
removed later since it no longer traps.

gcc/

	PR target/89650
	* config/i386/i386.c (remove_partial_avx_dependency): Handle
	REG_EH_REGION note.

gcc/testsuite/

	PR target/89650
	* g++.target/i386/pr89650.C: New test.
---
 gcc/config/i386/i386.c  | 45 +
 gcc/testsuite/g++.target/i386/pr89650.C | 19 +++
 2 files changed, 64 insertions(+)
 create mode 100644 gcc/testsuite/g++.target/i386/pr89650.C