[PATCH] [i386] Optimize __builtin_shuffle_vector.

2021-08-15 Thread liuhongt via Gcc-patches
Hi:
  Here's updated patch which does 3 things:
1. Support vpermw/vpermb in ix86_expand_vec_one_operand_perm_avx512.
2. Support 256/128-bits vpermi2b in ix86_expand_vec_perm_vpermt2.
3. Add define_insn_and_split to optimize specific vector permutation to 
opmov{dw,wb,qd}.

  Bootstrapped and regtested on x86_64-linux-gnu{-m32,}.
  Ok for trunk?

gcc/ChangeLog:

PR target/101846
* config/i386/i386-expand.c (ix86_expand_vec_perm_vpermt2):
Support vpermi2b for V32QI/V16QImode.
(ix86_extract_perm_from_pool_constant): New function.
(ix86_expand_vec_one_operand_perm_avx512): Support
vpermw/vpermb under TARGET_AVX512BW/TARGET_AVX512VBMI.
(expand_vec_perm_1): Adjust comments for upper.
* config/i386/i386-protos.h (ix86_extract_perm_from_pool_constant):
New declare.
* config/i386/predicates.md (permvar_truncate_operand): New predicate.
(pshufb_truncv4siv4hi_operand): Ditto.
(pshufb_truncv8hiv8qi_operand): Ditto.
* config/i386/sse.md (*avx512bw_permvar_truncv16siv16hi_1):
New pre_reload define_insn_and_split.
(*avx512f_permvar_truncv8siv8hi_1): Ditto.
(*avx512f_vpermvar_truncv8div8si_1): Ditto.
(*avx512f_permvar_truncv32hiv32qi_1): Ditto.
(*avx512f_permvar_truncv16hiv16qi_1): Ditto.
(*avx512f_permvar_truncv4div4si_1): Ditto.
(*avx512f_pshufb_truncv8hiv8qi_1): Ditto.
(*avx512f_pshufb_truncv4siv4hi_1): Ditto.
(*avx512f_pshufd_truncv2div2si_1): Ditto.

gcc/testsuite/ChangeLog:

PR target/101846
* gcc.target/i386/pr101846-2.c: New test.
* gcc.target/i386/pr101846-3.c: New test.
* gcc.target/i386/pr101846-4.c: New test.
---
 gcc/config/i386/i386-expand.c  |  89 +-
 gcc/config/i386/i386-protos.h  |   1 +
 gcc/config/i386/predicates.md  |  90 ++
 gcc/config/i386/sse.md | 190 +
 gcc/testsuite/gcc.target/i386/pr101846-2.c |  81 +
 gcc/testsuite/gcc.target/i386/pr101846-3.c |  73 
 gcc/testsuite/gcc.target/i386/pr101846-4.c |  40 +
 7 files changed, 559 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr101846-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr101846-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr101846-4.c

diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index a652b25f534..56319cb6f6a 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -4778,6 +4778,18 @@ ix86_expand_vec_perm_vpermt2 (rtx target, rtx mask, rtx 
op0, rtx op1,
 
   switch (mode)
 {
+case E_V16QImode:
+  if (TARGET_AVX512VL && TARGET_AVX512VBMI)
+   gen = gen_avx512vl_vpermt2varv16qi3;
+  break;
+case E_V32QImode:
+  if (TARGET_AVX512VL && TARGET_AVX512VBMI)
+   gen = gen_avx512vl_vpermt2varv32qi3;
+  break;
+case E_V64QImode:
+  if (TARGET_AVX512VBMI)
+   gen = gen_avx512bw_vpermt2varv64qi3;
+  break;
 case E_V8HImode:
   if (TARGET_AVX512VL && TARGET_AVX512BW)
gen = gen_avx512vl_vpermt2varv8hi3;
@@ -4786,10 +4798,6 @@ ix86_expand_vec_perm_vpermt2 (rtx target, rtx mask, rtx 
op0, rtx op1,
   if (TARGET_AVX512VL && TARGET_AVX512BW)
gen = gen_avx512vl_vpermt2varv16hi3;
   break;
-case E_V64QImode:
-  if (TARGET_AVX512VBMI)
-   gen = gen_avx512bw_vpermt2varv64qi3;
-  break;
 case E_V32HImode:
   if (TARGET_AVX512BW)
gen = gen_avx512bw_vpermt2varv32hi3;
@@ -5487,6 +5495,45 @@ ix86_expand_sse_unpack (rtx dest, rtx src, bool 
unsigned_p, bool high_p)
 }
 }
 
+/* Return true if mem is pool constant which contains a const_vector
+   perm index, assign the index to PERM.  */
+bool
+ix86_extract_perm_from_pool_constant (int* perm, rtx mem)
+{
+  machine_mode mode = GET_MODE (mem);
+  int nelt = GET_MODE_NUNITS (mode);
+
+  if (!INTEGRAL_MODE_P (mode))
+return false;
+
+/* Needs to be constant pool.  */
+  if (!(MEM_P (mem))
+  || !SYMBOL_REF_P (XEXP (mem, 0))
+  || !CONSTANT_POOL_ADDRESS_P (XEXP (mem, 0)))
+   return false;
+
+  rtx constant = get_pool_constant (XEXP (mem, 0));
+
+  if (GET_CODE (constant) != CONST_VECTOR)
+return false;
+
+  /* There could be some rtx like
+ (mem/u/c:V16QI (symbol_ref/u:DI ("*.LC1")))
+ but with "*.LC1" refer to V2DI constant vector.  */
+  if (GET_MODE (constant) != mode)
+{
+  constant = simplify_subreg (mode, constant, GET_MODE (constant), 0);
+
+  if (constant == nullptr || GET_CODE (constant) != CONST_VECTOR)
+   return false;
+}
+
+  for (int i = 0; i != nelt; i++)
+perm[i] = UINTVAL (XVECEXP (constant, 0, i));
+
+  return true;
+}
+
 /* Split operands 0 and 1 into half-mode parts.  Similar to split_double_mode,
but works for floating pointer parameters and nonoffsetable memories.
For pushes, it returns just stack 

Re: [PATCH] Fix ICE when mixing VLAs and statement expressions [PR91038]

2021-08-15 Thread Uecker, Martin
Am Montag, den 16.08.2021, 00:30 -0400 schrieb Jason Merrill:
> On 8/1/21 1:36 PM, Uecker, Martin wrote:
> > 
> > Here is an attempt to fix some old and annoying bugs related
> > to VLAs and statement expressions. In particulary, this seems
> > to fix the issues with variably-modified types which are
> > returned from statement expressions (which works on clang),
> > but there are still bugs remaining related to structs
> > with VLA members (which seems to be a FE bug).
> > 
> > Of course, I might be doing something stupid...
> > 
> > The patch survives bootstrapping and regresstion testing
> > on x86_64.
> 
> Including Ada?


It broke PLACEHOLDER_EXPRs as you pointed out below.

Please take a look at the new version:

https://gcc.gnu.org/pipermail/gcc-patches/2021-August/577402.html

Martin



> > Fix ICE when mixing VLAs and statement expressions [PR91038]
> > 
> > When returning VM-types from statement expressions, this can
> > lead to an ICE when declarations from the statement expression
> > are referred to later. Some of these issues can be addressed by
> > gimplifying the base expression earlier in gimplify_compound_lval.
> > This fixes PR91038 and some of the test cases from PR29970
> > (structs with VLA members need further work).
> > 
> >  
> >  2021-08-01  Martin Uecker  
> >  
> >  gcc/
> > PR c/91038
> > PR c/29970
> > * gimplify.c (gimplify_var_or_parm_decl): Update comment.
> > (gimplify_compound_lval): Gimplify base expression first.
> >  
> >  gcc/testsuite/
> > PR c/91038
> > PR c/29970
> > * gcc.dg/vla-stexp-01.c: New test.
> > * gcc.dg/vla-stexp-02.c: New test.
> > * gcc.dg/vla-stexp-03.c: New test.
> > * gcc.dg/vla-stexp-04.c: New test.
> > 
> > 
> > diff --git a/gcc/gimplify.c b/gcc/gimplify.c
> > index 21ff32ee4aa..885d5f73585 100644
> > --- a/gcc/gimplify.c
> > +++ b/gcc/gimplify.c
> > @@ -2839,7 +2839,10 @@ gimplify_var_or_parm_decl (tree *expr_p)
> >declaration, for which we've already issued an error.  It would
> >be really nice if the front end wouldn't leak these at all.
> >Currently the only known culprit is C++ destructors, as seen
> > - in g++.old-deja/g++.jason/binding.C.  */
> > + in g++.old-deja/g++.jason/binding.C.
> > + Another culpit are size expressions for variably modified
> > + types which are lost in the FE or not gimplified correctly.
> > +  */
> > if (VAR_P (decl)
> > && !DECL_SEEN_IN_BIND_EXPR_P (decl)
> > && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
> > @@ -2984,9 +2987,23 @@ gimplify_compound_lval (tree *expr_p, gimple_seq 
> > *pre_p, gimple_seq
> > *post_p,
> >expression until we deal with any variable bounds, sizes, or
> >positions in order to deal with PLACEHOLDER_EXPRs.
> >   
> > - So we do this in three steps.  First we deal with the annotations
> > - for any variables in the components, then we gimplify the base,
> > - then we gimplify any indices, from left to right.  */
> > + So we do this in three steps.  First we gimplify the base,
> > + then we deal with the annotations for any variables in the
> > + components, then we gimplify any indices, from left to right.
> > +
> > + The base expression may contain a statement expression that
> > + has declarations used in size expressions, so has to be
> > + gimplified first. */
> 
> The previous paragraph says,
> 
> >   But we can't gimplify the
> > inner   
> >  expression until we deal with any variable bounds, sizes,
> > or  
> >  positions in order to deal with PLACEHOLDER_EXPRs. 
> 
> so I would expect your change to break examples that the current code 
> was designed to handle.  The change to delay gimplifying the inner 
> expression was in r0-59131 (SVN r83474), by Richard Kenner.  But there 
> aren't any testcases in that commit.  Richard, any insight?  Can you 
> review this patch?



> > +  /* Step 1 is to gimplify the base expression.  Make sure lvalue is set
> > + so as to match the min_lval predicate.  Failure to do so may result
> > + in the creation of large aggregate temporaries.  */
> > +  tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
> > +   fallback | fb_lvalue);
> > +
> > +  ret = MIN (ret, tret);
> > +
> > +
> > for (i = expr_stack.length () - 1; i >= 0; i--)
> >   {
> > tree t = expr_stack[i];
> > @@ -3076,12 +3093,6 @@ gimplify_compound_lval (tree *expr_p, gimple_seq 
> > *pre_p, gimple_seq
> > *post_p,
> > }
> >   }
> >   
> > -  /* Step 2 is to gimplify the base expression.  Make sure lvalue is set
> > - so as to match the min_lval predicate.  Failure to do so may result
> > - in the creation of large aggregate temporaries.  */
> > -  tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
> > -   

Re: [PATCH] RISC-V: Allow multi-lib build with different code model

2021-08-15 Thread Kito Cheng
Committed to trunk.

On Wed, Jul 21, 2021 at 4:45 PM Kito Cheng  wrote:
>
> --with-multilib-generator was only support for different ISA/ABI
> combination, however code model is effect the code gen a lots it
> should able to handled in multilib mechanism.
>
> Adding `--cmodel=` option to `--with-multilib-generator` to generating
> multilib combination with different code model.
>
> E.g.
> --with-multilib-generator="rv64ima-lp64--;--cmodel=medlow,medany"
> will generate 3 multi-lib suppport:
> 1) rv64ima with lp64
> 2) rv64ima with lp64 and medlow code model
> 3) rv64ima with lp64 and medany code model
>
> gcc/
>
> * config/riscv/multilib-generator: Support code model option for
> multi-lib.
> * doc/install.texi: Add document of new option for
> --with-multilib-generator.
> ---
>  gcc/config/riscv/multilib-generator | 86 +++--
>  gcc/doc/install.texi| 17 ++
>  2 files changed, 73 insertions(+), 30 deletions(-)
>
> diff --git a/gcc/config/riscv/multilib-generator 
> b/gcc/config/riscv/multilib-generator
> index fe115b3184f..1164d1c5c8e 100755
> --- a/gcc/config/riscv/multilib-generator
> +++ b/gcc/config/riscv/multilib-generator
> @@ -40,6 +40,7 @@ import collections
>  import itertools
>  from functools import reduce
>  import subprocess
> +import argparse
>
>  #
>  # TODO: Add test for this script.
> @@ -127,44 +128,69 @@ def expand_combination(ext):
>
>return ext
>
> -for cfg in sys.argv[1:]:
> -  try:
> -(arch, abi, extra, ext) = cfg.split('-')
> -  except:
> -print ("Invalid configure string %s, ---\n"
> -   " and  can be empty, "
> -   "e.g. rv32imafd-ilp32--" % cfg)
> -sys.exit(1)
> -
> -  arch = arch_canonicalize (arch)
> -  arches[arch] = 1
> -  abis[abi] = 1
> -  extra = list(filter(None, extra.split(',')))
> -  ext_combs = expand_combination(ext)
> -  alts = sum([[x] + [x + y for y in ext_combs] for x in [arch] + extra], [])
> -  alts = list(map(arch_canonicalize, alts))
> +multilib_cfgs = filter(lambda x:not x.startswith("--"), sys.argv[1:])
> +options = filter(lambda x:x.startswith("--"), sys.argv[1:])
> +
> +parser = argparse.ArgumentParser()
> +parser.add_argument("--cmodel", type=str)
> +parser.add_argument("cfgs", type=str, nargs='*')
> +args = parser.parse_args()
> +
> +if args.cmodel:
> +  cmodels = [None] + args.cmodel.split(",")
> +else:
> +  cmodels = [None]
> +
> +cmodel_options = '/'.join(['mcmodel=%s' % x for x in cmodels[1:]])
> +cmodel_dirnames = ' \\\n'.join(cmodels[1:])
> +
> +for cmodel in cmodels:
> +  for cfg in args.cfgs:
> +try:
> +  (arch, abi, extra, ext) = cfg.split('-')
> +except:
> +  print ("Invalid configure string %s, 
> ---\n"
> + " and  can be empty, "
> + "e.g. rv32imafd-ilp32--" % cfg)
> +  sys.exit(1)
> +
> +# Compact code model only support rv64.
> +if cmodel == "compact" and arch.startswith("rv32"):
> +  continue
>
> -  # Drop duplicated entry.
> -  alts = unique(alts)
> +arch = arch_canonicalize (arch)
> +arches[arch] = 1
> +abis[abi] = 1
> +extra = list(filter(None, extra.split(',')))
> +ext_combs = expand_combination(ext)
> +alts = sum([[x] + [x + y for y in ext_combs] for x in [arch] + extra], 
> [])
> +alts = list(map(arch_canonicalize, alts))
>
> -  for alt in alts:
> -if alt == arch:
> -  continue
> -arches[alt] = 1
> -reuse.append('march.%s/mabi.%s=march.%s/mabi.%s' % (arch, abi, alt, abi))
> -  required.append('march=%s/mabi=%s' % (arch, abi))
> +# Drop duplicated entry.
> +alts = unique(alts)
> +
> +for alt in alts[1:]:
> +  if alt == arch:
> +continue
> +  arches[alt] = 1
> +  reuse.append('march.%s/mabi.%s=march.%s/mabi.%s' % (arch, abi, alt, 
> abi))
> +
> +if cmodel:
> +  required.append('march=%s/mabi=%s/mcmodel=%s' % (arch, abi, cmodel))
> +else:
> +  required.append('march=%s/mabi=%s' % (arch, abi))
>
> -arch_options = '/'.join(['march=%s' % x for x in arches.keys()])
> -arch_dirnames = ' \\\n'.join(arches.keys())
> +  arch_options = '/'.join(['march=%s' % x for x in arches.keys()])
> +  arch_dirnames = ' \\\n'.join(arches.keys())
>
> -abi_options = '/'.join(['mabi=%s' % x for x in abis.keys()])
> -abi_dirnames = ' \\\n'.join(abis.keys())
> +  abi_options = '/'.join(['mabi=%s' % x for x in abis.keys()])
> +  abi_dirnames = ' \\\n'.join(abis.keys())
>
>  prog = sys.argv[0].split('/')[-1]
>  print('# This file was generated by %s with the command:' % prog)
>  print('#  %s' % ' '.join(sys.argv))
>
> -print('MULTILIB_OPTIONS = %s %s' % (arch_options, abi_options))
> -print('MULTILIB_DIRNAMES = %s %s' % (arch_dirnames, abi_dirnames))
> +print('MULTILIB_OPTIONS = %s %s %s' % (arch_options, abi_options, 
> cmodel_options))
> +print('MULTILIB_DIRNAMES = %s %s %s' % (arch_dirnames, abi_dirnames, 
> cmodel_dirnames))
>  print('MULTILIB_REQUIRED = %s' % ' \\\n'.join(required))
>  print('MULTILIB_REUSE 

Re: [PATCH] Fix ICE when mixing VLAs and statement expressions [PR91038]

2021-08-15 Thread Jason Merrill via Gcc-patches

On 8/1/21 1:36 PM, Uecker, Martin wrote:



Here is an attempt to fix some old and annoying bugs related
to VLAs and statement expressions. In particulary, this seems
to fix the issues with variably-modified types which are
returned from statement expressions (which works on clang),
but there are still bugs remaining related to structs
with VLA members (which seems to be a FE bug).

Of course, I might be doing something stupid...

The patch survives bootstrapping and regresstion testing
on x86_64.


Including Ada?


Fix ICE when mixing VLAs and statement expressions [PR91038]

When returning VM-types from statement expressions, this can
lead to an ICE when declarations from the statement expression
are referred to later. Some of these issues can be addressed by
gimplifying the base expression earlier in gimplify_compound_lval.
This fixes PR91038 and some of the test cases from PR29970
(structs with VLA members need further work).

 
 2021-08-01  Martin Uecker  
 
 gcc/

PR c/91038
PR c/29970
* gimplify.c (gimplify_var_or_parm_decl): Update comment.
(gimplify_compound_lval): Gimplify base expression first.
 
 gcc/testsuite/

PR c/91038
PR c/29970
* gcc.dg/vla-stexp-01.c: New test.
* gcc.dg/vla-stexp-02.c: New test.
* gcc.dg/vla-stexp-03.c: New test.
* gcc.dg/vla-stexp-04.c: New test.


diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 21ff32ee4aa..885d5f73585 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -2839,7 +2839,10 @@ gimplify_var_or_parm_decl (tree *expr_p)
   declaration, for which we've already issued an error.  It would
   be really nice if the front end wouldn't leak these at all.
   Currently the only known culprit is C++ destructors, as seen
- in g++.old-deja/g++.jason/binding.C.  */
+ in g++.old-deja/g++.jason/binding.C.
+ Another culpit are size expressions for variably modified
+ types which are lost in the FE or not gimplified correctly.
+  */
if (VAR_P (decl)
&& !DECL_SEEN_IN_BIND_EXPR_P (decl)
&& !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
@@ -2984,9 +2987,23 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
   expression until we deal with any variable bounds, sizes, or
   positions in order to deal with PLACEHOLDER_EXPRs.
  
- So we do this in three steps.  First we deal with the annotations

- for any variables in the components, then we gimplify the base,
- then we gimplify any indices, from left to right.  */
+ So we do this in three steps.  First we gimplify the base,
+ then we deal with the annotations for any variables in the
+ components, then we gimplify any indices, from left to right.
+
+ The base expression may contain a statement expression that
+ has declarations used in size expressions, so has to be
+ gimplified first. */


The previous paragraph says,

  But we can't gimplify the inner   
 expression until we deal with any variable bounds, sizes, or  
 positions in order to deal with PLACEHOLDER_EXPRs. 


so I would expect your change to break examples that the current code 
was designed to handle.  The change to delay gimplifying the inner 
expression was in r0-59131 (SVN r83474), by Richard Kenner.  But there 
aren't any testcases in that commit.  Richard, any insight?  Can you 
review this patch?



+  /* Step 1 is to gimplify the base expression.  Make sure lvalue is set
+ so as to match the min_lval predicate.  Failure to do so may result
+ in the creation of large aggregate temporaries.  */
+  tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
+   fallback | fb_lvalue);
+
+  ret = MIN (ret, tret);
+
+
for (i = expr_stack.length () - 1; i >= 0; i--)
  {
tree t = expr_stack[i];
@@ -3076,12 +3093,6 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
}
  }
  
-  /* Step 2 is to gimplify the base expression.  Make sure lvalue is set

- so as to match the min_lval predicate.  Failure to do so may result
- in the creation of large aggregate temporaries.  */
-  tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
-   fallback | fb_lvalue);
-  ret = MIN (ret, tret);
  
/* And finally, the indices and operands of ARRAY_REF.  During this

   loop we also remove any useless conversions.  */
diff --git a/gcc/testsuite/gcc.dg/vla-stexpr-01.c 
b/gcc/testsuite/gcc.dg/vla-stexpr-01.c
new file mode 100644
index 000..27e1817eb63
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vla-stexpr-01.c
@@ -0,0 +1,94 @@
+/* PR29970, PR91038 */
+/* { dg-do run } */
+/* { dg-options "-O0" } */
+
+int foo3b(void)   // should not return 0
+{
+int n = 0;
+return sizeof *({ n = 10; int x[n]; 

Re: Ping: [PATCH v2] Analyze niter for until-wrap condition [PR101145]

2021-08-15 Thread Bin.Cheng via Gcc-patches
On Wed, Aug 4, 2021 at 10:42 AM guojiufu  wrote:
>
> Hi,
>
> I would like to have a ping on this.
>
> https://gcc.gnu.org/pipermail/gcc-patches/2021-July/574596.html
Sorry for being late in replying.

>
> BR,
> Jiufu
>
> On 2021-07-15 08:17, guojiufu via Gcc-patches wrote:
> > Hi,
> >
> > I would like to have an early ping on this with more mail addresses.
> >
> > BR,
> > Jiufu.
> >
> > On 2021-07-07 20:47, Jiufu Guo wrote:
> >> Changes since v1:
> >> * Update assumptions for niter, add more test cases check
> >> * Use widest_int/wide_int instead mpz to do +-/
> >> * Move some early check for quick return
> >>
> >> For code like:
> >> unsigned foo(unsigned val, unsigned start)
> >> {
> >>   unsigned cnt = 0;
> >>   for (unsigned i = start; i > val; ++i)
> >> cnt++;
> >>   return cnt;
> >> }
> >>
> >> The number of iterations should be about UINT_MAX - start.
> >>
> >> There is function adjust_cond_for_loop_until_wrap which
> >> handles similar work for const bases.
> >> Like adjust_cond_for_loop_until_wrap, this patch enhance
> >> function number_of_iterations_cond/number_of_iterations_lt
> >> to analyze number of iterations for this kind of loop.
> >>
> >> Bootstrap and regtest pass on powerpc64le, x86_64 and aarch64.
> >> Is this ok for trunk?
> >>
> >> gcc/ChangeLog:
> >>
> >> 2021-07-07  Jiufu Guo  
> >>
> >>  PR tree-optimization/101145
> >>  * tree-ssa-loop-niter.c (number_of_iterations_until_wrap):
> >>  New function.
> >>  (number_of_iterations_lt): Invoke above function.
> >>  (adjust_cond_for_loop_until_wrap):
> >>  Merge to number_of_iterations_until_wrap.
> >>  (number_of_iterations_cond): Update invokes for
> >>  adjust_cond_for_loop_until_wrap and number_of_iterations_lt.
> >>
> >> gcc/testsuite/ChangeLog:
> >>
> >> 2021-07-07  Jiufu Guo  
> >>
> >>  PR tree-optimization/101145
> >>  * gcc.dg/vect/pr101145.c: New test.
> >>  * gcc.dg/vect/pr101145.inc: New test.
> >>  * gcc.dg/vect/pr101145_1.c: New test.
> >>  * gcc.dg/vect/pr101145_2.c: New test.
> >>  * gcc.dg/vect/pr101145_3.c: New test.
> >>  * gcc.dg/vect/pr101145inf.c: New test.
> >>  * gcc.dg/vect/pr101145inf.inc: New test.
> >>  * gcc.dg/vect/pr101145inf_1.c: New test.
> >> ---
> >>  gcc/testsuite/gcc.dg/vect/pr101145.c  | 187
> >> ++
> >>  gcc/testsuite/gcc.dg/vect/pr101145.inc|  63 
> >>  gcc/testsuite/gcc.dg/vect/pr101145_1.c|  15 ++
> >>  gcc/testsuite/gcc.dg/vect/pr101145_2.c|  15 ++
> >>  gcc/testsuite/gcc.dg/vect/pr101145_3.c|  15 ++
> >>  gcc/testsuite/gcc.dg/vect/pr101145inf.c   |  25 +++
> >>  gcc/testsuite/gcc.dg/vect/pr101145inf.inc |  28 
> >>  gcc/testsuite/gcc.dg/vect/pr101145inf_1.c |  23 +++
> >>  gcc/tree-ssa-loop-niter.c | 157 ++
> >>  9 files changed, 463 insertions(+), 65 deletions(-)
> >>  create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145.c
> >>  create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145.inc
> >>  create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145_1.c
> >>  create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145_2.c
> >>  create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145_3.c
> >>  create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145inf.c
> >>  create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145inf.inc
> >>  create mode 100644 gcc/testsuite/gcc.dg/vect/pr101145inf_1.c
> >>
> >> diff --git a/gcc/testsuite/gcc.dg/vect/pr101145.c
> >> b/gcc/testsuite/gcc.dg/vect/pr101145.c
> >> new file mode 100644
> >> index 000..74031b031cf
> >> --- /dev/null
> >> +++ b/gcc/testsuite/gcc.dg/vect/pr101145.c
> >> @@ -0,0 +1,187 @@
> >> +/* { dg-require-effective-target vect_int } */
> >> +/* { dg-options "-O3 -fdump-tree-vect-details" } */
> >> +#include 
> >> +
> >> +unsigned __attribute__ ((noinline))
> >> +foo (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned
> >> n)
> >> +{
> >> +  while (n < ++l)
> >> +*a++ = *b++ + 1;
> >> +  return l;
> >> +}
> >> +
> >> +unsigned __attribute__ ((noinline))
> >> +foo_1 (int *__restrict__ a, int *__restrict__ b, unsigned l,
> >> unsigned)
> >> +{
> >> +  while (UINT_MAX - 64 < ++l)
> >> +*a++ = *b++ + 1;
> >> +  return l;
> >> +}
> >> +
> >> +unsigned __attribute__ ((noinline))
> >> +foo_2 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned
> >> n)
> >> +{
> >> +  l = UINT_MAX - 32;
> >> +  while (n < ++l)
> >> +*a++ = *b++ + 1;
> >> +  return l;
> >> +}
> >> +
> >> +unsigned __attribute__ ((noinline))
> >> +foo_3 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned
> >> n)
> >> +{
> >> +  while (n <= ++l)
> >> +*a++ = *b++ + 1;
> >> +  return l;
> >> +}
> >> +
> >> +unsigned __attribute__ ((noinline))
> >> +foo_4 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned
> >> n)
> >> +{  // infininate
> >> +  while (0 <= ++l)
> >> +*a++ = *b++ + 1;
> >> +  return l;
> >> +}
> >> +
> >> +unsigned __attribute__ ((noinline))
> >> +foo_5 (int 

Re: [PATCH 1/2] analyzer: detect and analyze calls via function pointer (GSoC)

2021-08-15 Thread David Malcolm via Gcc-patches
On Sun, 2021-08-15 at 20:28 +0530, Ankur Saini wrote:
> The patch extends the analyser’s functionality to understand and
> analyze indirect calls (calls via a function pointer or calls to
> virtual functions ) 
> 
> On successful merging, the patch should also fix the following bugs :- 
> 
> 1. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100546
> 2. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97114 
> 

Thanks, this is looking promising.  Has this been rebased recently
(e.g. since I merged
  https://gcc.gnu.org/pipermail/gcc-patches/2021-August/576737.html )
and have you run the test suite on this version?

I've posted various minor nits below, and a request for more test
coverage, but this is close to being ready to commit.

> Subject: [PATCH 1/2] analyzer: detect and analyze calls via function pointer

> 2021-07-29  Ankur Saini  >
> gcc/analyzer/ChangeLog:


[...snip...]

The ChangeLog entries should reference the pertinent bugs with:

PR analyzer/97114
PR analyzer/100546

See the existing ChangeLog file for examples of how this is done.

[...snip...]

> /* class rewind_info_t : public exploded_edge::custom_info_t.  */
> 
> /* Implementation of exploded_edge::custom_info_t::update_model vfunc
> @@ -2980,6 +3024,61 @@ state_change_requires_new_enode_p (const program_state 
> _state,
> return false;
> }
> 
> +/* Create enodes and eedges for the function calls that doesn't have an 
> +   underlying call superedge.
> +
> +   Such case occurs when GCC's middle end didn't know which function to
> +   call but analyzer do (with the help of current state).

Grammar nit: "but analyzer do" -> "but the analyzer does"

[...snip...]

> @@ -3174,10 +3273,13 @@ exploded_graph::process_node (exploded_node *node)
> break;
> case PK_AFTER_SUPERNODE:
> {
> +bool found_a_superedge = false;
> +bool is_an_exit_block = false;
> /* If this is an EXIT BB, detect leaks, and potentially
> create a function summary.  */
> if (point.get_supernode ()->return_p ())
> {
> + is_an_exit_block = true;
> node->detect_leaks (*this);
> if (flag_analyzer_call_summaries
> && point.get_call_string ().empty_p ())
> @@ -3205,6 +3307,7 @@ exploded_graph::process_node (exploded_node *node)
> superedge *succ;
> FOR_EACH_VEC_ELT (point.get_supernode ()->m_succs, i, succ)
> {
> + found_a_superedge = true;
> if (logger)
> logger->log ("considering SN: %i -> SN: %i",
> succ->m_src->m_index, succ->m_dest->m_index);
> @@ -3214,6 +3317,54 @@ exploded_graph::process_node (exploded_node *node)
> point.get_call_string ());
> program_state next_state (state);
> uncertainty_t uncertainty;
> +
> +/* Make use the current state and try to discover and analyse
> +   indirect function calls (calls that doesn't hage underlying

Grammar and spelling nit: "calls that doesn't hage" -> "a call that doesn't 
have an"

[...snip...]

> diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h
> index 8f48d8a286c..acfd5fd7167 100644
> --- a/gcc/analyzer/exploded-graph.h
> +++ b/gcc/analyzer/exploded-graph.h
> @@ -362,6 +362,37 @@ private:
> DISABLE_COPY_AND_ASSIGN (exploded_edge);
> };
> 
> +/* Extra data for an exploded_edge that represents a dynamic call info ( 
> calls
> +   that doesn't have a superedge representing the call ).  */

Similar grammar nit here

[...snip...]

> diff --git a/gcc/analyzer/state-purge.cc b/gcc/analyzer/state-purge.cc
> index e82ea87e735..c4050c2cf9a 100644
> --- a/gcc/analyzer/state-purge.cc
> +++ b/gcc/analyzer/state-purge.cc
> @@ -377,18 +377,32 @@ state_purge_per_ssa_name::process_point (const 
> function_point ,
> {
> /* Add any intraprocedually edge for a call.  */
> if (snode->m_returning_call)
> -   {
> - cgraph_edge *cedge
> + {
> +   gcall *returning_call = snode->m_returning_call;
> +   cgraph_edge *cedge
> = supergraph_call_edge (snode->m_fun,
> -   snode->m_returning_call);
> - gcc_assert (cedge);
> - superedge *sedge
> -   = map.get_sg ().get_intraprocedural_edge_for_call (cedge);
> - gcc_assert (sedge);
> - add_to_worklist
> -   (function_point::after_supernode (sedge->m_src),
> -worklist, logger);
> -   }
> +   returning_call);

I think that in the following it would be more readable to reverse the
sense of the condition, so that rather than:

if (!cedge)
  {
// code for NULL cedge
  }
else
  {
// code for non-NULL cedge
  }

instead have:

if (cedge)
  {
// code for non-NULL cedge
  }
else
  {
// code for NULL cedge
  }

to avoid having a double-negative when reasoning about the "else" clause.

> +   if(!cedge)
> + {
> +   supernode *callernode 
> +  

[PATCH 1/2] analyzer: detect and analyze calls via function pointer (GSoC)

2021-08-15 Thread Ankur Saini via Gcc-patches
The patch extends the analyser’s functionality to understand and analyze 
indirect calls (calls via a function pointer or calls to virtual functions ) 

On successful merging, the patch should also fix the following bugs :- 

1. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100546
2. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97114 

Patch :


vfunc.patch
Description: Binary data


Thanks 
- Ankur