[PATCH] Disallow pointer operands for |, ^ and partly & [PR106878]

2022-09-14 Thread Jakub Jelinek via Gcc-patches
Hi!

My change to match.pd (that added the two simplifications this patch
touches) results in more |/^/& assignments with pointer arguments,
but since r12-1608 we reject pointer operands for BIT_NOT_EXPR.

Disallowing them for BIT_NOT_EXPR and allowing for BIT_{IOR,XOR,AND}_EXPR
leads to a match.pd maintainance nightmare (see one of the patches in the
PR), so either we want to allow pointer operand on BIT_NOT_EXPR (but then
we run into issues e.g. with the ranger which expects it can emulate
BIT_NOT_EXPR ~X as - 1 - X which doesn't work for pointers which don't
support MINUS_EXPR), or the following patch disallows pointer arguments
for all of BIT_{IOR,XOR,AND}_EXPR with the exception of BIT_AND_EXPR
with INTEGER_CST last operand (for simpler pointer realignment).
I had to tweak one reassoc optimization and the two match.pd
simplifications.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

P.S.: I know it would be better for the verifiers to have positive
set of types it wants to allow for each operation, but I have no idea
what exactly we use there right now.

2022-09-14  Jakub Jelinek  

PR tree-optimization/106878
* tree-cfg.cc (verify_gimple_assign_binary): Disallow pointer,
reference or OFFSET_TYPE BIT_IOR_EXPR, BIT_XOR_EXPR or, unless
the second argument is INTEGER_CST, BIT_AND_EXPR.
* match.pd ((type) X op CST -> (type) (X op ((type-x) CST)),
(type) (((type2) X) op Y) -> (X op (type) Y)): Punt for
POINTER_TYPE_P or OFFSET_TYPE.
* tree-ssa-reassoc.cc (optimize_range_tests_cmp_bitwise): For
pointers cast them to pointer sized integers first.

* gcc.c-torture/compile/pr106878.c: New test.

--- gcc/tree-cfg.cc.jj  2022-09-08 20:22:07.788184491 +0200
+++ gcc/tree-cfg.cc 2022-09-13 09:28:53.563243962 +0200
@@ -4167,6 +4167,8 @@ verify_gimple_assign_binary (gassign *st
 case ROUND_MOD_EXPR:
 case RDIV_EXPR:
 case EXACT_DIV_EXPR:
+case BIT_IOR_EXPR:
+case BIT_XOR_EXPR:
   /* Disallow pointer and offset types for many of the binary gimple. */
   if (POINTER_TYPE_P (lhs_type)
  || TREE_CODE (lhs_type) == OFFSET_TYPE)
@@ -4182,9 +4184,23 @@ verify_gimple_assign_binary (gassign *st
 
 case MIN_EXPR:
 case MAX_EXPR:
-case BIT_IOR_EXPR:
-case BIT_XOR_EXPR:
+  /* Continue with generic binary expression handling.  */
+  break;
+
 case BIT_AND_EXPR:
+  if (POINTER_TYPE_P (lhs_type)
+ && TREE_CODE (rhs2) == INTEGER_CST)
+   break;
+  /* Disallow pointer and offset types for many of the binary gimple. */
+  if (POINTER_TYPE_P (lhs_type)
+ || TREE_CODE (lhs_type) == OFFSET_TYPE)
+   {
+ error ("invalid types for %qs", code_name);
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
+ debug_generic_expr (rhs2_type);
+ return true;
+   }
   /* Continue with generic binary expression handling.  */
   break;
 
--- gcc/match.pd.jj 2022-09-08 20:22:00.836276502 +0200
+++ gcc/match.pd2022-09-13 10:21:04.567853941 +0200
@@ -1763,6 +1763,8 @@ (define_operator_list SYNC_FETCH_AND_AND
 && (int_fits_type_p (@1, TREE_TYPE (@0))
 || tree_nop_conversion_p (TREE_TYPE (@0), type)))
|| types_match (@0, @1))
+   && !POINTER_TYPE_P (TREE_TYPE (@0))
+   && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE
/* ???  This transform conflicts with fold-const.cc doing
  Convert (T)(x & c) into (T)x & (T)c, if c is an integer
  constants (if x has signed type, the sign bit cannot be set
@@ -1799,7 +1801,9 @@ (define_operator_list SYNC_FETCH_AND_AND
   (if (GIMPLE
&& TREE_CODE (@1) != INTEGER_CST
&& tree_nop_conversion_p (type, TREE_TYPE (@2))
-   && types_match (type, @0))
+   && types_match (type, @0)
+   && !POINTER_TYPE_P (TREE_TYPE (@0))
+   && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE)
(bitop @0 (convert @1)
 
 (for bitop (bit_and bit_ior)
--- gcc/tree-ssa-reassoc.cc.jj  2022-06-28 13:03:31.292684917 +0200
+++ gcc/tree-ssa-reassoc.cc 2022-09-13 10:18:27.466085947 +0200
@@ -3608,10 +3608,14 @@ optimize_range_tests_cmp_bitwise (enum t
tree type2 = NULL_TREE;
bool strict_overflow_p = false;
candidates.truncate (0);
+   if (POINTER_TYPE_P (type1))
+ type1 = pointer_sized_int_node;
for (j = i; j; j = chains[j - 1])
  {
tree type = TREE_TYPE (ranges[j - 1].exp);
strict_overflow_p |= ranges[j - 1].strict_overflow_p;
+   if (POINTER_TYPE_P (type))
+ type = pointer_sized_int_node;
if ((b % 4) == 3)
  {
/* For the signed < 0 cases, the types should be
@@ -3642,6 +3646,8 @@ optimize_range_tests_cmp_bitwise (enum t
tree type = TREE_TYPE (ranges[j - 1].exp);
if (j == k)
  continue;
+   if (POINTER_TYPE_P (t

Re: [PATCH] Disallow pointer operands for |, ^ and partly & [PR106878]

2022-09-14 Thread Richard Biener via Gcc-patches
On Wed, 14 Sep 2022, Jakub Jelinek wrote:

> Hi!
> 
> My change to match.pd (that added the two simplifications this patch
> touches) results in more |/^/& assignments with pointer arguments,
> but since r12-1608 we reject pointer operands for BIT_NOT_EXPR.
> 
> Disallowing them for BIT_NOT_EXPR and allowing for BIT_{IOR,XOR,AND}_EXPR
> leads to a match.pd maintainance nightmare (see one of the patches in the
> PR), so either we want to allow pointer operand on BIT_NOT_EXPR (but then
> we run into issues e.g. with the ranger which expects it can emulate
> BIT_NOT_EXPR ~X as - 1 - X which doesn't work for pointers which don't
> support MINUS_EXPR), or the following patch disallows pointer arguments
> for all of BIT_{IOR,XOR,AND}_EXPR with the exception of BIT_AND_EXPR
> with INTEGER_CST last operand (for simpler pointer realignment).
> I had to tweak one reassoc optimization and the two match.pd
> simplifications.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Did you check what breaks when we reverse the decision to allow
BIT_AND_EXPR to align pointers alltogether?  I think we don't
have any

 (T')(((T)ptr) & CST) -> ptr & CST

folding at least.  But I guess some passes that build pointer
re-alignments might need adjustment.

> P.S.: I know it would be better for the verifiers to have positive
> set of types it wants to allow for each operation, but I have no idea
> what exactly we use there right now.

I think for BIT_*_EXPR we want ANY_INTEGRAL_TYPE_P (well, likely
not complex int, but ...).  So if a patch to check that passes
bootstrap that would be nice to have.

Richard.

> 2022-09-14  Jakub Jelinek  
> 
>   PR tree-optimization/106878
>   * tree-cfg.cc (verify_gimple_assign_binary): Disallow pointer,
>   reference or OFFSET_TYPE BIT_IOR_EXPR, BIT_XOR_EXPR or, unless
>   the second argument is INTEGER_CST, BIT_AND_EXPR.
>   * match.pd ((type) X op CST -> (type) (X op ((type-x) CST)),
>   (type) (((type2) X) op Y) -> (X op (type) Y)): Punt for
>   POINTER_TYPE_P or OFFSET_TYPE.
>   * tree-ssa-reassoc.cc (optimize_range_tests_cmp_bitwise): For
>   pointers cast them to pointer sized integers first.
> 
>   * gcc.c-torture/compile/pr106878.c: New test.
> 
> --- gcc/tree-cfg.cc.jj2022-09-08 20:22:07.788184491 +0200
> +++ gcc/tree-cfg.cc   2022-09-13 09:28:53.563243962 +0200
> @@ -4167,6 +4167,8 @@ verify_gimple_assign_binary (gassign *st
>  case ROUND_MOD_EXPR:
>  case RDIV_EXPR:
>  case EXACT_DIV_EXPR:
> +case BIT_IOR_EXPR:
> +case BIT_XOR_EXPR:
>/* Disallow pointer and offset types for many of the binary gimple. */
>if (POINTER_TYPE_P (lhs_type)
> || TREE_CODE (lhs_type) == OFFSET_TYPE)
> @@ -4182,9 +4184,23 @@ verify_gimple_assign_binary (gassign *st
>  
>  case MIN_EXPR:
>  case MAX_EXPR:
> -case BIT_IOR_EXPR:
> -case BIT_XOR_EXPR:
> +  /* Continue with generic binary expression handling.  */
> +  break;
> +
>  case BIT_AND_EXPR:
> +  if (POINTER_TYPE_P (lhs_type)
> +   && TREE_CODE (rhs2) == INTEGER_CST)
> + break;
> +  /* Disallow pointer and offset types for many of the binary gimple. */
> +  if (POINTER_TYPE_P (lhs_type)
> +   || TREE_CODE (lhs_type) == OFFSET_TYPE)
> + {
> +   error ("invalid types for %qs", code_name);
> +   debug_generic_expr (lhs_type);
> +   debug_generic_expr (rhs1_type);
> +   debug_generic_expr (rhs2_type);
> +   return true;
> + }
>/* Continue with generic binary expression handling.  */
>break;
>  
> --- gcc/match.pd.jj   2022-09-08 20:22:00.836276502 +0200
> +++ gcc/match.pd  2022-09-13 10:21:04.567853941 +0200
> @@ -1763,6 +1763,8 @@ (define_operator_list SYNC_FETCH_AND_AND
>&& (int_fits_type_p (@1, TREE_TYPE (@0))
>|| tree_nop_conversion_p (TREE_TYPE (@0), type)))
>   || types_match (@0, @1))
> +   && !POINTER_TYPE_P (TREE_TYPE (@0))
> +   && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE
> /* ???  This transform conflicts with fold-const.cc doing
> Convert (T)(x & c) into (T)x & (T)c, if c is an integer
> constants (if x has signed type, the sign bit cannot be set
> @@ -1799,7 +1801,9 @@ (define_operator_list SYNC_FETCH_AND_AND
>(if (GIMPLE
> && TREE_CODE (@1) != INTEGER_CST
> && tree_nop_conversion_p (type, TREE_TYPE (@2))
> -   && types_match (type, @0))
> +   && types_match (type, @0)
> +   && !POINTER_TYPE_P (TREE_TYPE (@0))
> +   && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE)
> (bitop @0 (convert @1)
>  
>  (for bitop (bit_and bit_ior)
> --- gcc/tree-ssa-reassoc.cc.jj2022-06-28 13:03:31.292684917 +0200
> +++ gcc/tree-ssa-reassoc.cc   2022-09-13 10:18:27.466085947 +0200
> @@ -3608,10 +3608,14 @@ optimize_range_tests_cmp_bitwise (enum t
>   tree type2 = NULL_TREE;
>   bool strict_overflow_p = false;
>   candidates.truncate (0);
> + 

Re: [PATCH 3/3] vect: inbranch SIMD clones

2022-09-14 Thread Richard Biener via Gcc-patches
On Fri, 9 Sep 2022, Jakub Jelinek wrote:

> On Tue, Aug 09, 2022 at 02:23:50PM +0100, Andrew Stubbs wrote:
> > 
> > There has been support for generating "inbranch" SIMD clones for a long 
> > time,
> > but nothing actually uses them (as far as I can see).
> 
> Thanks for working on this.
> 
> Note, there is another case where the inbranch SIMD clones could be used
> and I even thought it is implemented, but apparently it isn't or it doesn't
> work:
> #ifndef TYPE
> #define TYPE int
> #endif
> 
> /* A simple function that will be cloned.  */
> #pragma omp declare simd inbranch
> TYPE __attribute__((noinline))
> foo (TYPE a)
> {
>   return a + 1;
> }
> 
> /* Check that "inbranch" clones are called correctly.  */
> 
> void __attribute__((noinline))
> masked (TYPE * __restrict a, TYPE * __restrict b, int size)
> {
>   #pragma omp simd
>   for (int i = 0; i < size; i++)
> b[i] = foo(a[i]);
> }
> 
> Here, IMHO we should use the inbranch clone for vectorization (better
> than not vectorizing it, worse than when we'd have a notinbranch clone)
> and just use mask of all ones.
> But sure, it can be done incrementally, just mentioning it for completeness.
> 
> > This patch add supports for a sub-set of possible cases (those using
> > mask_mode == VOIDmode).  The other cases fail to vectorize, just as before,
> > so there should be no regressions.
> > 
> > The sub-set of support should cover all cases needed by amdgcn, at present.
> > 
> > gcc/ChangeLog:
> > 
> > * omp-simd-clone.cc (simd_clone_adjust_argument_types): Set vector_type
> > for mask arguments also.
> > * tree-if-conv.cc: Include cgraph.h.
> > (if_convertible_stmt_p): Do if conversions for calls to SIMD calls.
> > (predicate_statements): Pass the predicate to SIMD functions.
> > * tree-vect-stmts.cc (vectorizable_simd_clone_call): Permit calls
> > to clones with mask arguments, in some cases.
> > Generate the mask vector arguments.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * gcc.dg/vect/vect-simd-clone-16.c: New test.
> > * gcc.dg/vect/vect-simd-clone-16b.c: New test.
> > * gcc.dg/vect/vect-simd-clone-16c.c: New test.
> > * gcc.dg/vect/vect-simd-clone-16d.c: New test.
> > * gcc.dg/vect/vect-simd-clone-16e.c: New test.
> > * gcc.dg/vect/vect-simd-clone-16f.c: New test.
> > * gcc.dg/vect/vect-simd-clone-17.c: New test.
> > * gcc.dg/vect/vect-simd-clone-17b.c: New test.
> > * gcc.dg/vect/vect-simd-clone-17c.c: New test.
> > * gcc.dg/vect/vect-simd-clone-17d.c: New test.
> > * gcc.dg/vect/vect-simd-clone-17e.c: New test.
> > * gcc.dg/vect/vect-simd-clone-17f.c: New test.
> > * gcc.dg/vect/vect-simd-clone-18.c: New test.
> > * gcc.dg/vect/vect-simd-clone-18b.c: New test.
> > * gcc.dg/vect/vect-simd-clone-18c.c: New test.
> > * gcc.dg/vect/vect-simd-clone-18d.c: New test.
> > * gcc.dg/vect/vect-simd-clone-18e.c: New test.
> > * gcc.dg/vect/vect-simd-clone-18f.c: New test.
> 
> > --- a/gcc/tree-if-conv.cc
> > +++ b/gcc/tree-if-conv.cc
> > @@ -1074,13 +1076,19 @@ if_convertible_stmt_p (gimple *stmt, 
> > vec refs)
> > tree fndecl = gimple_call_fndecl (stmt);
> > if (fndecl)
> >   {
> > +   /* We can vectorize some builtins and functions with SIMD
> > +  clones.  */
> > int flags = gimple_call_flags (stmt);
> > +   struct cgraph_node *node = cgraph_node::get (fndecl);
> > if ((flags & ECF_CONST)
> > && !(flags & ECF_LOOPING_CONST_OR_PURE)
> > -   /* We can only vectorize some builtins at the moment,
> > -  so restrict if-conversion to those.  */
> > && fndecl_built_in_p (fndecl))
> >   return true;
> > +   else if (node && node->simd_clones != NULL)
> > + {
> > +   need_to_predicate = true;
> 
> I think it would be worth it to check that at least one of the
> node->simd_clones clones has ->inbranch set, because if all calls
> are declare simd notinbranch, then predicating the loop will be just a
> wasted effort.
> 
> > +   return true;
> > + }
> >   }
> > return false;
> >}
> > @@ -2614,6 +2622,31 @@ predicate_statements (loop_p loop)
> >   gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
> >   update_stmt (stmt);
> > }
> > +
> > + /* Add a predicate parameter to functions that have a SIMD clone.
> > +This will cause the vectorizer to match the "in branch" clone
> > +variants because they also have the extra parameter, and serves
> > +to build the mask vector in a natural way.  */
> > + gcall *call = dyn_cast  (gsi_stmt (gsi));
> > + if (call && !gimple_call_internal_p (call))
> > +   {
> > + tree orig_fndecl = gimple_call_fndecl (call);
> > + int orig_nargs = gimple_call_num_args (call);
> > + auto_vec args;
> > + for (int i=0; i < orig_nargs; i++)
> > +   args.safe_push (gimple_call_arg (call,

Re: [PATCH] Enhance final_value_replacement_loop to handle bitop with an invariant induction.[PR105735]

2022-09-14 Thread Richard Biener via Gcc-patches
On Tue, Sep 13, 2022 at 9:54 AM Kong, Lingling  wrote:
>
> Hi Richard,
>
> Thanks you so much for reviewing this patch.  I really appreciate it. For 
> these review comments, I have made some changes.
>
> > That's a single-stmt match, you shouldn't use match.pd matching for this.
> > Instead just do
> >
> >   if (is_gimple_assign (stmt)
> >   && ((code = gimple_assign_rhs_code (stmt)), true)
> >   && (code == BIT_AND_EXPR || code == BIT_IOR_EXPR || code ==
> > BIT_XOR_EXPR))
>
> Yes, I fixed it and dropped modification for match.pd.
>
> > and pick gimple_assign_rhs{1,2} (stmt) as the operands.  The :c in bit_op:c 
> > is
> > redundant btw. - while the name suggests "with invariant" you don't actually
> > check for that.  But again, given canonicalization rules the invariant will 
> > be rhs2
> > so above add
> >
> > && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
>
> For " with invariant", this needed op1 is invariant, and I used 
> `expr_invariant_in_loop_p (loop, match_op[0])` for check.
> And op2 just be PHI is ok. If op2 is INTEGER_CST, existing gcc can be 
> directly optimized and do not need modification.
>
> > you probably need dg-require-effective-target longlong, but is it necessary 
> > to
> > use long long for the testcases in the first place?
> > The IV seems to be unused, if it should match the variables bit size use 
> > sizeof
> > (type) * 8
>
> Yes, It is not necessary to use long long for the testcases. I changed type 
> to unsigned int.
>
> > > +  inv = PHI_ARG_DEF_FROM_EDGE (header_phi, loop_preheader_edge
> > > + (loop));  return fold_build2 (code1, type, inv, match_op[0]); }
> >
> > The } goes to the next line.
>
> Sorry, It might be something wrong with my use of gcc send-email format.
>
> > > +  tree bitinv_def;
> > > +  if ((bitinv_def
> >
> > please use else if here
>
> Sorry, If use the else if here, there is no corresponding above if. I'm not 
> sure if you mean change bitwise induction expression if to else if.

Yes, use else if for the bitwise induction.  Can you also make the new
case conditional on 'def'
(the compute_overall_effect_of_inner_loop) being chrec_dont_know?  If
that call produced
something useful it will not be of either of the two special forms.  Thus like

  if (def != chrec_dont_know)
/* Already OK.  */
;
 else if ((bitinv_def = ...)
..
 else if (tree_fits_uhwi_p (niter)
 ... bitwise induction case...)
...

?

Otherwise looks OK now.

Thanks,
Richard.

> Do you agree with these changes?  Thanks again for taking a look.
>
> Thanks,
> Lingling
>
> > -Original Message-
> > From: Richard Biener 
> > Sent: Tuesday, August 23, 2022 3:27 PM
> > To: Kong, Lingling 
> > Cc: Liu, Hongtao ; gcc-patches@gcc.gnu.org
> > Subject: Re: [PATCH] Enhance final_value_replacement_loop to handle bitop
> > with an invariant induction.[PR105735]
> >
> > On Thu, Aug 18, 2022 at 8:48 AM Kong, Lingling via Gcc-patches  > patc...@gcc.gnu.org> wrote:
> > >
> > > Hi,
> > >
> > > This patch is for pr105735/pr101991. It will enable below optimization:
> > > {
> > > -  long unsigned int bit;
> > > -
> > > -   [local count: 32534376]:
> > > -
> > > -   [local count: 1041207449]:
> > > -  # tmp_10 = PHI 
> > > -  # bit_12 = PHI 
> > > -  tmp_7 = bit2_6(D) & tmp_10;
> > > -  bit_8 = bit_12 + 1;
> > > -  if (bit_8 != 32)
> > > -goto ; [96.97%]
> > > -  else
> > > -goto ; [3.03%]
> > > -
> > > -   [local count: 1009658865]:
> > > -  goto ; [100.00%]
> > > -
> > > -   [local count: 32534376]:
> > > -  # tmp_11 = PHI 
> > > -  return tmp_11;
> > > +  tmp_11 = tmp_4(D) & bit2_6(D);
> > > +  return tmp_11;
> > >
> > > }
> > >
> > > Ok for master ?
> > >
> > > gcc/ChangeLog:
> > >
> > > PR middle-end/105735
> > > * match.pd (bitop_with_inv_p): New match.
> > > * tree-scalar-evolution.cc (gimple_bitop_with_inv_p): Declare.
> > > (analyze_and_compute_bitop_with_inv_effect): New function.
> > > (final_value_replacement_loop): Enhanced to handle bitop
> > > with inv induction.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * gcc.target/i386/pr105735-1.c: New test.
> > > * gcc.target/i386/pr105735-2.c: New test.
> > > ---
> > >  gcc/match.pd   |  4 +
> > >  gcc/testsuite/gcc.target/i386/pr105735-1.c | 88 ++
> > gcc/testsuite/gcc.target/i386/pr105735-2.c | 28 +++
> > >  gcc/tree-scalar-evolution.cc   | 59 +++
> > >  4 files changed, 179 insertions(+)
> > >  create mode 100644 gcc/testsuite/gcc.target/i386/pr105735-1.c
> > >  create mode 100644 gcc/testsuite/gcc.target/i386/pr105735-2.c
> > >
> > > diff --git a/gcc/match.pd b/gcc/match.pd index
> > > 562138a8034..cfe593ebb02 100644
> > > --- a/gcc/match.pd
> > > +++ b/gcc/match.pd
> > > @@ -8050,6 +8050,10 @@ and,
> > >   (bit_not
> > >(nop_convert1? (bit_xor@0 (convert2? (lshift integer_onep@1 @2))
> > > @3
> > >
> > > +(for bit_op (bit_

Re: [PATCH] PR tree-optimization/71343: Value number X<<2 as X*4.

2022-09-14 Thread Richard Biener via Gcc-patches
On Tue, Sep 13, 2022 at 7:55 PM Roger Sayle  wrote:
>
>
> This patch is the second part of a fix for PR tree-optimization/71343,
> that implements Richard Biener's suggestion of using tree-ssa's value
> numbering instead of match.pd.  The change is that when assigning a
> value number for the expression X< the value number for the multiplication X*(1< handles the fact that we (intentionally) don't canonicalize these as
> equivalent in GIMPLE, and the optimization/equivalence in PR 71343 now
> happens by (tree-ssa SCCVN) magic.
>
> This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> and make -k check, both with and without --target_board=unix{-32},
> with no new failures.  Ok for mainline?

Note that "insertion" is quite limited, in particular does not support
inserting a MULT_EXPR (see eliminate_dom_walker::eliminate_insert).

Your testcases have all expressions in one C statement, if you break
things down to enforce the various evaluation orders you seem to
test I think you'd see that CSEing

   tem1 = (a + b) << 2;
   tem2 = (a + b ) * 4;

does not actually work?  Amending eliminate_insert by for example
changing the BIT_AND_EXPR handling (with constant rhs2) to
covert all tcc_binary should make it work.

Can you double-check?

Otherwise this looks OK.

Thanks,
Richard.

>
> 2022-09-13  Roger Sayle  
>
> gcc/ChangeLog
> PR tree-optimization/71343
> * tree-ssa-sccvn.cc (visit_nary_op) : Make
> the value number of the expression X << C the same as the value
> number for the multiplication X * (1<
> gcc/testsuite/ChangeLog
> PR tree-optimization/71343
> * gcc.dg/pr71343-2.c: New test case.
>
>
> Thanks in advance,
> Roger
> --
>
> > -Original Message-
> > From: Richard Biener 
> > Sent: 08 August 2022 12:42
> > To: Roger Sayle 
> > Cc: GCC Patches 
> > Subject: Re: [PATCH] PR tree-optimization/71343: Optimize (X< > (X&Y)< >
> > On Mon, Aug 8, 2022 at 10:07 AM Roger Sayle
> >  wrote:
> > >
> > > This patch resolves PR tree-optimization/71343, a missed-optimization
> > > enhancement request where GCC fails to see that (a<<2)+(b<<2) == a*4+b*4.
> > > This requires two related (sets of) optimizations to be added to match.pd.
> > >
> > > The first is that (X< > > for many binary operators, including AND, IOR, XOR, and (if overflow
> > > isn't an issue) PLUS and MINUS.  Likewise, the right shifts (both
> > > logical and arithmetic) and bit-wise logical operators can be
> > > simplified in a similar fashion.  These all reduce the number of
> > > GIMPLE binary operations from 3 to 2, by combining/eliminating a shift
> > operation.
> > >
> > > The second optimization reflects that the middle-end doesn't impose a
> > > canonical form on multiplications by powers of two, vs. left shifts,
> > > instead leaving these operations as specified by the programmer unless
> > > there's a good reason to change them.  Hence, GIMPLE code may contain
> > > the expressions "X * 8" and "X << 3" even though these represent the
> > > same value/computation.  The tweak to match.pd is that comparison
> > > operations whose operands are equivalent non-canonical expressions can
> > > be taught their equivalence.  Hence "(X * 8) == (X << 3)" will always
> > > evaluate to true, and "(X<<2) > 4*X" will always evaluate to false.
> > >
> > > This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> > > and make -k check, both with and without --target_board=unix{-m32},
> > > with no new failures.  Ok for mainline?
> >
> > +/* Shifts by constants distribute over several binary operations,
> > +   hence (X << C) + (Y << C) can be simplified to (X + Y) << C.  */
> > +(for op (plus minus)
> > +  (simplify
> > +(op (lshift:s @0 INTEGER_CST@1) (lshift:s @2 INTEGER_CST@1))
> > +(if (INTEGRAL_TYPE_P (type)
> > +&& TYPE_OVERFLOW_WRAPS (type)
> > +&& !TYPE_SATURATING (type)
> > +&& tree_fits_shwi_p (@1)
> > +&& tree_to_shwi (@1) > 0
> > +&& tree_to_shwi (@1) < TYPE_PRECISION (type))
> >
> > I do wonder why we need to restrict this to shifts by constants?
> > Any out-of-bound shift was already there, no?
> >
> > +/* Some tree expressions are intentionally non-canonical.
> > +   We handle the comparison of the equivalent forms here.  */ (for cmp
> > +(eq le ge)
> > +  (simplify
> > +(cmp:c (lshift @0 INTEGER_CST@1) (mult @0 integer_pow2p@2))
> > +(if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
> > +&& tree_fits_shwi_p (@1)
> > +&& tree_to_shwi (@1) > 0
> > +&& tree_to_shwi (@1) < TYPE_PRECISION  (TREE_TYPE (@0))
> > +&& wi::to_wide (@1) == wi::exact_log2 (wi::to_wide (@2)))
> > +  { constant_boolean_node (true, type); })))
> > +
> > +(for cmp (ne lt gt)
> > +  (simplify
> > +(cmp:c (lshift @0 INTEGER_CST@1) (mult @0 integer_pow2p@2))
> > +(if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
> > +&& tree_fits_shwi_p (@1)
> > +&& tree_to_shwi (@1) > 0
> > +&& tree_to_shwi

Re: [PATCH] Optimize (X<

2022-09-14 Thread Richard Biener via Gcc-patches
On Tue, Sep 13, 2022 at 8:37 PM Roger Sayle  wrote:
>
>
> This patch tweaks the match.pd transformation previously added to fold
> (X< (wrapping) types, to also allow signed integer types provided that they
> don't trap and the overflow needn't be preserved for sanitization.
> i.e. this should now apply (by default) for "int x,y;", but is disabled
> with -ftrapv.
>
> This unsigned transformation has baked on mainline without problems, so it's
> time to turn up the heat...  LLVM, icc and MSVC perform this optimization.
>
>
> This patch has been tested on x86_64-pc-linux-gnu with make bootstrap and
> make -k check, both with and without --target_board=unix{-m32}, with no
> new failures.  Ok for mainline?

OK.

Thanks,
Richard.

>
>
> 2022-09-13  Roger Sayle  
>
> gcc/ChangeLog
> * match.pd (op (lshift @0 @1) (lshift @2 @1)): Optimize the
> expression (X< may have undefined overflow, provided that they don't trap.
>
> gcc/testsuite/ChangeLog
> * gcc.dg/pr71343-3.c: New test case.
>
>
> Thanks in advance,
> Roger
> --
>


Re: [PATCH 3/3] vect: inbranch SIMD clones

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Wed, Sep 14, 2022 at 08:09:08AM +, Richard Biener wrote:
> Are nested functions a thing for OpenMP?  But yes, punt on them
> for now.

For Fortran certainly because they are part of the language, for C
too because they are GNU extension.
But declare simd is mostly best effort, so we can at least for now punt.

> I agree that a conditional call should be explicit, but the above is
> only transitional between if-conversion and vectorization, right?
> Do we support indirect calls here?  As Jakub says one possibility
> is to do
> 
>  .IFN_COND/MASK_CALL (fn-addr, condition/mask, ...)
> 
> another would be
> 
>  fnptr = cond ? fn : &nop_call;
>  (*fnptr) (...);
> 
> thus replace the called function with conditional "nop".  How
> to exactly represent that NOP probably isn't too important
> when it's transitional until vectorization only, even NULL
> might work there.  Of course having the function address
> in a computation might confuse parts of the vectorizer.  OTOH
> it allows to keep the original call (and the chain and any
> other info we'd have to preserve otherwise).

On the ifn one can preserve those too and the advantage is that
it would be just one command rather than 2, but I'm not opposed
to the other way either.

Jakub



Re: [PATCH] Disallow pointer operands for |, ^ and partly & [PR106878]

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Wed, Sep 14, 2022 at 07:58:47AM +, Richard Biener wrote:
> > My change to match.pd (that added the two simplifications this patch
> > touches) results in more |/^/& assignments with pointer arguments,
> > but since r12-1608 we reject pointer operands for BIT_NOT_EXPR.
> > 
> > Disallowing them for BIT_NOT_EXPR and allowing for BIT_{IOR,XOR,AND}_EXPR
> > leads to a match.pd maintainance nightmare (see one of the patches in the
> > PR), so either we want to allow pointer operand on BIT_NOT_EXPR (but then
> > we run into issues e.g. with the ranger which expects it can emulate
> > BIT_NOT_EXPR ~X as - 1 - X which doesn't work for pointers which don't
> > support MINUS_EXPR), or the following patch disallows pointer arguments
> > for all of BIT_{IOR,XOR,AND}_EXPR with the exception of BIT_AND_EXPR
> > with INTEGER_CST last operand (for simpler pointer realignment).
> > I had to tweak one reassoc optimization and the two match.pd
> > simplifications.
> > 
> > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> OK.

Thanks.

> Did you check what breaks when we reverse the decision to allow
> BIT_AND_EXPR to align pointers alltogether?  I think we don't
> have any
> 
>  (T')(((T)ptr) & CST) -> ptr & CST

I haven't tried that, but can try that next.
Would prefer a few days in between so if my current patch affects other
arches it is reported.

> I think for BIT_*_EXPR we want ANY_INTEGRAL_TYPE_P (well, likely
> not complex int, but ...).  So if a patch to check that passes
> bootstrap that would be nice to have.

And can try that as the third step then.

Jakub



Re: [committed][nvptx] Add bar.warp.sync

2022-09-14 Thread Thomas Schwinge
Hi Tom!

On 2022-02-01T19:31:13+0100, Tom de Vries via Gcc-patches 
 wrote:
> On a GT 1030 (sm_61), with driver version 470.94 I run into:
> ...
> FAIL: libgomp.oacc-c/../libgomp.oacc-c-c++-common/parallel-dims.c \
>   -DACC_DEVICE_TYPE_nvidia=1 -DACC_MEM_SHARED=0 -foffload=nvptx-none \
>   -O2 execution test
> ...

This relates to PR99932 "OpenACC/nvptx offloading execution regressions
starting with CUDA 11.2-era Nvidia Driver 460.27.04".  You've fixed that
for GCC 12+, but testing nvptx offloading for GCC 11, GCC 10 branches on
a system with current Nvidia Driver, we're still running into the several
FAILs and annoying 'WARNING: program timed out' reported in PR99932.

Given that GCC 11, GCC 10 only build '.version 3.1' target libraries, the
patch below is actually a no-op ('!TARGET_PTX_6_0'; thus the attached
"nvptx: Define (dummy) 'TARGET_PTX_6_0'"), but having it makes it easier
to cherry-pick the actual relevant "[nvptx] Add uniform_warp_check insn".

OK to push to GCC 11, GCC 10 branches the attached
"nvptx: Define (dummy) 'TARGET_PTX_6_0'", "[nvptx] Add bar.warp.sync"?


Grüße
 Thomas


> which minimizes to the same test-case as listed in commit "[nvptx] Update
> default ptx isa to 6.3".
>
> The first divergent branch looks like:
> ...
>   {
> .reg .u32 %x;
> mov.u32 %x,%tid.x;
> setp.ne.u32 %r59,%x,0;
>   }
>   @ %r59 bra $L15;
>   mov.u64 %r48,%ar0;
>   mov.u32 %r22,2;
>   ld.u64 %r53,[%r48];
>   mov.u32 %r55,%r22;
>   mov.u32 %r54,1;
>  $L15:
> ...
> and when inspecting the generated SASS, the branch is not setup as a divergent
> branch, but instead as a regular branch.
>
> This causes us to execute a shfl.sync insn in divergent mode, which is likely
> to cause trouble given a remark in the ptx isa version 6.3, which mentions
> that for .target sm_6x or below, all threads must excute the same
> shfl.sync instruction in convergence.
>
> Fix this by placing a "bar.warp.sync 0x" at the desired convergence
> point (in the example above, after $L15).
>
> Tested on x86_64 with nvptx accelerator.
>
> Committed to trunk.
>
> Thanks,
> - Tom
>
> [nvptx] Add bar.warp.sync
>
> gcc/ChangeLog:
>
> 2022-01-31  Tom de Vries  
>
>   * config/nvptx/nvptx.cc (nvptx_single): Use nvptx_warpsync.
>   * config/nvptx/nvptx.md (define_c_enum "unspecv"): Add
>   UNSPECV_WARPSYNC.
>   (define_insn "nvptx_warpsync"): New define_insn.
>
> ---
>  gcc/config/nvptx/nvptx.cc | 7 +++
>  gcc/config/nvptx/nvptx.md | 7 +++
>  2 files changed, 14 insertions(+)
>
> diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
> index 262e8f9cc1b..1b91990ca1f 100644
> --- a/gcc/config/nvptx/nvptx.cc
> +++ b/gcc/config/nvptx/nvptx.cc
> @@ -4598,6 +4598,7 @@ nvptx_single (unsigned mask, basic_block from, 
> basic_block to)
>rtx_insn *neuter_start = NULL;
>rtx_insn *worker_label = NULL, *vector_label = NULL;
>rtx_insn *worker_jump = NULL, *vector_jump = NULL;
> +  rtx_insn *warp_sync = NULL;
>for (mode = GOMP_DIM_WORKER; mode <= GOMP_DIM_VECTOR; mode++)
>  if (GOMP_DIM_MASK (mode) & skip_mask)
>{
> @@ -4630,11 +4631,15 @@ nvptx_single (unsigned mask, basic_block from, 
> basic_block to)
>   if (tail_branch)
> {
>   label_insn = emit_label_before (label, before);
> + if (TARGET_PTX_6_0 && mode == GOMP_DIM_VECTOR)
> +   warp_sync = emit_insn_after (gen_nvptx_warpsync (), label_insn);
>   before = label_insn;
> }
>   else
> {
>   label_insn = emit_label_after (label, tail);
> + if (TARGET_PTX_6_0 && mode == GOMP_DIM_VECTOR)
> +   warp_sync = emit_insn_after (gen_nvptx_warpsync (), label_insn);
>   if ((mode == GOMP_DIM_VECTOR || mode == GOMP_DIM_WORKER)
>   && CALL_P (tail) && find_reg_note (tail, REG_NORETURN, NULL))
> emit_insn_after (gen_exit (), label_insn);
> @@ -4702,6 +4707,8 @@ nvptx_single (unsigned mask, basic_block from, 
> basic_block to)
>setp.ne.u32 %rcond,%rcondu32,0;
> */
> rtx_insn *label = PREV_INSN (tail);
> +   if (label == warp_sync)
> + label = PREV_INSN (label);
> gcc_assert (label && LABEL_P (label));
> rtx tmp = gen_reg_rtx (BImode);
> emit_insn_before (gen_movbi (tmp, const0_rtx),
> diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md
> index b39116520ba..b4c7cd6e56d 100644
> --- a/gcc/config/nvptx/nvptx.md
> +++ b/gcc/config/nvptx/nvptx.md
> @@ -56,6 +56,7 @@ (define_c_enum "unspecv" [
> UNSPECV_CAS
> UNSPECV_XCHG
> UNSPECV_BARSYNC
> +   UNSPECV_WARPSYNC
> UNSPECV_MEMBAR
> UNSPECV_MEMBAR_CTA
> UNSPECV_MEMBAR_GL
> @@ -1978,6 +1979,12 @@ (define_insn "nvptx_barsync"
>}
>[(set_attr "predicable" "false")])
>
> +(define_insn "nvptx_warpsync"
> +  [(unspec_volatile [(const_int 0)] UNSPECV_WARPSYNC)]
> +  "TARGET_PTX_6_0"
> +  "\\tbar.warp.sync\\t0x;"
> +  [(set_attr "predicable" "false")])
> +
>  (define_e

Re: [committed][nvptx] Add uniform_warp_check insn

2022-09-14 Thread Thomas Schwinge
Hi Tom!

On 2022-02-01T19:31:27+0100, Tom de Vries via Gcc-patches 
 wrote:
> Hi,
>
> On a GT 1030, with driver version 470.94 and -mptx=3.1 I run into:
> ...
> FAIL: libgomp.oacc-c/../libgomp.oacc-c-c++-common/parallel-dims.c \
>   -DACC_DEVICE_TYPE_nvidia=1 -DACC_MEM_SHARED=0 -foffload=nvptx-none \
>   -O2 execution test
> ...

This relates to PR99932 "OpenACC/nvptx offloading execution regressions
starting with CUDA 11.2-era Nvidia Driver 460.27.04".  You've fixed that
for GCC 12+, but testing nvptx offloading for GCC 11, GCC 10 branches on
a system with current Nvidia Driver, we're still running into the several
FAILs and annoying 'WARNING: program timed out' reported in PR99932.

GCC 11, GCC 10 only build '.version 3.1' target libraries, and with
"[nvptx] Add bar.warp.sync" in place (which this patch here thus only
textually depends on), we've got good test results again.

OK to push to GCC 11, GCC 10 branches the attached
"[nvptx] Add uniform_warp_check insn"?


Grüße
 Thomas


> which minimizes to the same test-case as listed in commit "[nvptx]
> Update default ptx isa to 6.3".
>
> The problem is again that the first diverging branch is not handled as such in
> SASS, which causes problems with a subsequent shfl insn, but given that we
> have -mptx=3.1 we can't use the bar.warp.sync insn.
>
> Given that the default is now -mptx=6.3, and consequently -mptx=3.1 is of a
> lesser importance, implement the next best thing: abort when detecting
> non-convergence using this insn:
> ...
>   { .reg.b32 act;
> vote.ballot.b32 act,1;
> .reg.pred uni;
> setp.eq.b32 uni,act,0x;
> @ !uni trap;
> @ !uni exit;
>   }
> ...
>
> Interestingly, the effect of this is that rather than aborting, the test-case
> now passes.
>
> Tested on x86_64 with nvptx accelerator.
>
> Committed to trunk.
>
> Thanks,
> - Tom
>
> [nvptx] Add uniform_warp_check insn
>
> gcc/ChangeLog:
>
> 2022-01-31  Tom de Vries  
>
>   * config/nvptx/nvptx.cc (nvptx_single): Use nvptx_uniform_warp_check.
>   * config/nvptx/nvptx.md (define_c_enum "unspecv"): Add
>   UNSPECV_UNIFORM_WARP_CHECK.
>   (define_insn "nvptx_uniform_warp_check"): New define_insn.
>
> ---
>  gcc/config/nvptx/nvptx.cc | 22 ++
>  gcc/config/nvptx/nvptx.md | 18 ++
>  2 files changed, 36 insertions(+), 4 deletions(-)
>
> diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
> index 1b91990ca1f..b3bb97c3c14 100644
> --- a/gcc/config/nvptx/nvptx.cc
> +++ b/gcc/config/nvptx/nvptx.cc
> @@ -4631,15 +4631,29 @@ nvptx_single (unsigned mask, basic_block from, 
> basic_block to)
>   if (tail_branch)
> {
>   label_insn = emit_label_before (label, before);
> - if (TARGET_PTX_6_0 && mode == GOMP_DIM_VECTOR)
> -   warp_sync = emit_insn_after (gen_nvptx_warpsync (), label_insn);
> + if (mode == GOMP_DIM_VECTOR)
> +   {
> + if (TARGET_PTX_6_0)
> +   warp_sync = emit_insn_after (gen_nvptx_warpsync (),
> +label_insn);
> + else
> +   warp_sync = emit_insn_after (gen_nvptx_uniform_warp_check (),
> +label_insn);
> +   }
>   before = label_insn;
> }
>   else
> {
>   label_insn = emit_label_after (label, tail);
> - if (TARGET_PTX_6_0 && mode == GOMP_DIM_VECTOR)
> -   warp_sync = emit_insn_after (gen_nvptx_warpsync (), label_insn);
> + if (mode == GOMP_DIM_VECTOR)
> +   {
> + if (TARGET_PTX_6_0)
> +   warp_sync = emit_insn_after (gen_nvptx_warpsync (),
> +label_insn);
> + else
> +   warp_sync = emit_insn_after (gen_nvptx_uniform_warp_check (),
> +label_insn);
> +   }
>   if ((mode == GOMP_DIM_VECTOR || mode == GOMP_DIM_WORKER)
>   && CALL_P (tail) && find_reg_note (tail, REG_NORETURN, NULL))
> emit_insn_after (gen_exit (), label_insn);
> diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md
> index b4c7cd6e56d..92768dd9e95 100644
> --- a/gcc/config/nvptx/nvptx.md
> +++ b/gcc/config/nvptx/nvptx.md
> @@ -57,6 +57,7 @@ (define_c_enum "unspecv" [
> UNSPECV_XCHG
> UNSPECV_BARSYNC
> UNSPECV_WARPSYNC
> +   UNSPECV_UNIFORM_WARP_CHECK
> UNSPECV_MEMBAR
> UNSPECV_MEMBAR_CTA
> UNSPECV_MEMBAR_GL
> @@ -1985,6 +1986,23 @@ (define_insn "nvptx_warpsync"
>"\\tbar.warp.sync\\t0x;"
>[(set_attr "predicable" "false")])
>
> +(define_insn "nvptx_uniform_warp_check"
> +  [(unspec_volatile [(const_int 0)] UNSPECV_UNIFORM_WARP_CHECK)]
> +  ""
> +  {
> +output_asm_insn ("{", NULL);
> +output_asm_insn ("\\t"".reg.b32""\\t" "act;", NULL);
> +output_asm_insn ("\\t""vote.ballot.b32" "\\t" "act,1;", NULL);
> +output_asm_insn ("\\t" 

Re: [committed][nvptx] Add bar.warp.sync

2022-09-14 Thread Tom de Vries via Gcc-patches

On 9/14/22 11:41, Thomas Schwinge wrote:

Hi Tom!

On 2022-02-01T19:31:13+0100, Tom de Vries via Gcc-patches 
 wrote:

On a GT 1030 (sm_61), with driver version 470.94 I run into:
...
FAIL: libgomp.oacc-c/../libgomp.oacc-c-c++-common/parallel-dims.c \
   -DACC_DEVICE_TYPE_nvidia=1 -DACC_MEM_SHARED=0 -foffload=nvptx-none \
   -O2 execution test
...


This relates to PR99932 "OpenACC/nvptx offloading execution regressions
starting with CUDA 11.2-era Nvidia Driver 460.27.04".  You've fixed that
for GCC 12+, but testing nvptx offloading for GCC 11, GCC 10 branches on
a system with current Nvidia Driver, we're still running into the several
FAILs and annoying 'WARNING: program timed out' reported in PR99932.

Given that GCC 11, GCC 10 only build '.version 3.1' target libraries, the
patch below is actually a no-op ('!TARGET_PTX_6_0'; thus the attached
"nvptx: Define (dummy) 'TARGET_PTX_6_0'"), but having it makes it easier
to cherry-pick the actual relevant "[nvptx] Add uniform_warp_check insn".

OK to push to GCC 11, GCC 10 branches the attached
"nvptx: Define (dummy) 'TARGET_PTX_6_0'", "[nvptx] Add bar.warp.sync"?



LGTM, and thanks for taking care of this.

Thanks,
- Tom



Re: [committed][nvptx] Add uniform_warp_check insn

2022-09-14 Thread Tom de Vries via Gcc-patches

On 9/14/22 11:41, Thomas Schwinge wrote:

Hi Tom!

On 2022-02-01T19:31:27+0100, Tom de Vries via Gcc-patches 
 wrote:

Hi,

On a GT 1030, with driver version 470.94 and -mptx=3.1 I run into:
...
FAIL: libgomp.oacc-c/../libgomp.oacc-c-c++-common/parallel-dims.c \
   -DACC_DEVICE_TYPE_nvidia=1 -DACC_MEM_SHARED=0 -foffload=nvptx-none \
   -O2 execution test
...


This relates to PR99932 "OpenACC/nvptx offloading execution regressions
starting with CUDA 11.2-era Nvidia Driver 460.27.04".  You've fixed that
for GCC 12+, but testing nvptx offloading for GCC 11, GCC 10 branches on
a system with current Nvidia Driver, we're still running into the several
FAILs and annoying 'WARNING: program timed out' reported in PR99932.

GCC 11, GCC 10 only build '.version 3.1' target libraries, and with
"[nvptx] Add bar.warp.sync" in place (which this patch here thus only
textually depends on), we've got good test results again.

OK to push to GCC 11, GCC 10 branches the attached
"[nvptx] Add uniform_warp_check insn"?




LGTM.

Thanks,
- Tom


[PATCH] tree-optimization/106934 - avoid BIT_FIELD_REF of bitfields

2022-09-14 Thread Richard Biener via Gcc-patches
The following avoids creating BIT_FIELD_REF of bitfields in
update-address-taken.  The patch doesn't implement punning to
a full precision integer type but leaves a comment according to
that.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

PR tree-optimization/106934
* tree-ssa.cc (non_rewritable_mem_ref_base): Avoid BIT_FIELD_REFs
of bitfields.
(maybe_rewrite_mem_ref_base): Likewise.

* gfortran.dg/pr106934.f90: New testcase.
---
 gcc/testsuite/gfortran.dg/pr106934.f90 | 7 +++
 gcc/tree-ssa.cc| 6 ++
 2 files changed, 13 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/pr106934.f90

diff --git a/gcc/testsuite/gfortran.dg/pr106934.f90 
b/gcc/testsuite/gfortran.dg/pr106934.f90
new file mode 100644
index 000..ac58a3e82e3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr106934.f90
@@ -0,0 +1,7 @@
+! { dg-do compile }
+! { dg-options "-O" }
+subroutine s
+   logical(1) :: a = .true.
+   logical(2) :: b
+   a = transfer(b, a)
+end
diff --git a/gcc/tree-ssa.cc b/gcc/tree-ssa.cc
index 6507348e793..1a93ffdbd64 100644
--- a/gcc/tree-ssa.cc
+++ b/gcc/tree-ssa.cc
@@ -1459,6 +1459,8 @@ maybe_rewrite_mem_ref_base (tree *tp, bitmap 
suitable_for_renaming)
   && (! INTEGRAL_TYPE_P (TREE_TYPE (*tp)) 
   || (wi::to_offset (TYPE_SIZE (TREE_TYPE (*tp)))
   == TYPE_PRECISION (TREE_TYPE (*tp
+  && (! INTEGRAL_TYPE_P (TREE_TYPE (sym))
+  || type_has_mode_precision_p (TREE_TYPE (sym)))
   && wi::umod_trunc (wi::to_offset (TYPE_SIZE (TREE_TYPE (*tp))),
  BITS_PER_UNIT) == 0)
{
@@ -1531,6 +1533,10 @@ non_rewritable_mem_ref_base (tree ref)
  && (! INTEGRAL_TYPE_P (TREE_TYPE (base))
  || (wi::to_offset (TYPE_SIZE (TREE_TYPE (base)))
  == TYPE_PRECISION (TREE_TYPE (base
+ /* ???  Likewise for extracts from bitfields, we'd have
+to pun the base object to a size precision mode first.  */
+ && (! INTEGRAL_TYPE_P (TREE_TYPE (decl))
+ || type_has_mode_precision_p (TREE_TYPE (decl)))
  && wi::umod_trunc (wi::to_offset (TYPE_SIZE (TREE_TYPE (base))),
 BITS_PER_UNIT) == 0)
return NULL_TREE;
-- 
2.35.3


Re: [PATCH v3 01/11] OpenMP 5.0: Clause ordering for OpenMP 5.0 (topological sorting by base pointer)

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 13, 2022 at 02:01:42PM -0700, Julian Brown wrote:
> --- a/gcc/omp-low.cc
> +++ b/gcc/omp-low.cc
> @@ -1599,8 +1599,11 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
>   {
> /* If this is an offloaded region, an attach operation should
>only exist when the pointer variable is mapped in a prior
> -  clause.  */
> -   if (is_gimple_omp_offloaded (ctx->stmt))
> +  clause.
> +  If we had an error, we may not have attempted to sort clauses
> +  properly, so avoid the test.  */
> +   if (is_gimple_omp_offloaded (ctx->stmt)
> +   && !seen_error ())

I'll repeat that it would be better if we just leave out the whole
GOMP_TARGET if there were errors regarding it and the clauses aren't sorted
properly.
But I'm ok if it is handled incrementally and this spot reverted.

Otherwise LGTM.

Jakub



Re: [PATCH v3 02/11] Remove omp_target_reorder_clauses

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 13, 2022 at 02:01:43PM -0700, Julian Brown wrote:
> This patch has been split out from the previous one to avoid a
> confusingly-interleaved diff.  The two patches will be committed squashed
> together.
> 
> 2022-09-13  Julian Brown  
> 
> gcc/
>   * gimplify.c (omp_target_reorder_clauses): Delete.

Ok.

Jakub



Re: [PATCH v3 03/11] OpenMP/OpenACC struct sibling list gimplification extension and rework

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 13, 2022 at 02:01:44PM -0700, Julian Brown wrote:
>  static tree
> -insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
> - tree prev_node, tree *scp)
> +build_struct_comp_nodes (enum tree_code code, tree grp_start, tree grp_end,
> +  tree *extra_node)

I'd rename even this function, say to build_omp_struct_comp_nodes.

So that it is clear it is OpenMP/OpenACC specific.

Otherwise LGTM.

Jakub



Re: [PATCH v3 04/11] OpenMP/OpenACC: mapping group list-handling improvements

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 13, 2022 at 02:01:45PM -0700, Julian Brown wrote:
> @@ -9443,6 +9499,41 @@ omp_containing_struct (tree expr)
>return expr;
>  }
>  

Missing function comment here.

> +static bool
> +omp_mapped_by_containing_struct (hash_map +   omp_mapping_group *> *grpmap,
> +  tree decl,
> +  omp_mapping_group **mapped_by_group)

Otherwise LGTM.

Jakub



Re: [PATCH] Add libgo dependency on libbacktrace.

2022-09-14 Thread Thomas Schwinge
Hi!

On 2022-08-18T07:59:50+0100, Sergei Trofimovich via Gcc-patches 
 wrote:
> From: Sergei Trofimovich 
>
> Noticed missing dependency when regenerated Makefile.in for unrelated
> change with 'autoget Makefile.def'.

ACK.  (..., and by now pushed in
commit r13-2108-g5dbc94bf13c5ef2f2b777d76d7880fe2153aa37b
"Add libgo dependency on libbacktrace".)

> The change was lost in basepoints/gcc-12-6861-gaeac414923a
> ("Revert "Fix PR 67102: Add libstdc++ dependancy to libffi" [PR67102]").

That'd be my doing, but -- nope.  ;-) (... but no worries, no offense
meant.)

This 'Makefile.in' was simply missing from recent
commit r13-1902-g351e3cad2c5d4dfe43d68ba333bde1d70fa0b807
"PR bootstrap/106472: Add libgo depends on libbacktrace to Makefile.def".


Grüße
 Thomas


> /
>   Makefile.in: Regenerate.
> ---
>  Makefile.in | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Makefile.in b/Makefile.in
> index 13ee95a2602..60077a6aa36 100644
> --- a/Makefile.in
> +++ b/Makefile.in
> @@ -66523,6 +66523,7 @@ all-target-liboffloadmic: maybe-all-target-libgomp
>  configure-target-newlib: maybe-all-binutils
>  configure-target-newlib: maybe-all-ld
>  configure-target-libgfortran: maybe-all-target-libbacktrace
> +configure-target-libgo: maybe-all-target-libbacktrace
>  @endunless gcc-bootstrap
>
>  # Dependencies for target modules on other target modules are
> --
> 2.37.1
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955


[COMMITTED] Fix unused variable warning (was: [PATCH 1/3] STABS: remove -gstabs and -gxcoff functionality)

2022-09-14 Thread Jan-Benedict Glaw
On Thu, 2022-09-01 12:05:23 +0200, Martin Liška  wrote:
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> 
> I've also built all cross compilers.
> 
> Ready to be installed?
> Thanks,
> Martin
> 
> gcc/ChangeLog:
> 
>   * Makefile.in: Remove -gstabs option support, DBX-related
> macros and DBX debugging info support.
[...]
>   * config/mips/mips.cc (mips_output_filename): Likewise.
>   (mips_option_override): Likewise.
[...]
> diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
> index e81a245dcf4..47724950c3e 100644
> --- a/gcc/config/mips/mips.cc
> +++ b/gcc/config/mips/mips.cc
[...]
> @@ -20505,24 +20500,13 @@ mips_option_override (void)
>  
>for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
>  {
> -  mips_dbx_regno[i] = IGNORED_DWARF_REGNUM;
>if (GP_REG_P (i) || FP_REG_P (i) || ALL_COP_REG_P (i))
>   mips_dwarf_regno[i] = i;
>else
>   mips_dwarf_regno[i] = INVALID_REGNUM;
>  }
>  
> -  start = GP_DBX_FIRST - GP_REG_FIRST;
> -  for (i = GP_REG_FIRST; i <= GP_REG_LAST; i++)
> -mips_dbx_regno[i] = i + start;
> -
> -  start = FP_DBX_FIRST - FP_REG_FIRST;
> -  for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++)
> -mips_dbx_regno[i] = i + start;
> -
>/* Accumulator debug registers use big-endian ordering.  */
> -  mips_dbx_regno[HI_REGNUM] = MD_DBX_FIRST + 0;
> -  mips_dbx_regno[LO_REGNUM] = MD_DBX_FIRST + 1;
>mips_dwarf_regno[HI_REGNUM] = MD_REG_FIRST + 0;
>mips_dwarf_regno[LO_REGNUM] = MD_REG_FIRST + 1;
>for (i = DSP_ACC_REG_FIRST; i <= DSP_ACC_REG_LAST; i += 2)

This leaves the `start` variable unused, resulting in a new warning.
Fixed (committed as obvious) by this:

/usr/lib/gcc-snapshot/bin/g++  -fno-PIE -c   -g -O2   -DIN_GCC  
-DCROSS_DIRECTORY_STRUCTURE   -fno-exceptions -fno-rtti 
-fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings 
-Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic 
-Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror -fno-common 
 -DHAVE_CONFIG_H -I. -I. -I../../gcc/gcc -I../../gcc/gcc/. 
-I../../gcc/gcc/../include -I../../gcc/gcc/../libcpp/include 
-I../../gcc/gcc/../libcody  -I../../gcc/gcc/../libdecnumber 
-I../../gcc/gcc/../libdecnumber/dpd -I../libdecnumber 
-I../../gcc/gcc/../libbacktrace   -o mips.o -MT mips.o -MMD -MP -MF 
./.deps/mips.TPo ../../gcc/gcc/config/mips/mips.cc
../../gcc/gcc/config/mips/mips.cc: In function 'void mips_option_override()':
../../gcc/gcc/config/mips/mips.cc:20021:10: error: unused variable 'start' 
[-Werror=unused-variable]
20021 |   int i, start, regno, mode;
  |  ^

2022-09-14  Jan-Benedict Glaw  

gcc/
* config/mips/mips.cc (mips_option_override): Drop unused variable.

diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 47724950c3e..387376b3df8 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -20018,7 +20018,7 @@ mips_set_tune (const struct mips_cpu_info *info)
 static void
 mips_option_override (void)
 {
-  int i, start, regno, mode;
+  int i, regno, mode;
 
   if (OPTION_SET_P (mips_isa_option))
 mips_isa_option_info = &mips_cpu_info_table[mips_isa_option];


Committed as obvious.

MfG, JBG

-- 


signature.asc
Description: PGP signature


Re: [PATCH v3 05/11] OpenMP: push attaches to end of clause list in "target" regions

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 13, 2022 at 02:03:15PM -0700, Julian Brown wrote:
> This patch moves GOMP_MAP_ATTACH{_ZERO_LENGTH_ARRAY_SECTION} nodes to
> the end of the clause list, for offload regions.  This ensures that when
> we do the attach operation, both the "attachment point" and the target
> region have both already been mapped on the target.  This avoids a
> pathological case that can otherwise happen with struct sibling-list
> handling.
> 
> 2022-09-13  Julian Brown  
> 
> gcc/
>   * gimplify.cc (omp_segregate_mapping_groups): Update comment.
>   (omp_push_attaches_to_end): New function.
>   (gimplify_scan_omp_clauses): Use omp_push_attaches_to_end for offloaded
>   regions.

Shouldn't this be done at the end of gimplify_adjust_omp_clauses?
I mean, can't further attach clauses appear because of declare mapper
for implicitly mapped variables?
Other than that, it is yet another walk of the whole clause list, so would
be nicer if it could be done in an existing walk over the clauses or
at least have a flag whether there are any such clauses present and do it
only in that case.
If it could be done in the main gimplify_adjust_omp_clauses loop, nice,
if it can appear also during
  splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
that isn't the case.

Jakub



Re: [PATCH v2] libstdc++: Add pretty printer for std::stringstreams

2022-09-14 Thread Jonathan Wakely via Gcc-patches
On Tue, 6 Sept 2022 at 22:25, Philipp Fent  wrote:
>
> To display (o-,i-)stringstreams in the common case, we just print the
> underlying stringbuf, without the many ios_base members. In the
> unconventional case that the underlying streambuf was redirected, we
> report the redirected target.
>
> Signed-off-by: Philipp Fent 
> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py  | 56 +++
>  .../libstdc++-prettyprinters/debug.cc | 15 +
>  .../libstdc++-prettyprinters/simple.cc| 15 +
>  .../libstdc++-prettyprinters/simple11.cc  | 15 +
>  4 files changed, 101 insertions(+)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index d70c8d5d616..bd4289c1c62 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -969,6 +969,57 @@ class StdStringPrinter:
>  def display_hint (self):
>  return 'string'
>
> +def access_streambuf_ptrs(streambuf):
> +"Access the streambuf put area pointers"
> +pbase = streambuf['_M_out_beg']
> +pptr = streambuf['_M_out_cur']
> +egptr = streambuf['_M_in_end']
> +return pbase, pptr, egptr
> +
> +class StdStringBufPrinter:
> +"Print a std::basic_stringbuf"
> +
> +def __init__(self, _, val):
> +self.val = val
> +
> +def to_string(self):
> +(pbase, pptr, egptr) = access_streambuf_ptrs(self.val)
> +# Logic from basic_stringbuf::_M_high_mark()
> +if pptr:
> +if not egptr or pptr > egptr:
> +return pbase.string(length = pptr - pbase)
> +else:
> +return pbase.string(length = egptr - pbase)
> +return self.val['_M_string']
> +
> +def display_hint(self):
> +return 'string'
> +
> +class StdStringStreamPrinter:
> +"Print a std::basic_stringstream"
> +
> +def __init__(self, typename, val):
> +self.val = val
> +self.typename = typename
> +
> +# Check if the stream was redirected:
> +# This is essentially: val['_M_streambuf'] == 
> val['_M_stringbuf'].address
> +# However, GDB can't resolve the virtual inheritance, so we do that 
> manually

Oh yuck, sorry you had to figure that out.

The patch looks good, thanks. I'll get it pushed to trunk.


> +basetype = [f.type for f in val.type.fields() if f.is_base_class][0]
> +gdb.set_convenience_variable('__stream', val.cast(basetype).address)
> +self.streambuf = gdb.parse_and_eval('$__stream->rdbuf()')
> +self.was_redirected = self.streambuf != val['_M_stringbuf'].address
> +
> +def to_string(self):
> +if self.was_redirected:
> +return "%s redirected to %s" % (self.typename, 
> self.streambuf.dereference())
> +return self.val['_M_stringbuf']
> +
> +def display_hint(self):
> +if self.was_redirected:
> +return None
> +return 'string'
> +
>  class Tr1HashtableIterator(Iterator):
>  def __init__ (self, hashtable):
>  self.buckets = hashtable['_M_buckets']
> @@ -2232,6 +2283,11 @@ def build_libstdcxx_dictionary ():
>  libstdcxx_printer.add_version('std::', 'initializer_list',
>StdInitializerListPrinter)
>  libstdcxx_printer.add_version('std::', 'atomic', StdAtomicPrinter)
> +libstdcxx_printer.add_version('std::', 'basic_stringbuf', 
> StdStringBufPrinter)
> +libstdcxx_printer.add_version('std::__cxx11::', 'basic_stringbuf', 
> StdStringBufPrinter)
> +for sstream in ('istringstream', 'ostringstream', 'stringstream'):
> +libstdcxx_printer.add_version('std::', 'basic_' + sstream, 
> StdStringStreamPrinter)
> +libstdcxx_printer.add_version('std::__cxx11::', 'basic_' + sstream, 
> StdStringStreamPrinter)
>
>  # std::regex components
>  libstdcxx_printer.add_version('std::__detail::', '_State',
> diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc 
> b/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
> index 98bbc182551..3c6195591c5 100644
> --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
> +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
> @@ -29,6 +29,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>
> @@ -110,6 +111,20 @@ main()
>__gnu_cxx::slist::iterator slliter = sll.begin();
>  // { dg-final { note-test slliter {47} } }
>
> +  std::stringstream sstream;
> +  sstream << "abc";
> +// { dg-final { note-test sstream "\"abc\"" } }
> +  std::stringstream ssin("input", std::ios::in);
> +// { dg-final { note-test ssin "\"input\"" } }
> +  std::istringstream ssin2("input");
> +// { dg-final { note-test ssin2 "\"input\"" } }
> +  std::ostringstream ssout;
> +  ssout << "out";
> +// { dg-final { note-test ssout "\"out\"" } }
> +  std::stringstream redirected("xxx");
> +  
> static_cast&>(redirected).rdbuf(sstream.rdbuf());
> +// { 

[COMMITTED] [PR106936] Remove assert from get_value_range.

2022-09-14 Thread Aldy Hernandez via Gcc-patches
This assert was put here to make sure that the legacy
get_value_range() wasn't being called on stuff that legacy couldn't
handle (floats, etc), because the result would ultimately be copied
into a value_range_equiv.

In this case, simplify_casted_cond() is calling it on an offset_type
which is neither an integer nor a pointer.  However, range_of_expr
happily punted on it, and then the fallthru code set the range to
VARYING.  As value_range_equiv can store VARYING types of anything
(including types it can't handle), this is fine.

The easiest thing to do is remove the assert.  If someone from the non
legacy world tries to get a non integer/pointer range here, it's going
to blow up anyhow because the temporary in get_value_range is
int_range_max.

PR tree-optimization/106936

gcc/ChangeLog:

* value-query.cc (range_query::get_value_range): Remove assert.

gcc/testsuite/ChangeLog:

* g++.dg/tree-ssa/pr106936.C: New test.
---
 gcc/testsuite/g++.dg/tree-ssa/pr106936.C | 14 ++
 gcc/value-query.cc   |  1 -
 2 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr106936.C

diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr106936.C 
b/gcc/testsuite/g++.dg/tree-ssa/pr106936.C
new file mode 100644
index 000..c3096e0dd20
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr106936.C
@@ -0,0 +1,14 @@
+// { dg-do compile } */
+// { dg-options "-O2 -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre" }
+
+namespace testPointerToMemberMiscCasts2 {
+struct B {
+  int f;
+};
+struct L : public B { };
+struct R : public B { };
+struct D : public L, R { };
+  int B::* pb = &B::f;
+  int R::* pr = pb;
+  int D::* pdr = pr;
+}
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 201f679a36e..ad80db780c2 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -167,7 +167,6 @@ range_query::free_value_range_equiv (value_range_equiv *v)
 const class value_range_equiv *
 range_query::get_value_range (const_tree expr, gimple *stmt)
 {
-  gcc_checking_assert (value_range_equiv::supports_p (TREE_TYPE (expr)));
   int_range_max r;
   if (range_of_expr (r, const_cast (expr), stmt))
 return new (equiv_alloc->allocate ()) value_range_equiv (r);
-- 
2.37.1



[PATCH] tree-optimization/106938 - cleanup abnormal edges after inlining

2022-09-14 Thread Richard Biener via Gcc-patches
After inlining and IPA transforms we run fixup_cfg to fixup CFG
effects in other functions.  But that fails to clean abnormal
edges from non-pure/const calls which might no longer be necessary
when ->calls_setjmp is false.  The following ensures this happens
and refactors things so we call EH/abnormal cleanup only on the
last stmt in a block.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

PR tree-optimization/106938
* tree-cfg.cc (execute_fixup_cfg): Purge dead abnormal
edges for all last stmts in a block.  Do EH cleanup
only on the last stmt in a block.

* gcc.dg/pr106938.c: New testcase.
---
 gcc/testsuite/gcc.dg/pr106938.c | 36 +
 gcc/tree-cfg.cc | 13 ++--
 2 files changed, 43 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr106938.c

diff --git a/gcc/testsuite/gcc.dg/pr106938.c b/gcc/testsuite/gcc.dg/pr106938.c
new file mode 100644
index 000..7365a8c29fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr106938.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-ipa-pure-const -fno-tree-ccp -Wuninitialized" } */
+
+int n;
+
+void
+undefined (void);
+
+__attribute__ ((returns_twice)) int
+zero (void)
+{
+  return 0;
+}
+
+void
+bar (int)
+{
+  int i;
+
+  for (i = 0; i < -1; ++i)
+n = 0;
+}
+
+__attribute__ ((simd)) void
+foo (void)
+{
+  int uninitialized;
+
+  undefined ();
+
+  while (uninitialized < 1) /* { dg-warning "uninitialized" } */
+{
+  bar (zero ());
+  ++uninitialized;
+}
+}
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index 5cb6db337f9..48c5c4de51f 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -9828,16 +9828,12 @@ execute_fixup_cfg (void)
  int flags = gimple_call_flags (stmt);
  if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
{
- if (gimple_purge_dead_abnormal_call_edges (bb))
-   todo |= TODO_cleanup_cfg;
-
  if (gimple_in_ssa_p (cfun))
{
  todo |= TODO_update_ssa | TODO_cleanup_cfg;
  update_stmt (stmt);
}
}
-
  if (flags & ECF_NORETURN
  && fixup_noreturn_call (stmt))
todo |= TODO_cleanup_cfg;
@@ -9867,10 +9863,15 @@ execute_fixup_cfg (void)
}
}
 
- if (maybe_clean_eh_stmt (stmt)
+ gsi_next (&gsi);
+   }
+  if (gimple *last = last_stmt (bb))
+   {
+ if (maybe_clean_eh_stmt (last)
  && gimple_purge_dead_eh_edges (bb))
todo |= TODO_cleanup_cfg;
- gsi_next (&gsi);
+ if (gimple_purge_dead_abnormal_call_edges (bb))
+   todo |= TODO_cleanup_cfg;
}
 
   /* If we have a basic block with no successors that does not
-- 
2.35.3


Re: [PATCH v3 06/11] OpenMP: Pointers and member mappings

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 13, 2022 at 02:03:16PM -0700, Julian Brown wrote:
> @@ -3440,6 +3437,50 @@ gfc_trans_omp_clauses (stmtblock_t *block, 
> gfc_omp_clauses *clauses,
>   {
> if (pointer || (openacc && allocatable))
>   {
> +   gfc_omp_namelist *n2
> + = openacc ? NULL : clauses->lists[OMP_LIST_MAP];
> +
> +   /* If the last reference is a pointer to a derived
> +  type ("foo%dt_ptr"), check if any subcomponents
> +  of the same derived type member are being mapped
> +  elsewhere in the clause list ("foo%dt_ptr%x",
> +  etc.).  If we have such subcomponent mappings,
> +  we only create an ALLOC node for the pointer
> +  itself, and inhibit mapping the whole derived
> +  type.  */
> +
> +   for (; n2 != NULL; n2 = n2->next)
> + {
> +   if (n == n2 || !n2->expr)
> + continue;
> +
> +   int dep
> + = gfc_dep_resolver (n->expr->ref, n2->expr->ref,
> + NULL, true);
> +   if (dep == 0)
> + continue;

Isn't this and the other loop quadratic compile time in number of clauses?
Could it be done linearly through some perhaps lazily built hash table or
something similar?

Jakub



Re: [COMMITTED] Fix unused variable warning (was: [PATCH 1/3] STABS: remove -gstabs and -gxcoff functionality)

2022-09-14 Thread Martin Liška
On 9/14/22 14:19, Jan-Benedict Glaw wrote:
> On Thu, 2022-09-01 12:05:23 +0200, Martin Liška  wrote:
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> I've also built all cross compilers.
>>
>> Ready to be installed?
>> Thanks,
>> Martin
>>
>> gcc/ChangeLog:
>>
>>  * Makefile.in: Remove -gstabs option support, DBX-related
>>macros and DBX debugging info support.
> [...]
>>  * config/mips/mips.cc (mips_output_filename): Likewise.
>>  (mips_option_override): Likewise.
> [...]
>> diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
>> index e81a245dcf4..47724950c3e 100644
>> --- a/gcc/config/mips/mips.cc
>> +++ b/gcc/config/mips/mips.cc
> [...]
>> @@ -20505,24 +20500,13 @@ mips_option_override (void)
>>  
>>for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
>>  {
>> -  mips_dbx_regno[i] = IGNORED_DWARF_REGNUM;
>>if (GP_REG_P (i) || FP_REG_P (i) || ALL_COP_REG_P (i))
>>  mips_dwarf_regno[i] = i;
>>else
>>  mips_dwarf_regno[i] = INVALID_REGNUM;
>>  }
>>  
>> -  start = GP_DBX_FIRST - GP_REG_FIRST;
>> -  for (i = GP_REG_FIRST; i <= GP_REG_LAST; i++)
>> -mips_dbx_regno[i] = i + start;
>> -
>> -  start = FP_DBX_FIRST - FP_REG_FIRST;
>> -  for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++)
>> -mips_dbx_regno[i] = i + start;
>> -
>>/* Accumulator debug registers use big-endian ordering.  */
>> -  mips_dbx_regno[HI_REGNUM] = MD_DBX_FIRST + 0;
>> -  mips_dbx_regno[LO_REGNUM] = MD_DBX_FIRST + 1;
>>mips_dwarf_regno[HI_REGNUM] = MD_REG_FIRST + 0;
>>mips_dwarf_regno[LO_REGNUM] = MD_REG_FIRST + 1;
>>for (i = DSP_ACC_REG_FIRST; i <= DSP_ACC_REG_LAST; i += 2)
> 
> This leaves the `start` variable unused, resulting in a new warning.
> Fixed (committed as obvious) by this:
> 
> /usr/lib/gcc-snapshot/bin/g++  -fno-PIE -c   -g -O2   -DIN_GCC  
> -DCROSS_DIRECTORY_STRUCTURE   -fno-exceptions -fno-rtti 
> -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings 
> -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic 
> -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror 
> -fno-common  -DHAVE_CONFIG_H -I. -I. -I../../gcc/gcc -I../../gcc/gcc/. 
> -I../../gcc/gcc/../include -I../../gcc/gcc/../libcpp/include 
> -I../../gcc/gcc/../libcody  -I../../gcc/gcc/../libdecnumber 
> -I../../gcc/gcc/../libdecnumber/dpd -I../libdecnumber 
> -I../../gcc/gcc/../libbacktrace   -o mips.o -MT mips.o -MMD -MP -MF 
> ./.deps/mips.TPo ../../gcc/gcc/config/mips/mips.cc
> ../../gcc/gcc/config/mips/mips.cc: In function 'void mips_option_override()':
> ../../gcc/gcc/config/mips/mips.cc:20021:10: error: unused variable 'start' 
> [-Werror=unused-variable]
> 20021 |   int i, start, regno, mode;
>   |  ^
> 
> 2022-09-14  Jan-Benedict Glaw  
> 
> gcc/
>   * config/mips/mips.cc (mips_option_override): Drop unused variable.
> 
> diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
> index 47724950c3e..387376b3df8 100644
> --- a/gcc/config/mips/mips.cc
> +++ b/gcc/config/mips/mips.cc
> @@ -20018,7 +20018,7 @@ mips_set_tune (const struct mips_cpu_info *info)
>  static void
>  mips_option_override (void)
>  {
> -  int i, start, regno, mode;
> +  int i, regno, mode;
>  
>if (OPTION_SET_P (mips_isa_option))
>  mips_isa_option_info = &mips_cpu_info_table[mips_isa_option];
> 
> 
> Committed as obvious.
> 
> MfG, JBG
> 

Thanks for the commit!

Cheers,
Martin


Re: [PATCH v3 07/11] OpenMP/OpenACC: Reindent TO/FROM/_CACHE_ stanza in {c_}finish_omp_clause

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 13, 2022 at 02:03:17PM -0700, Julian Brown wrote:
> This patch trivially adds braces and reindents the
> OMP_CLAUSE_TO/OMP_CLAUSE_FROM/OMP_CLAUSE__CACHE_ stanza in
> c_finish_omp_clause and finish_omp_clause, in preparation for the
> following patch (to clarify the diff a little).
> 
> 2022-09-13  Julian Brown  
> 
> gcc/c/
>   * c-typeck.cc (c_finish_omp_clauses): Add braces and reindent
>   OMP_CLAUSE_TO/OMP_CLAUSE_FROM/OMP_CLAUSE__CACHE_ stanza.
> 
> gcc/cp/
>   * semantics.cc (finish_omp_clause): Add braces and reindent
>   OMP_CLAUSE_TO/OMP_CLAUSE_FROM/OMP_CLAUSE__CACHE_ stanza.

Not very happy about this because it ruins git blame, some
vars can be declared separately from initializing them and be thus
usable in switches.  But I see you use there classes with ctors...
So ok.

Jakub



Re: [PATCH v3 08/11] OpenMP/OpenACC: Rework clause expansion and nested struct handling

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 13, 2022 at 02:03:18PM -0700, Julian Brown wrote:
> This patch is an extension and rewrite/rethink of the following two patches:
> 
>   "OpenMP/OpenACC: Add inspector class to unify mapped address analysis"
>   https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591977.html
> 
>   "OpenMP: Handle reference-typed struct members"
>   https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591978.html
> 
> The latter was reviewed here by Jakub:
> 
>   https://gcc.gnu.org/pipermail/gcc-patches/2022-May/595510.html with the
> 
> with the comment,
> 
> > Why isn't a reference to pointer handled that way too?
> 
> and that opened a whole can of worms... generally, C++ references were
> not handled very consistently after the clause-processing code had been
> extended several times already for both OpenACC and OpenMP, and many
> cases of using C++ (and Fortran) references were broken.  Even some
> cases not involving references were being mapped incorrectly.
> 
> At present a single clause may be turned into several mapping nodes,
> or have its mapping type changed, in several places scattered through
> the front- and middle-end.  The analysis relating to which particular
> transformations are needed for some given expression has become quite hard
> to follow.  Briefly, we manipulate clause types in the following places:
> 
>  1. During parsing, in c_omp_adjust_map_clauses.  Depending on a set of
> rules, we may change a FIRSTPRIVATE_POINTER (etc.) mapping into
> ATTACH_DETACH, or mark the decl addressable.
> 
>  2. In semantics.cc or c-typeck.cc, clauses are expanded in
> handle_omp_array_sections (called via {c_}finish_omp_clauses, or in
> finish_omp_clauses itself.  The two cases are for processing array
> sections (the former), or non-array sections (the latter).
> 
>  3. In gimplify.cc, we build sibling lists for struct accesses, which
> groups and sorts accesses along with their struct base, creating
> new ALLOC/RELEASE nodes for pointers.
> 
>  4. In gimplify.cc:gimplify_adjust_omp_clauses, mapping nodes may be
> adjusted or created.
> 
> This patch doesn't completely disrupt this scheme, though clause
> types are no longer adjusted in c_omp_adjust_map_clauses (step 1).
> Clause expansion in step 2 (for C and C++) now uses a single, unified
> mechanism, parts of which are also reused for analysis in step 3.
> 
> Rather than the kind-of "ad-hoc" pattern matching on addresses used to
> expand clauses used at present, a new method for analysing addresses is
> introduced.  This does a recursive-descent tree walk on expression nodes,
> and emits a vector of tokens describing each "part" of the address.
> This tokenized address can then be translated directly into mapping nodes,
> with the assurance that no part of the expression has been inadvertently
> skipped or misinterpreted.  In this way, all the variations of ways
> pointers, arrays, references and component accesses can be teased apart
> into easily-understood cases - and we know we've "parsed" the whole
> address before we start analysis, so the right code paths can easily
> be selected.
> 
> For example, a simple access "arr[idx]" might parse as:
> 
>   base-decl access-indexed-array
> 
> or "mystruct->foo[x]" with a pointer "foo" component might parse as:
> 
>   base-decl access-pointer component-selector access-pointer
> 
> A key observation is that support for "array" bases, e.g. accesses
> whose root nodes are not structures, but describe scalars or arrays,
> and also *one-level deep* structure accesses, have first-class support
> in gimplify and beyond.  Expressions that use deeper struct accesses
> or e.g. multiple indirections were more problematic: some cases worked,
> but lots of cases didn't.  This patch reimplements the support for those
> in gimplify.cc, again using the new "address tokenization" support.
> 
> An expression like "mystruct->foo->bar[0:10]" used in a mapping node will
> translate the right-hand access directly in the front-end.  The base for
> the access will be "mystruct->foo".  This is handled recursively -- there
> may be several accesses of "mystruct"'s members on the same directive,
> so the sibling-list building machinery can be used again.  (This was
> already being done for OpenACC, but the new implementation differs
> somewhat in details, and is more robust.)
> 
> For OpenMP, in the case where the base pointer itself,
> i.e. "mystruct->foo" here, is NOT mapped on the same directive, we
> create a "fragile" mapping.  This turns the "foo" component access
> into a zero-length allocation (which is a new feature for the runtime,
> so support has been added there too).
> 
> A couple of changes have been made to how mapping clauses are turned
> into mapping nodes:
> 
> The first change is based on the observation that it is probably never
> correct to use GOMP_MAP_ALWAYS_POINTER for component accesses (e.g. for
> references), because if the containing struct is already mapped on the

Re: [PATCH Rust front-end v2 09/37] gccrs: Add Lexer for Rust front-end

2022-09-14 Thread Richard Biener via Gcc-patches
On Wed, Aug 24, 2022 at 2:04 PM  wrote:
>
> From: The Other 
>
> The lexer is refered to as a ManagedTokenSource within the parser, this
> lexer does not currently support unicode but serves as a starting point
> to do so.
>
> Co-authored-by: Philip Herron 
> Co-authored-by: Arthur Cohen 
> Co-authored-by: Mark Wielaard 
> ---
>  gcc/rust/lex/rust-codepoint.h  |   46 +
>  gcc/rust/lex/rust-lex.cc   | 2729 
>  gcc/rust/lex/rust-lex.h|  271 
>  gcc/rust/lex/rust-token.cc |  135 ++
>  gcc/rust/lex/rust-token.h  |  455 ++
>  gcc/rust/rust-buffered-queue.h |  204 +++
>  6 files changed, 3840 insertions(+)
>  create mode 100644 gcc/rust/lex/rust-codepoint.h
>  create mode 100644 gcc/rust/lex/rust-lex.cc
>  create mode 100644 gcc/rust/lex/rust-lex.h
>  create mode 100644 gcc/rust/lex/rust-token.cc
>  create mode 100644 gcc/rust/lex/rust-token.h
>  create mode 100644 gcc/rust/rust-buffered-queue.h
>
> diff --git a/gcc/rust/lex/rust-codepoint.h b/gcc/rust/lex/rust-codepoint.h
> new file mode 100644
> index 000..22da080bbb2
> --- /dev/null
> +++ b/gcc/rust/lex/rust-codepoint.h
> @@ -0,0 +1,46 @@
> +// Copyright (C) 2020-2022 Free Software Foundation, Inc.
> +
> +// This file is part of GCC.
> +
> +// GCC is free software; you can redistribute it and/or modify it under
> +// the terms of the GNU General Public License as published by the Free
> +// Software Foundation; either version 3, or (at your option) any later
> +// version.
> +
> +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +// WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +// for more details.
> +
> +// You should have received a copy of the GNU General Public License
> +// along with GCC; see the file COPYING3.  If not see
> +// .
> +
> +#ifndef RUST_CODEPOINT_H
> +#define RUST_CODEPOINT_H
> +
> +#include 
> +
> +namespace Rust {
> +struct Codepoint
> +{
> +  uint32_t value;
> +
> +  // Creates a zero codepoint.
> +  Codepoint () : value (0) {}
> +
> +  // Creates a codepoint from an encoded UTF-8 value.
> +  Codepoint (uint32_t value) : value (value) {}
> +
> +  static Codepoint eof () { return Codepoint (UINT32_MAX); }
> +  bool is_eof () const { return value == UINT32_MAX; }
> +
> +  // Returns a C++ string containing string value of codepoint.
> +  std::string as_string ();
> +
> +  bool operator== (Codepoint other) const { return value == other.value; }
> +  bool operator!= (Codepoint other) const { return !operator== (other); }
> +};
> +} // namespace Rust
> +
> +#endif
> diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
> new file mode 100644
> index 000..70e6b50209f
> --- /dev/null
> +++ b/gcc/rust/lex/rust-lex.cc
> @@ -0,0 +1,2729 @@
> +// Copyright (C) 2020-2022 Free Software Foundation, Inc.
> +
> +// This file is part of GCC.
> +
> +// GCC is free software; you can redistribute it and/or modify it under
> +// the terms of the GNU General Public License as published by the Free
> +// Software Foundation; either version 3, or (at your option) any later
> +// version.
> +
> +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +// WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +// for more details.
> +
> +// You should have received a copy of the GNU General Public License
> +// along with GCC; see the file COPYING3.  If not see
> +// .
> +
> +#include "rust-lex.h"
> +
> +#include "rust-system.h"  // for rust_assert and rust_unreachable
> +#include "rust-diagnostics.h" // for rust_error_at
> +#include "rust-linemap.h"
> +#include "rust-session-manager.h"
> +#include "safe-ctype.h"

just diving into a random patch here - I'm assuming I can take rust-lex.cc as
a boiler-plate example for the #include structure.

In GCC all files should start with #including "config.h" followed by
"system.h" where _all_ system, including C++ standard library headers
should be pulled via system.h to allow working around OS and system
compiler issues.

It might be that rust-system.h plays the role of config.h + system.h
but then the rust-lex.h include is before it.

rust-codepoint.h including  is also problematic btw.

Richard.

> +namespace Rust {
> +// TODO: move to separate compilation unit?
> +// overload += for uint32_t to allow 32-bit encoded utf-8 to be added
> +std::string &
> +operator+= (std::string &str, Codepoint char32)
> +{
> +  if (char32.value < 0x80)
> +{
> +  str += static_cast (char32.value);
> +}
> +  else if (char32.value < (0x1F + 1) << (1 * 6))
> +{
> +  str += static_cast (0xC0 | ((char32.value >> 6) & 0x1F));
> +  str += static_cast (0x80 | ((char32.value >> 0) & 0x3F));
> +}
> +  else if (char32.value < (0x0F + 1) << (2 *

Re: [PATCH Rust front-end v2 31/37] gccrs: Add GCC Rust front-end Make-lang.in

2022-09-14 Thread Richard Biener via Gcc-patches
On Wed, Aug 24, 2022 at 2:22 PM  wrote:
>
> From: Philip Herron 
>
> This is the Makefile for our front-end.
> ---
>  gcc/rust/Make-lang.in | 400 ++
>  1 file changed, 400 insertions(+)
>  create mode 100644 gcc/rust/Make-lang.in
>
> diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
> new file mode 100644
> index 000..f687cc2f667
> --- /dev/null
> +++ b/gcc/rust/Make-lang.in
> @@ -0,0 +1,400 @@
> +# Make-lang.in -- Top level -*- makefile -*- fragment for GCC Rust frontend.
> +
> +# Copyright (C) 2009-2022 Free Software Foundation, Inc.
> +
> +# This file is part of GCC.
> +
> +# GCC is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3, or (at your option)
> +# any later version.
> +
> +# GCC is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# .
> +
> +# This file provides the language dependent support in the main Makefile.
> +
> +#RUST_EXES = rust
> +
> +# Use strict warnings for this front end.
> +rust-warn = $(STRICT_WARN)
> +
> +# Installation name. Useful for cross compilers and used during install.
> +GCCRS_INSTALL_NAME := $(shell echo gccrs|sed '$(program_transform_name)')
> +GCCRS_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gccrs|sed 
> '$(program_transform_name)')
> +
> +# Define the names for selecting rust in LANGUAGES.
> +rust: rust1$(exeext)
> +
> +# Tell GNU make to ignore files by these names if they exist.
> +.PHONY: rust
> +
> +# removed GRS_CFLAGS from here
> +
> +CFLAGS-rust/rustspec.o += $(DRIVER_DEFINES)
> +
> +# Create the compiler driver gccrs.
> +# A compiler driver is the program that interprets command argument and can 
> be called from the command
> +# line - e.g. gcc or g++, and not cc1, which is the actual compiler
> +
> +# Create driver objects
> +GCCRS_D_OBJS = \
> +   $(GCC_OBJS) \
> +   rust/rustspec.o \
> +   $(END)
> +
> +gccrs$(exeext): $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a 
> $(LIBDEPS)
> +   +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
> + $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \
> + $(EXTRA_GCC_LIBS) $(LIBS)
> +
> +# List of host object files used by the rust language - files for 
> translation from the parse tree
> +# to GENERIC
> +# The compiler proper, not driver
> +GRS_OBJS = \
> +rust/rust-lang.o \
> +rust/rust-object-export.o \
> +rust/rust-linemap.o \
> +rust/rust-gcc-diagnostics.o \
> +rust/rust-diagnostics.o \
> +rust/rust-gcc.o \
> +rust/rust-token.o \
> +rust/rust-lex.o \
> +rust/rust-cfg-parser.o \
> +rust/rust-parse.o \
> +rust/rust-ast-full-test.o \
> +rust/rust-ast-dump.o \
> +rust/rust-hir-dump.o \
> +rust/rust-session-manager.o \
> +rust/rust-compile.o \
> +rust/rust-mangle.o \
> +rust/rust-compile-resolve-path.o \
> +rust/rust-macro-expand.o \
> +rust/rust-attribute-visitor.o \
> +rust/rust-macro-invoc-lexer.o \
> +rust/rust-macro-substitute-ctx.o \
> +rust/rust-macro-builtins.o \
> +rust/rust-hir-full-test.o \
> +rust/rust-hir-map.o \
> +rust/rust-attributes.o \
> +rust/rust-abi.o \
> +rust/rust-ast-lower.o \
> +rust/rust-ast-lower-base.o \
> +rust/rust-ast-lower-pattern.o \
> +rust/rust-ast-lower-item.o \
> +rust/rust-name-resolver.o \
> +rust/rust-ast-resolve.o \
> +rust/rust-ast-resolve-base.o \
> +rust/rust-ast-resolve-item.o \
> +rust/rust-ast-resolve-pattern.o \
> +rust/rust-ast-resolve-expr.o \
> +rust/rust-ast-resolve-type.o \
> +rust/rust-ast-resolve-path.o \
> +rust/rust-ast-resolve-stmt.o \
> +rust/rust-ast-resolve-struct-expr-field.o \
> +rust/rust-hir-type-check.o \
> +rust/rust-privacy-check.o \
> +rust/rust-privacy-ctx.o \
> +rust/rust-reachability.o \
> +rust/rust-visibility-resolver.o \
> +rust/rust-pub-restricted-visitor.o \
> +rust/rust-privacy-reporter.o \
> +rust/rust-tyty.o \
> +rust/rust-tyty-call.o \
> +rust/rust-tyctx.o \
> +rust/rust-tyty-bounds.o \
> +rust/rust-hir-type-check-util.o \
> +rust/rust-hir-trait-resolve.o \
> +rust/rust-hir-type-check-toplevel.o \
> +rust/rust-hir-type-check-item.o \
> +rust/rust-hir-type-check-type.o \
> +rust/rust-hir-type-check-struct.o \
> +rust/rust-hir-type-check-pattern.o \
> +rust/rust-hir-type-check-expr.o \
> +rust/rust-hir-type-check-stmt.o \
> +rust/rust-hir-type-check-enumitem.o \
> +rust/rust-hir-type-check-implitem.o \
> +rust/rust-hir-dot-o

Re: [PATCH Rust front-end v2 09/37] gccrs: Add Lexer for Rust front-end

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Wed, Sep 14, 2022 at 03:30:39PM +0200, Richard Biener via Gcc-patches wrote:
> > +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> > +// WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > +// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> > +// for more details.
> > +
> > +// You should have received a copy of the GNU General Public License
> > +// along with GCC; see the file COPYING3.  If not see
> > +// .
> > +
> > +#include "rust-lex.h"
> > +
> > +#include "rust-system.h"  // for rust_assert and rust_unreachable
> > +#include "rust-diagnostics.h" // for rust_error_at
> > +#include "rust-linemap.h"
> > +#include "rust-session-manager.h"
> > +#include "safe-ctype.h"
> 
> just diving into a random patch here - I'm assuming I can take rust-lex.cc as
> a boiler-plate example for the #include structure.
> 
> In GCC all files should start with #including "config.h" followed by
> "system.h" where _all_ system, including C++ standard library headers
> should be pulled via system.h to allow working around OS and system
> compiler issues.
> 
> It might be that rust-system.h plays the role of config.h + system.h
> but then the rust-lex.h include is before it.
> 
> rust-codepoint.h including  is also problematic btw.

E.g. the Go FE has two parts, one very GCC specific that uses the explicit
config.h + system.h etc. includes, the other is generic and there it
includes go-system.h in every file first, where that starts with
#include 

various C++ standard includes

#include 
etc.

Jakub



Re: [PATCH Rust front-end v2 34/37] gccrs: add lang.opt

2022-09-14 Thread Richard Biener via Gcc-patches
On Wed, Aug 24, 2022 at 2:13 PM  wrote:
>
> From: Philip Herron 
>
> We have some rust specific langugage options note -fwrapv is enabled by
> default in the code. We are trying to respect options such as
> -Wunused-result which we get by porting over c++ no-discard for rust's
> must-use attribute, so we have enabled these by default directly here.

LGTM

Richard.

> ---
>  gcc/rust/lang.opt | 118 ++
>  1 file changed, 118 insertions(+)
>  create mode 100644 gcc/rust/lang.opt
>
> diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
> new file mode 100644
> index 000..1f6855ede1d
> --- /dev/null
> +++ b/gcc/rust/lang.opt
> @@ -0,0 +1,118 @@
> +; Options for the Rust front end.
> +; Copyright (C) 2003-2022 Free Software Foundation, Inc.
> +;
> +; This file is part of GCC.
> +;
> +; GCC is free software; you can redistribute it and/or modify it under
> +; the terms of the GNU General Public License as published by the Free
> +; Software Foundation; either version 3, or (at your option) any later
> +; version.
> +;
> +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +; WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +; for more details.
> +;
> +; You should have received a copy of the GNU General Public License
> +; along with GCC; see the file COPYING3.  If not see
> +; .
> +
> +; See the GCC internals manual for a description of this file's format.
> +
> +; Please try to keep this file in ASCII collating order.
> +
> +; Describes command-line options used by this frontend
> +
> +Language
> +Rust
> +
> +I
> +Rust Joined Separate
> +; Documented in c.opt
> +
> +L
> +Rust Joined Separate
> +; Not documented
> +
> +Wall
> +Rust
> +; Documented in c.opt
> +
> +Wunused-variable
> +Rust Var(warn_unused_variable) Init(1) Warning
> +; documented in common.opt
> +
> +Wunused-const-variable
> +Rust Warning Alias(Wunused-const-variable=, 2, 0)
> +Warn when a const variable is unused.
> +
> +Wunused-const-variable=
> +Rust Joined RejectNegative UInteger Var(warn_unused_const_variable) Init(1) 
> Warning LangEnabledBy(Rust,Wunused-variable, 1, 0) IntegerRange(0, 2)
> +Warn when a const variable is unused.
> +
> +Wunused-result
> +Rust Var(warn_unused_result) Init(1) Warning
> +Warn if a caller of a function, marked with attribute warn_unused_result, 
> does not use its return value.
> +
> +frust-crate=
> +Rust Joined RejectNegative
> +-frust-crate= Set the crate name for the compilation
> +
> +frust-debug
> +Rust Var(flag_rust_debug)
> +Dump various Rust front end internals.
> +
> +frust-dump-
> +Rust Joined RejectNegative
> +-frust-dump- Dump Rust frontend internal information.
> +
> +frust-max-recursion-depth=
> +Rust RejectNegative Type(int) Var(rust_max_recursion_depth) Init(64)
> +-frust-max-recursion-depth=integer
> +
> +frust-mangling=
> +Rust Joined RejectNegative Enum(frust_mangling) Var(flag_rust_mangling)
> +-frust-mangling=[legacy|v0] Choose which version to use for name mangling
> +
> +Enum
> +Name(frust_mangling) Type(int) UnknownError(unknown rust mangling option %qs)
> +
> +EnumValue
> +Enum(frust_mangling) String(legacy) Value(0)
> +
> +EnumValue
> +Enum(frust_mangling) String(v0) Value(1)
> +
> +frust-cfg=
> +Rust Joined RejectNegative
> +-frust-cfg= Set a config expansion option
> +
> +frust-edition=
> +Rust Joined RejectNegative Enum(frust_edition) Var(flag_rust_edition)
> +-frust-edition=[2015|2018|2021] Choose which edition to use when 
> compiling rust code
> +
> +Enum
> +Name(frust_edition) Type(int) UnknownError(unknown rust edition %qs)
> +
> +EnumValue
> +Enum(frust_edition) String(2015) Value(0)
> +
> +EnumValue
> +Enum(frust_edition) String(2018) Value(1)
> +
> +EnumValue
> +Enum(frust_edition) String(2021) Value(2)
> +
> +frust-embed-metadata
> +Rust Var(flag_rust_embed_metadata)
> +Flag to enable embeding metadata directly into object files
> +
> +frust-metadata-output=
> +Rust Joined RejectNegative
> +-frust-metadata-output=  Path to output crate metadata
> +
> +o
> +Rust Joined Separate
> +; Documented in common.opt
> +
> +; This comment is to ensure we retain the blank line above.
> --
> 2.25.1
>


Re: [PATCH Rust front-end v2 32/37] gccrs: Add config-lang.in

2022-09-14 Thread Richard Biener via Gcc-patches
On Wed, Aug 24, 2022 at 2:19 PM  wrote:
>
> From: Philip Herron 
>
> This was a copy paste from gccgo front-end, we do not use any of the
> target_libs yet but we will need these when we support the libpanic crate.

LGTM

> ---
>  gcc/rust/config-lang.in | 34 ++
>  1 file changed, 34 insertions(+)
>  create mode 100644 gcc/rust/config-lang.in
>
> diff --git a/gcc/rust/config-lang.in b/gcc/rust/config-lang.in
> new file mode 100644
> index 000..d2ff376032a
> --- /dev/null
> +++ b/gcc/rust/config-lang.in
> @@ -0,0 +1,34 @@
> +# config-lang.in -- Top level configure fragment for gcc Rust frontend.
> +
> +# Copyright (C) 2009-2022 Free Software Foundation, Inc.
> +
> +# This file is part of GCC.
> +
> +# GCC is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3, or (at your option)
> +# any later version.
> +
> +# GCC is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# .
> +
> +# Configure looks for the existence of this file to auto-config each 
> language.
> +# We define several parameters used by configure:
> +#
> +# language - name of language as it would appear in $(LANGUAGES)
> +# compilers- value to add to $(COMPILERS)
> +
> +language="rust"
> +compilers="rust1\$(exeext)"
> +
> +build_by_default="no"
> +
> +target_libs="target-libffi target-libbacktrace"
> +
> +gtfiles="\$(srcdir)/rust/rust-lang.cc"
> --
> 2.25.1
>


Re: [PATCH Rust front-end v2 33/37] gccrs: add lang-spec.h

2022-09-14 Thread Richard Biener via Gcc-patches
On Wed, Aug 24, 2022 at 2:20 PM  wrote:
>
> From: Philip Herron 
>
> This specifies the extensions of the Rust language.

LGTM

> ---
>  gcc/rust/lang-specs.h | 26 ++
>  1 file changed, 26 insertions(+)
>  create mode 100644 gcc/rust/lang-specs.h
>
> diff --git a/gcc/rust/lang-specs.h b/gcc/rust/lang-specs.h
> new file mode 100644
> index 000..9b14a559dd6
> --- /dev/null
> +++ b/gcc/rust/lang-specs.h
> @@ -0,0 +1,26 @@
> +/* lang-specs.h -- gcc driver specs for Rust frontend.
> +   Copyright (C) 2009-2022 Free Software Foundation, Inc.
> +
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it under
> +   the terms of the GNU General Public License as published by the Free
> +   Software Foundation; either version 3, or (at your option) any later
> +   version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +   WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +   for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   .  */
> +
> +/* This is the contribution to the `default_compilers' array in gcc.cc
> +   for the Rust language.  */
> +
> +{".rs", "@rs", 0, 1, 0},
> +  {"@rs",
> +   "rust1 %i %(cc1_options) %{I*} %{L*} %D %{!fsyntax-only:%(invoke_as)}", 
> 0, 1,
> +   0},
> --
> 2.25.1
>


Re: [PATCH Rust front-end v2 07/37] gccrs: Add gcc-check-target check-rust

2022-09-14 Thread Richard Biener via Gcc-patches
On Wed, Aug 24, 2022 at 2:08 PM  wrote:
>
> From: Philip Herron 
>
> This allows us to invoke the rust testsuite.

OK.

>
> ChangeLog:
> * Makefile.def: Add autogen target
> * Makefile.in: regenerate via autogen
> ---
>  Makefile.def | 1 +
>  Makefile.in  | 8 
>  2 files changed, 9 insertions(+)
>
> diff --git a/Makefile.def b/Makefile.def
> index 3291b126b26..821016af3a2 100644
> --- a/Makefile.def
> +++ b/Makefile.def
> @@ -681,6 +681,7 @@ languages = { language=go;  gcc-check-target=check-go;
>  languages = { language=d;  gcc-check-target=check-d;
> lib-check-target=check-target-libphobos; };
>  languages = { language=jit;gcc-check-target=check-jit; };
> +languages = { language=rust;   gcc-check-target=check-rust; };
>
>  // Toplevel bootstrap
>  bootstrap_stage = { id=1 ; };
> diff --git a/Makefile.in b/Makefile.in
> index 1919dfee829..9ed2c0dec52 100644
> --- a/Makefile.in
> +++ b/Makefile.in
> @@ -60583,6 +60583,14 @@ check-gcc-jit:
> (cd gcc && $(MAKE) $(GCC_FLAGS_TO_PASS) check-jit);
>  check-jit: check-gcc-jit
>
> +.PHONY: check-gcc-rust check-rust
> +check-gcc-rust:
> +   r=`${PWD_COMMAND}`; export r; \
> +   s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
> +   $(HOST_EXPORTS) \
> +   (cd gcc && $(MAKE) $(GCC_FLAGS_TO_PASS) check-rust);
> +check-rust: check-gcc-rust
> +
>
>  # The gcc part of install-no-fixedincludes, which relies on an intimate
>  # knowledge of how a number of gcc internal targets (inter)operate.  
> Delegate.
> --
> 2.25.1
>


Re: [PATCH v3 08/11] OpenMP/OpenACC: Rework clause expansion and nested struct handling

2022-09-14 Thread Julian Brown
On Wed, 14 Sep 2022 15:24:12 +0200
Jakub Jelinek via Fortran  wrote:

> On Tue, Sep 13, 2022 at 02:03:18PM -0700, Julian Brown wrote:
> > +class c_omp_address_inspector
> > +{
> > +  location_t loc;
> > +  tree root_term;
> > +  bool indirections;
> > +  int map_supported;
> > +
> > +protected:
> > +  tree orig;
> > +
> > +public:
> > +  c_omp_address_inspector (location_t loc, tree t)
> > +: loc (loc), root_term (NULL_TREE), indirections (false),
> > +  map_supported (-1), orig (t)
> > +  {}
> > +
> > +  ~c_omp_address_inspector ()
> > +  {}
> > +
> > +  virtual bool processing_template_decl_p ()
> > +{
> > +  return false;
> > +}
> > +
> > +  virtual void emit_unmappable_type_notes (tree)
> > +{
> > +}
> > +
> > +  virtual tree convert_from_reference (tree)
> > +{
> > +  gcc_unreachable ();
> > +}
> > +
> > +  virtual tree build_array_ref (location_t loc, tree arr, tree idx)
> > +{
> > +  tree eltype = TREE_TYPE (TREE_TYPE (arr));
> > +  return build4_loc (loc, ARRAY_REF, eltype, arr, idx,
> > NULL_TREE,
> > +NULL_TREE);
> > +}
> > +
> > +  bool check_clause (tree);
> > +  tree get_root_term (bool);
> > +
> > +  tree get_address ()
> > +{
> > +  return orig;
> > +}  
> 
> This has the method formatting style inconsistency I've walked about
> earlier.
> Either the {s are indented 2 further columns, or they aren't, but
> definitely not both in the same class.

OK, I wasn't sure about that (despite your previous comment), since the
empty constructor/destructor un-indented {} is present elsewhere in GCC
(...though I think you mentioned that, too). Will fix.

> Missing function comment before following:
> 
> > +static bool
> > +omp_directive_maps_explicitly (hash_map > +   omp_mapping_group *>
> > *grpmap,
> > +  tree decl, omp_mapping_group
> > **base_group,
> > +  bool to_specifically, bool
> > allow_deleted,
> > +  bool contained_in_struct)
> > +{
> > +  omp_mapping_group *decl_group
> > += omp_get_nonfirstprivate_group (grpmap, decl, allow_deleted);
> > +
> > +  *base_group = NULL;
> > +
> > +  if (decl_group)
> > +{
> > +  tree grp_first = *decl_group->grp_start;
> > +  /* We might be called during omp_build_struct_sibling_lists,
> > when
> > +GOMP_MAP_STRUCT might have been inserted at the start of
> > the group.
> > +Skip over that, and also possibly the node after it.  */
> > +  if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT)
> > +   {
> > + grp_first = OMP_CLAUSE_CHAIN (grp_first);
> > + if (OMP_CLAUSE_MAP_KIND (grp_first) ==
> > GOMP_MAP_FIRSTPRIVATE_POINTER
> > + || (OMP_CLAUSE_MAP_KIND (grp_first)
> > + == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
> > + || OMP_CLAUSE_MAP_KIND (grp_first) ==
> > GOMP_MAP_ATTACH_DETACH)
> > +   grp_first = OMP_CLAUSE_CHAIN (grp_first);
> > +   }
> > +  enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND
> > (grp_first);
> > +  if (!to_specifically
> > + || GOMP_MAP_COPY_TO_P (first_kind)
> > + || first_kind == GOMP_MAP_ALLOC)
> > +   {
> > + *base_group = decl_group;
> > + return true;
> > +   }
> > +}
> > +
> > +  if (contained_in_struct
> > +  && omp_mapped_by_containing_struct (grpmap, decl,
> > base_group))
> > +return true;
> > +
> > +  return false;
> > +}  
> 
> Why?
> gimplify_scan_omp_clauses certainly should have a function comment.

I'm actually not sure what happened there -- a merge error, I think.
Sorry about that!

> >  
> > -/* Scan the OMP clauses in *LIST_P, installing mappings into a new
> > -   and previous omp contexts.  */
> > -
> >  static void
> >  gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
> >enum omp_region_type region_type,
> >enum tree_code code)  
> 
> > +
> > +enum structure_base_kinds
> > +{
> > +  BASE_DECL,
> > +  BASE_COMPONENT_EXPR,
> > +  BASE_ARBITRARY_EXPR
> > +};
> > +
> > +enum token_type
> > +{
> > +  ARRAY_BASE,
> > +  STRUCTURE_BASE,
> > +  COMPONENT_SELECTOR,
> > +  ACCESS_METHOD
> > +};  
> 
> Wouldn't hurt to add comment about omp_addr_token and the above two
> enums.
> 
> > +
> > +struct omp_addr_token
> > +{
> > +  enum token_type type;
> > +  tree expr;
> > +
> > +  union
> > +  {
> > +access_method_kinds access_kind;
> > +structure_base_kinds structure_base_kind;
> > +  } u;
> > +
> > +  omp_addr_token (token_type, tree);
> > +  omp_addr_token (access_method_kinds, tree);
> > +  omp_addr_token (token_type, structure_base_kinds, tree);
> > +};  
> 
> > --- a/libgomp/target.c
> > +++ b/libgomp/target.c
> > @@ -718,7 +718,7 @@ gomp_map_fields_existing (struct
> > target_mem_desc *tgt, 
> >cur_node.host_start = (uintptr_t) hostaddrs[i];
> >cur_node.host_end = cur_node.host_start + sizes[i];
> > -  splay_tree_key n2 = splay_tree_lookup (mem_map, &cur_no

Re: [PATCH Rust front-end v2 07/37] gccrs: Add gcc-check-target check-rust

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Wed, Sep 14, 2022 at 03:41:48PM +0200, Richard Biener via Gcc-patches wrote:
> On Wed, Aug 24, 2022 at 2:08 PM  wrote:
> >
> > From: Philip Herron 
> >
> > This allows us to invoke the rust testsuite.
> 
> OK.
> 
> >
> > ChangeLog:
> > * Makefile.def: Add autogen target
> > * Makefile.in: regenerate via autogen

The changelog doesn't match what the patch does (Add rust language.
and Regenerate.), plus missing . at the end and in one case capital
letter after :

Jakub



[PATCH] Move void_list_node init to common code

2022-09-14 Thread Richard Biener via Gcc-patches
All frontends replicate this, so move it.

Bootstrap and regtest running for all languages on 
x86_64-unknown-linux-gnu.

OK if that succeeds?

Thanks,
Richard.

gcc/
* tree.cc (build_common_tree_nodes): Initialize void_list_node
here.

gcc/ada/
* gcc-interface/trans.cc (gigi): Do not initialize void_list_node.

gcc/c-family/
* c-common.h (build_void_list_node): Remove.
* c-common.cc (c_common_nodes_and_builtins): Do not initialize
void_list_node.

gcc/c/
* c-decl.cc (build_void_list_node): Remove.

gcc/cp/
* decl.cc (cxx_init_decl_processing): Inline last
build_void_list_node call.
(build_void_list_node): Remove.

gcc/d/
* d-builtins.cc (d_build_c_type_nodes): Do not initialize
void_list_node.

gcc/fortran/
* f95-lang.c (gfc_init_decl_processing): Do not initialize
void_list_node.

gcc/go/
* go-lang.cc (go_langhook_init): Do not initialize
void_list_node.

gcc/jit/
* dummy-frontend.cc (jit_langhook_init): Do not initialize
void_list_node.

gcc/lto/
* lto-lang.cc (lto_build_c_type_nodes): Do not initialize
void_list_node.
---
 gcc/ada/gcc-interface/trans.cc |  1 -
 gcc/c-family/c-common.cc   |  2 --
 gcc/c-family/c-common.h|  1 -
 gcc/c/c-decl.cc|  8 
 gcc/cp/decl.cc | 10 +-
 gcc/d/d-builtins.cc|  1 -
 gcc/fortran/f95-lang.cc|  2 --
 gcc/go/go-lang.cc  |  3 ---
 gcc/jit/dummy-frontend.cc  |  3 ---
 gcc/lto/lto-lang.cc|  1 -
 gcc/tree.cc|  2 ++
 11 files changed, 3 insertions(+), 31 deletions(-)

diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc
index f2e0cb2299b..2d93947cb26 100644
--- a/gcc/ada/gcc-interface/trans.cc
+++ b/gcc/ada/gcc-interface/trans.cc
@@ -413,7 +413,6 @@ gigi (Node_Id gnat_root,
   save_gnu_tree (gnat_literal, t, false);
 
   /* Declare the building blocks of function nodes.  */
-  void_list_node = build_tree_list (NULL_TREE, void_type_node);
   void_ftype = build_function_type_list (void_type_node, NULL_TREE);
   ptr_void_ftype = build_pointer_type (void_ftype);
 
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 0a5b7e120c9..c0f15f4cab1 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -4505,8 +4505,6 @@ c_common_nodes_and_builtins (void)
 TYPE_NAME (void_type_node) = void_name;
   }
 
-  void_list_node = build_void_list_node ();
-
   /* Make a type to be the domain of a few array types
  whose domains don't really matter.
  200 is small enough that it always fits in size_t
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index ce971a29b5d..2f592f5cd58 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -853,7 +853,6 @@ extern tree identifier_global_tag (tree);
 extern bool names_builtin_p (const char *);
 extern tree c_linkage_bindings (tree);
 extern void record_builtin_type (enum rid, const char *, tree);
-extern tree build_void_list_node (void);
 extern void start_fname_decls (void);
 extern void finish_fname_decls (void);
 extern const char *fname_as_string (int);
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 34f8feda897..b09c6393b91 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -10676,14 +10676,6 @@ record_builtin_type (enum rid rid_index, const char 
*name, tree type)
 debug_hooks->type_decl (decl, false);
 }
 
-/* Build the void_list_node (void_type_node having been created).  */
-tree
-build_void_list_node (void)
-{
-  tree t = build_tree_list (NULL_TREE, void_type_node);
-  return t;
-}
-
 /* Return a c_parm structure with the given SPECS, ATTRS and DECLARATOR.  */
 
 struct c_parm *
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 006e9affcba..070f673c3a2 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -4623,7 +4623,7 @@ cxx_init_decl_processing (void)
   record_unknown_type (init_list_type_node, "init list");
 
   /* Used when parsing to distinguish parameter-lists () and (void).  */
-  explicit_void_list_node = build_void_list_node ();
+  explicit_void_list_node = build_tree_list (NULL_TREE, void_type_node);
 
   {
 /* Make sure we get a unique function type, so we can give
@@ -18450,14 +18450,6 @@ cp_tree_node_structure (union lang_tree_node * t)
 }
 }
 
-/* Build the void_list_node (void_type_node having been created).  */
-tree
-build_void_list_node (void)
-{
-  tree t = build_tree_list (NULL_TREE, void_type_node);
-  return t;
-}
-
 bool
 cp_missing_noreturn_ok_p (tree decl)
 {
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index c2ef0c836e1..5997e5dcaf4 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -889,7 +889,6 @@ static GTY(()) tree signed_size_type_node;
 static void
 d_build_c_type_nodes (void)
 {
-  void_list_node = build_tree_list (NULL_TREE, void_type_node);
   string_type_node = build_pointer_type (char_type_

[PATCH] libstdc++: Implement ranges::chunk_by_view from P2443R1

2022-09-14 Thread Patrick Palka via Gcc-patches
Tested on x86_64-pc-linux-gnu, does this look OK for trunk?

libstdc++-v3/ChangeLog:

* include/bits/ranges_algo.h (__adjacent_find_fn, adjacent_find):
Move to ...
* include/bits/ranges_util.h: ... here.
* include/std/ranges (chunk_by_view): Define.
(chunk_by_view::_Iterator): Define.
(__detail::__can_chunk_by_view): Define.
(_ChunkBy, chunk_by): Define.
* testsuite/std/ranges/adaptors/chunk_by/1.cc: New test.
---
 libstdc++-v3/include/bits/ranges_algo.h   |  38 +---
 libstdc++-v3/include/bits/ranges_util.h   |  38 
 libstdc++-v3/include/std/ranges   | 193 ++
 .../std/ranges/adaptors/chunk_by/1.cc |  58 ++
 4 files changed, 290 insertions(+), 37 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/std/ranges/adaptors/chunk_by/1.cc

diff --git a/libstdc++-v3/include/bits/ranges_algo.h 
b/libstdc++-v3/include/bits/ranges_algo.h
index 2a116361a67..228e10b62bf 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -506,43 +506,7 @@ namespace ranges
 
   inline constexpr __find_end_fn find_end{};
 
-  struct __adjacent_find_fn
-  {
-template _Sent,
-typename _Proj = identity,
-indirect_binary_predicate,
-  projected<_Iter, _Proj>> _Pred
-  = ranges::equal_to>
-  constexpr _Iter
-  operator()(_Iter __first, _Sent __last,
-_Pred __pred = {}, _Proj __proj = {}) const
-  {
-   if (__first == __last)
- return __first;
-   auto __next = __first;
-   for (; ++__next != __last; __first = __next)
- {
-   if (std::__invoke(__pred,
- std::__invoke(__proj, *__first),
- std::__invoke(__proj, *__next)))
- return __first;
- }
-   return __next;
-  }
-
-template, _Proj>,
-  projected, _Proj>> _Pred = ranges::equal_to>
-  constexpr borrowed_iterator_t<_Range>
-  operator()(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) const
-  {
-   return (*this)(ranges::begin(__r), ranges::end(__r),
-  std::move(__pred), std::move(__proj));
-  }
-  };
-
-  inline constexpr __adjacent_find_fn adjacent_find{};
+  // adjacent_find is defined in .
 
   struct __is_permutation_fn
   {
diff --git a/libstdc++-v3/include/bits/ranges_util.h 
b/libstdc++-v3/include/bits/ranges_util.h
index bb56deee01b..85ddea68407 100644
--- a/libstdc++-v3/include/bits/ranges_util.h
+++ b/libstdc++-v3/include/bits/ranges_util.h
@@ -704,6 +704,44 @@ namespace ranges
 
   inline constexpr __min_fn min{};
 
+  struct __adjacent_find_fn
+  {
+template _Sent,
+typename _Proj = identity,
+indirect_binary_predicate,
+  projected<_Iter, _Proj>> _Pred
+  = ranges::equal_to>
+  constexpr _Iter
+  operator()(_Iter __first, _Sent __last,
+_Pred __pred = {}, _Proj __proj = {}) const
+  {
+   if (__first == __last)
+ return __first;
+   auto __next = __first;
+   for (; ++__next != __last; __first = __next)
+ {
+   if (std::__invoke(__pred,
+ std::__invoke(__proj, *__first),
+ std::__invoke(__proj, *__next)))
+ return __first;
+ }
+   return __next;
+  }
+
+template, _Proj>,
+  projected, _Proj>> _Pred = ranges::equal_to>
+  constexpr borrowed_iterator_t<_Range>
+  operator()(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) const
+  {
+   return (*this)(ranges::begin(__r), ranges::end(__r),
+  std::move(__pred), std::move(__proj));
+  }
+  };
+
+  inline constexpr __adjacent_find_fn adjacent_find{};
+
 } // namespace ranges
 
   using ranges::get;
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 44a4df8b5d5..53093a3762f 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -6676,6 +6676,199 @@ namespace views::__adaptor
 
 inline constexpr _Slide slide;
   }
+
+  template, iterator_t<_Vp>> _Pred>
+requires view<_Vp> && is_object_v<_Pred>
+  class chunk_by_view : public view_interface>
+  {
+_Vp _M_base = _Vp();
+__detail::__box<_Pred> _M_pred = _Pred();
+__detail::_CachedPosition<_Vp> _M_cached_begin;
+
+constexpr iterator_t<_Vp>
+_M_find_next(iterator_t<_Vp> __current)
+{
+  __glibcxx_assert(_M_pred.has_value());
+  auto __pred = [this](_Tp&& __x, _Tp&& __y) {
+   return !bool((*_M_pred)(std::forward<_Tp>(__x), 
std::forward<_Tp>(__y)));
+  };
+  auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), 
__pred);
+  return ranges::next(__it, 1, ranges::end(_M_base));
+}
+
+constexpr iterator_t<_Vp>
+_M_find_prev(iterat

[PATCH 10/15 V2] arm: Implement cortex-M return signing address codegen

2022-09-14 Thread Andrea Corallo via Gcc-patches
Hi all,

this patch enables address return signature and verification based on
Armv8.1-M Pointer Authentication [1].

To sign the return address, we use the PAC R12, LR, SP instruction
upon function entry.  This is signing LR using SP and storing the
result in R12.  R12 will be pushed into the stack.

During function epilogue R12 will be popped and AUT R12, LR, SP will
be used to verify that the content of LR is still valid before return.

Here an example of PAC instrumented function prologue and epilogue:

void foo (void);

int main()
{
  foo ();
  return 0;
}

Compiled with '-march=armv8.1-m.main -mbranch-protection=pac-ret
-mthumb' translates into:

main:
pac ip, lr, sp
push{r3, r7, ip, lr}
add r7, sp, #0
bl  foo
movsr3, #0
mov r0, r3
pop {r3, r7, ip, lr}
aut ip, lr, sp
bx  lr

The patch also takes care of generating a PACBTI instruction in place
of the sequence BTI+PAC when Branch Target Identification is enabled
contextually.

Ex. the previous example compiled with '-march=armv8.1-m.main
-mbranch-protection=pac-ret+bti -mthumb' translates into:

main:
pacbti  ip, lr, sp
push{r3, r7, ip, lr}
add r7, sp, #0
bl  foo
movsr3, #0
mov r0, r3
pop {r3, r7, ip, lr}
aut ip, lr, sp
bx  lr

As part of previous upstream suggestions a test for varargs has been
added and '-mtpcs-frame' is deemed being incompatible with this return
signing address feature being introduced.

[1] 


gcc/Changelog

2021-11-03  Andrea Corallo  

* config/arm/arm.c: (arm_compute_frame_layout)
(arm_expand_prologue, thumb2_expand_return, arm_expand_epilogue)
(arm_conditional_register_usage): Update for pac codegen.
(arm_current_function_pac_enabled_p): New function.
* config/arm/arm.md (pac_ip_lr_sp, pacbti_ip_lr_sp, aut_ip_lr_sp):
Add new patterns.
* config/arm/unspecs.md (UNSPEC_PAC_IP_LR_SP)
(UNSPEC_PACBTI_IP_LR_SP, UNSPEC_AUT_IP_LR_SP): Add unspecs.

gcc/testsuite/Changelog

2021-11-03  Andrea Corallo  

* gcc.target/arm/pac.h : New file.
* gcc.target/arm/pac-1.c : New test case.
* gcc.target/arm/pac-2.c : Likewise.
* gcc.target/arm/pac-3.c : Likewise.
* gcc.target/arm/pac-4.c : Likewise.
* gcc.target/arm/pac-5.c : Likewise.
* gcc.target/arm/pac-6.c : Likewise.
* gcc.target/arm/pac-7.c : Likewise.
* gcc.target/arm/pac-8.c : Likewise.

diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index cff7ff1da2a..84764bf27ce 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -379,6 +379,7 @@ extern int vfp3_const_double_for_bits (rtx);
 extern void arm_emit_coreregs_64bit_shift (enum rtx_code, rtx, rtx, rtx, rtx,
   rtx);
 extern bool arm_fusion_enabled_p (tune_params::fuse_ops);
+extern bool arm_current_function_pac_enabled_p (void);
 extern bool arm_valid_symbolic_address_p (rtx);
 extern bool arm_validize_comparison (rtx *, rtx *, rtx *);
 extern bool arm_expand_vector_compare (rtx, rtx_code, rtx, rtx, bool);
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index a5cf4225aa2..0ba9c0b9960 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -3209,6 +3209,9 @@ arm_option_override_internal (struct gcc_options *opts,
   arm_stack_protector_guard_offset = offs;
 }
 
+  if (arm_current_function_pac_enabled_p () && !(arm_arch7 && arm_arch_cmse))
+error ("This architecture does not support branch protection 
instructions");
+
 #ifdef SUBTARGET_OVERRIDE_INTERNAL_OPTIONS
   SUBTARGET_OVERRIDE_INTERNAL_OPTIONS;
 #endif
@@ -21139,6 +21142,9 @@ arm_compute_save_core_reg_mask (void)
 
   save_reg_mask |= arm_compute_save_reg0_reg12_mask ();
 
+  if (arm_current_function_pac_enabled_p ())
+save_reg_mask |= 1 << IP_REGNUM;
+
   /* Decide if we need to save the link register.
  Interrupt routines have their own banked link register,
  so they never need to save it.
@@ -23362,6 +23368,12 @@ output_probe_stack_range (rtx reg1, rtx reg2)
   return "";
 }
 
+static bool
+aarch_bti_enabled ()
+{
+  return false;
+}
+
 /* Generate the prologue instructions for entry into an ARM or Thumb-2
function.  */
 void
@@ -23440,12 +23452,13 @@ arm_expand_prologue (void)
 
   /* The static chain register is the same as the IP register.  If it is
  clobbered when creating the frame, we need to save and restore it.  */
-  clobber_ip = IS_NESTED (func_type)
-  && ((TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM)
-  || ((flag_stack_check == STATIC_BUILTIN_STACK_CHECK
-   || flag_stack_

Re: [PATCH v3 11/11] FYI/unfinished: OpenMP 5.0 "declare mapper" support for C++

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 13, 2022 at 02:04:30PM -0700, Julian Brown wrote:
> This patch implements OpenMP 5.0 "declare mapper" support for C++.
> This hasn't been fully revised yet following previous review comments,
> but I am including it in this series to demonstrate the new approach to
> gimplifying map clauses after "declare mapper" instantiation.
> 
> The "gimplify_scan_omp_clauses" function is still called twice: firstly
> (before scanning the offload region's body) with SUPPRESS_GIMPLIFICATION
> set to true.  This sets up variables in the splay tree, etc. but does
> not gimplify anything.
> 
> Then, implicit "declare mappers" are instantiated after scanning the
> region's body, then "gimplify_scan_omp_clauses" is called again, and
> does the rest of its previous tasks -- builds struct sibling lists,
> and gimplifies clauses. Then gimplify_adjust_omp_clauses is called,
> and compilation continues.
> 
> Does this approach seem OK?

As I wrote in https://gcc.gnu.org/pipermail/gcc-patches/2022-June/596444.html
I don't see a reason for this 3 passes approach and it will be a
maintainance problem.
The reason why we have 2 passes approach is that we need to populate the
splay trees based on explicit clauses before we gimplify the body, at which
point we can look up for variables seen in the body those splay trees,
either mark the explicit ones as seen or create new ones for implicit
etc.  And finally we need to adjust some explicit clauses based on that
(that is what the main loop in gimplify_adjust_omp_clauses does) and
add new clauses for implicit data sharing or mapping (that is done
through splay tree traversal through gimplify_adjust_omp_clauses_1).

We also need to gimplify expressions from the clauses somewhere, but
due to the way the gimplifier works we don't care that much when
exactly it is done, it can be done before the body is gimplified
(for most clauses we do it there in gimplify_scan_omp_clauses), it can be
done after the body is gimplified, the expressions from the clauses
will be in either case gimplified into some gimple sequence that we'll
place before the construct with its body.  The only reason to have
the gimplification done before and not after would be if the temporaries
from the gimplification are then needed in the splay trees for the
gimplification of the body.

I'd strongly prefer if the gimplification APIs for all the constructs
were just gimplify_scan_omp_clauses before processing the body and
gimplify_adjust_omp_clauses after doing so, not some extra APIs.
If there is a strong reason for 3 or more passes on say a subset of clauses,
either gimplify_scan_omp_clauses or gimplify_adjust_omp_clauses can do more
than one loop over the clauses, but those secondary loops ideally should be
enabled only when needed (e.g. see the gimplify_adjust_omp_clauses
has_inscan_reductions guarded loop at the end) and should only process
clauses they strictly have to.

Conceptually, there is no reason why e.g. the gimplification of the explicit
map clauses can't be done in gimplify_adjust_omp_clauses rather than in
gimplify_scan_omp_clauses.  What needs to happen in gimplify_scan_omp_clauses
is just what affects the gimplification of the body.  Does sorting of the
map clause affect it?  I don't think so.  Does declare mapper processing of
the explicit map clauses affect it?  I very much hope it doesn't, but I'm
afraid I don't remember all the declare mapper restrictions and discussions.
Can declare mapper e.g. try to map an unrelated variable in addition to say
parts of the structure?  If yes, then it could affect the gimplification of
the body, say
struct S { int s, t; };
extern int y;
#pragma omp declare mapper (struct S s) map (to: s.s) map (to: y)
#pragma omp target defaultmap(none:scalar) map(tofrom: x)
{
  int x = s.s + y;
}
because if we do process declare mapper before the gimplification of the
body, then y would be explicitly mapped, but if we don't, it wouldn't and
it should be rejected.  But in that case we'd be in big trouble with
implicit mappings using that same declare mapper.  Because it would then be
significant in which order we process the vars during gimplification of the
body and whether we process declare mapper right away at that point or only
at the end etc.
We have the
"List items in map clauses on the declare mapper directive may only refer to 
the declared
variable var and entities that could be referenced by a procedure defined at 
the same
location."
restriction but not sure that says the above isn't valid.
So probably it needs to be discussed in omp-lang.

If the agreement is that declare mapper for explicit map clauses needs to be
done before processing the body and declare mapper for implicit map clauses
can be deferred to the end, then yes, we need to handle declare mapper
twice, but it can be done say in a secondary loop of gimplify_scan_omp_clauses
guarded on at least one of the map clauses needs declare mapper processing
or something similar that can be quickly determined

[COMMITTED] frange: add both zeros to ranges when there's the possiblity of equality.

2022-09-14 Thread Aldy Hernandez via Gcc-patches
Every time there's equality at play, we must be careful that any
equality with zero matches both -0.0 and +0.0 when honoring signed
zeros.

We were doing this correctly for the == and != op1_range operators
(albeit inefficiently), but aren't doing it at all when building >=
and <=.  This fixes the oversight.

There is change in functionality here for the build_* functions.

This is the last "simple" patch I submit before overhauling NAN and
sign tracking.  And that will likely be after Cauldron because it will need
further testing (lapack, ppc64le, -ffinite-math-only, etc).

Regstrapped on x86-64 Linux, plus I ran selftests for
-ffinite-math-only.

gcc/ChangeLog:

* range-op-float.cc (frange_add_zeros): New.
(build_le): Call frange_add_zeros.
(build_ge): Same.
(foperator_equal::op1_range): Same.
(foperator_not_equal::op1_range): Same.
---
 gcc/range-op-float.cc | 31 +--
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 8f3e5241313..fbc14a730ad 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -208,6 +208,19 @@ frange_drop_ninf (frange &r, tree type)
   r.intersect (tmp);
 }
 
+// If zero is in R, make sure both -0.0 and +0.0 are in the range.
+
+static inline void
+frange_add_zeros (frange &r, tree type)
+{
+  if (r.undefined_p () || r.known_nan ())
+return;
+
+  if (HONOR_SIGNED_ZEROS (type)
+  && (real_iszero (&r.lower_bound ()) || real_iszero (&r.upper_bound (
+r.set_signbit (fp_prop::VARYING);
+}
+
 // Build a range that is <= VAL and store it in R.
 
 static bool
@@ -219,6 +232,10 @@ build_le (frange &r, tree type, const frange &val)
   return false;
 }
   r.set (type, dconstninf, val.upper_bound ());
+
+  // Add both zeros if there's the possibility of zero equality.
+  frange_add_zeros (r, type);
+
   return true;
 }
 
@@ -257,6 +274,10 @@ build_ge (frange &r, tree type, const frange &val)
   return false;
 }
   r.set (type, val.lower_bound (), dconstinf);
+
+  // Add both zeros if there's the possibility of zero equality.
+  frange_add_zeros (r, type);
+
   return true;
 }
 
@@ -376,9 +397,8 @@ foperator_equal::op1_range (frange &r, tree type,
 case BRS_TRUE:
   // If it's true, the result is the same as OP2.
   r = op2;
-  // Make sure we don't copy the sign bit if we may have a zero.
-  if (HONOR_SIGNED_ZEROS (type) && r.contains_p (build_zero_cst (type)))
-   r.set_signbit (fp_prop::VARYING);
+  // Add both zeros if there's the possibility of zero equality.
+  frange_add_zeros (r, type);
   // The TRUE side of op1 == op2 implies op1 is !NAN.
   r.clear_nan ();
   break;
@@ -480,9 +500,8 @@ foperator_not_equal::op1_range (frange &r, tree type,
 case BRS_FALSE:
   // If it's false, the result is the same as OP2.
   r = op2;
-  // Make sure we don't copy the sign bit if we may have a zero.
-  if (HONOR_SIGNED_ZEROS (type) && r.contains_p (build_zero_cst (type)))
-   r.set_signbit (fp_prop::VARYING);
+  // Add both zeros if there's the possibility of zero equality.
+  frange_add_zeros (r, type);
   // The FALSE side of op1 != op2 implies op1 is !NAN.
   r.clear_nan ();
   break;
-- 
2.37.1



[COMMITTED] Use frange::set_nan() from the generic frange::set().

2022-09-14 Thread Aldy Hernandez via Gcc-patches
This patch cleans up the frange::set() code by passing all things NAN
to frange::set_nan().

No functional changes.

Regstrapped on x86-64 Linux, plus I ran selftests for
-ffinite-math-only.

gcc/ChangeLog:

* value-range.cc (frange::set): Use set_nan.
* value-range.h (frange::set_nan): Inline code originally in
set().
---
 gcc/value-range.cc | 27 ++-
 gcc/value-range.h  |  9 -
 2 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index dd827421aca..d759fcf178c 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -369,32 +369,33 @@ frange::set (tree min, tree max, value_range_kind kind)
   return;
 }
 
+  // Handle NANs.
+  if (real_isnan (TREE_REAL_CST_PTR (min)) || real_isnan (TREE_REAL_CST_PTR 
(max)))
+{
+  gcc_checking_assert (real_identical (TREE_REAL_CST_PTR (min),
+  TREE_REAL_CST_PTR (max)));
+  tree type = TREE_TYPE (min);
+  set_nan (type);
+  return;
+}
+
   m_kind = kind;
   m_type = TREE_TYPE (min);
   m_props.set_varying ();
   m_min = *TREE_REAL_CST_PTR (min);
   m_max = *TREE_REAL_CST_PTR (max);
 
-  bool is_nan = (real_isnan (TREE_REAL_CST_PTR (min))
-|| real_isnan (TREE_REAL_CST_PTR (max)));
-
-  // Ranges with a NAN and a non-NAN endpoint are nonsensical.
-  gcc_checking_assert (!is_nan || operand_equal_p (min, max));
-
-  // Set NAN property if we're absolutely sure.
-  if (is_nan && operand_equal_p (min, max))
-m_props.nan_set_yes ();
-  else if (!HONOR_NANS (m_type))
-m_props.nan_set_no ();
-
   // Set SIGNBIT property for positive and negative ranges.
   if (real_less (&m_max, &dconst0))
 m_props.signbit_set_yes ();
   else if (real_less (&dconst0, &m_min))
 m_props.signbit_set_no ();
 
+  if (!HONOR_NANS (m_type))
+m_props.nan_set_no ();
+
   // Check for swapped ranges.
-  gcc_checking_assert (is_nan || tree_compare (LE_EXPR, min, max));
+  gcc_checking_assert (tree_compare (LE_EXPR, min, max));
 
   normalize_kind ();
   if (flag_checking)
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 6e896eb9ab5..4392de84c8b 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -1193,7 +1193,14 @@ frange::set_nan (tree type)
 {
   REAL_VALUE_TYPE r;
   gcc_assert (real_nan (&r, "", 1, TYPE_MODE (type)));
-  set (type, r, r);
+  m_kind = VR_RANGE;
+  m_type = type;
+  m_min = r;
+  m_max = r;
+  m_props.set_varying ();
+  m_props.nan_set_yes ();
+  if (flag_checking)
+verify_range ();
 }
 
 // Return TRUE if range is known to be finite.
-- 
2.37.1



[COMMITTED] Pass full range to build_* in range-op-float.cc

2022-09-14 Thread Aldy Hernandez via Gcc-patches
The build_ helper functions in range-op-float.cc take the
actual value from the operand's endpoint, but this value could be
deduced from the operand itself therefore cleaning up the call site.
This also reduces the potential of mistakenly passing the wrong bound.

No functional changes.

Regstrapped on x86-64 Linux, plus I ran selftests for
-ffinite-math-only.

gcc/ChangeLog:

* range-op-float.cc (build_le): Accept frange instead of number.
(build_lt): Same.
(build_ge): Same.
(build_gt): Same.
(foperator_lt::op1_range): Pass full range to build_*.
(foperator_lt::op2_range): Same.
(foperator_le::op1_range): Same.
(foperator_le::op2_range): Same.
(foperator_gt::op1_range): Same.
(foperator_gt::op2_range): Same.
(foperator_ge::op1_range): Same.
(foperator_ge::op2_range): Same.
---
 gcc/range-op-float.cc | 72 +--
 1 file changed, 36 insertions(+), 36 deletions(-)

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index f979ca597cb..8f3e5241313 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -208,32 +208,32 @@ frange_drop_ninf (frange &r, tree type)
   r.intersect (tmp);
 }
 
-// (X <= VAL) produces the range of [-INF, VAL].
+// Build a range that is <= VAL and store it in R.
 
 static bool
-build_le (frange &r, tree type, const REAL_VALUE_TYPE &val)
+build_le (frange &r, tree type, const frange &val)
 {
-  if (real_isnan (&val))
+  if (val.known_nan ())
 {
   r.set_undefined ();
   return false;
 }
-  r.set (type, dconstninf, val);
+  r.set (type, dconstninf, val.upper_bound ());
   return true;
 }
 
-// (X < VAL) produces the range of [-INF, VAL).
+// Build a range that is < VAL and store it in R.
 
 static bool
-build_lt (frange &r, tree type, const REAL_VALUE_TYPE &val)
+build_lt (frange &r, tree type, const frange &val)
 {
-  if (real_isnan (&val))
+  if (val.known_nan ())
 {
   r.set_undefined ();
   return false;
 }
   // < -INF is outside the range.
-  if (real_isinf (&val, 1))
+  if (real_isinf (&val.upper_bound (), 1))
 {
   if (HONOR_NANS (type))
r.set_nan (type);
@@ -241,37 +241,37 @@ build_lt (frange &r, tree type, const REAL_VALUE_TYPE 
&val)
r.set_undefined ();
   return false;
 }
-  // Hijack LE because we only support closed intervals.
-  build_le (r, type, val);
+  // We only support closed intervals.
+  r.set (type, dconstninf, val.upper_bound ());
   return true;
 }
 
-// (X >= VAL) produces the range of [VAL, +INF].
+// Build a range that is >= VAL and store it in R.
 
 static bool
-build_ge (frange &r, tree type, const REAL_VALUE_TYPE &val)
+build_ge (frange &r, tree type, const frange &val)
 {
-  if (real_isnan (&val))
+  if (val.known_nan ())
 {
   r.set_undefined ();
   return false;
 }
-  r.set (type, val, dconstinf);
+  r.set (type, val.lower_bound (), dconstinf);
   return true;
 }
 
-// (X > VAL) produces the range of (VAL, +INF].
+// Build a range that is > VAL and store it in R.
 
 static bool
-build_gt (frange &r, tree type, const REAL_VALUE_TYPE &val)
+build_gt (frange &r, tree type, const frange &val)
 {
-  if (real_isnan (&val))
+  if (val.known_nan ())
 {
   r.set_undefined ();
   return false;
 }
   // > +INF is outside the range.
-  if (real_isinf (&val, 0))
+  if (real_isinf (&val.lower_bound (), 0))
 {
   if (HONOR_NANS (type))
r.set_nan (type);
@@ -280,8 +280,8 @@ build_gt (frange &r, tree type, const REAL_VALUE_TYPE &val)
   return false;
 }
 
-  // Hijack GE because we only support closed intervals.
-  build_ge (r, type, val);
+  // We only support closed intervals.
+  r.set (type, val.lower_bound (), dconstinf);
   return true;
 }
 
@@ -549,7 +549,7 @@ foperator_lt::op1_range (frange &r,
   switch (get_bool_state (r, lhs, type))
 {
 case BRS_TRUE:
-  if (build_lt (r, type, op2.upper_bound ()))
+  if (build_lt (r, type, op2))
{
  r.clear_nan ();
  // x < y implies x is not +INF.
@@ -558,7 +558,7 @@ foperator_lt::op1_range (frange &r,
   break;
 
 case BRS_FALSE:
-  build_ge (r, type, op2.lower_bound ());
+  build_ge (r, type, op2);
   break;
 
 default:
@@ -577,7 +577,7 @@ foperator_lt::op2_range (frange &r,
   switch (get_bool_state (r, lhs, type))
 {
 case BRS_TRUE:
-  if (build_gt (r, type, op1.lower_bound ()))
+  if (build_gt (r, type, op1))
{
  r.clear_nan ();
  // x < y implies y is not -INF.
@@ -586,7 +586,7 @@ foperator_lt::op2_range (frange &r,
   break;
 
 case BRS_FALSE:
-  build_le (r, type, op1.upper_bound ());
+  build_le (r, type, op1);
   break;
 
 default:
@@ -651,12 +651,12 @@ foperator_le::op1_range (frange &r,
   switch (get_bool_state (r, lhs, type))
 {
 case BRS_TRUE:
-  if (build_le (r, type, op2.upper_bound ()))
+  if (build_l

[COMMITTED] Provide cleaner set_nan(), clear_nan(), and update_nan() methods.

2022-09-14 Thread Aldy Hernandez via Gcc-patches
set_* has a very specific meaning for irange's and friends.  Methods
prefixed with set_* are setters clobbering the existing range.  As
such, the current set_nan() method is confusing in that it's not
actually setting a range to a NAN, but twiddling the NAN flags for an
existing frange.

This patch replaces set_nan() with an update_nan() to set the flag,
and clear_nan() to clear it.  This makes the code clearer, and though
the confusing tristate is still there, it will be removed in upcoming
patches.

Also, there is now an actual set_nan() method to set the range to a
NAN.  This replaces two out of class functions doing the same thing.
In future patches I will also add the ability to create a NAN with a
specific sign, but doing so now would be confusing because we're not
tracking NAN signs.

We should also submit set_signbit to the same fate, but it's about to
get removed.

No functional changes.

Regstrapped on x86-64 Linux, plus I ran selftests for
-ffinite-math-only.

gcc/ChangeLog:

* range-op-float.cc (frange_set_nan): Remove.
(build_lt): Use set_nan, update_nan, clear_nan.
(build_gt): Same.
(foperator_equal::op1_range): Same.
(foperator_not_equal::op1_range): Same.
(foperator_lt::op1_range): Same.
(foperator_lt::op2_range): Same.
(foperator_le::op1_range): Same.
(foperator_le::op2_range): Same.
(foperator_gt::op1_range): Same.
(foperator_gt::op2_range): Same.
(foperator_ge::op1_range): Same.
(foperator_ge::op2_range): Same.
(foperator_unordered::op1_range): Same.
(foperator_ordered::op1_range): Same.
* value-query.cc (range_query::get_tree_range): Same.
* value-range.cc (frange::set_nan): Same.
(frange::update_nan): Same.
(frange::union_): Same.
(frange::intersect): Same.
(range_tests_nan): Same.
(range_tests_signed_zeros): Same.
(range_tests_signbit): Same.
(range_tests_floats): Same.
* value-range.h (class frange): Add update_nan and clear_nan.
(frange::set_nan): New.
---
 gcc/range-op-float.cc | 46 ++
 gcc/value-query.cc|  4 ++--
 gcc/value-range.cc| 52 +--
 gcc/value-range.h | 11 -
 4 files changed, 51 insertions(+), 62 deletions(-)

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 0f928b6c098..f979ca597cb 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -150,18 +150,6 @@ range_operator_float::op1_op2_relation (const irange &lhs 
ATTRIBUTE_UNUSED) cons
   return VREL_VARYING;
 }
 
-// Set R to [NAN, NAN].
-
-static inline void
-frange_set_nan (frange &r, tree type)
-{
-  REAL_VALUE_TYPE rv;
-  bool res = real_nan (&rv, "", 1, TYPE_MODE (type));
-  if (flag_checking)
-gcc_assert (res);
-  r.set (type, rv, rv);
-}
-
 // Return TRUE if OP1 is known to be free of NANs.
 
 static inline bool
@@ -248,7 +236,7 @@ build_lt (frange &r, tree type, const REAL_VALUE_TYPE &val)
   if (real_isinf (&val, 1))
 {
   if (HONOR_NANS (type))
-   frange_set_nan (r, type);
+   r.set_nan (type);
   else
r.set_undefined ();
   return false;
@@ -286,7 +274,7 @@ build_gt (frange &r, tree type, const REAL_VALUE_TYPE &val)
   if (real_isinf (&val, 0))
 {
   if (HONOR_NANS (type))
-   frange_set_nan (r, type);
+   r.set_nan (type);
   else
r.set_undefined ();
   return false;
@@ -392,14 +380,14 @@ foperator_equal::op1_range (frange &r, tree type,
   if (HONOR_SIGNED_ZEROS (type) && r.contains_p (build_zero_cst (type)))
r.set_signbit (fp_prop::VARYING);
   // The TRUE side of op1 == op2 implies op1 is !NAN.
-  r.set_nan (fp_prop::NO);
+  r.clear_nan ();
   break;
 
 case BRS_FALSE:
   r.set_varying (type);
   // The FALSE side of op1 == op1 implies op1 is a NAN.
   if (rel == VREL_EQ)
-   frange_set_nan (r, type);
+   r.set_nan (type);
   // If the result is false, the only time we know anything is
   // if OP2 is a constant.
   else if (op2.singleton_p ()
@@ -496,7 +484,7 @@ foperator_not_equal::op1_range (frange &r, tree type,
   if (HONOR_SIGNED_ZEROS (type) && r.contains_p (build_zero_cst (type)))
r.set_signbit (fp_prop::VARYING);
   // The FALSE side of op1 != op2 implies op1 is !NAN.
-  r.set_nan (fp_prop::NO);
+  r.clear_nan ();
   break;
 
 default:
@@ -563,7 +551,7 @@ foperator_lt::op1_range (frange &r,
 case BRS_TRUE:
   if (build_lt (r, type, op2.upper_bound ()))
{
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
  // x < y implies x is not +INF.
  frange_drop_inf (r, type);
}
@@ -591,7 +579,7 @@ foperator_lt::op2_range (frange &r,
 case BRS_TRUE:
   if (build_gt (r, type, op1.lower_bound ()))
{
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
 

[COMMITTED] Minor fixes to frange.

2022-09-14 Thread Aldy Hernandez via Gcc-patches
Following are a series of cleanups to the frange code in preparation
for a much more invasive patch rewriting the NAN and sign tracking
bits.  Please be patient, as I'm trying to break everything up into
small chunks instead of dropping a mondo patch removing the NAN and
sign tristate handling.

No functional changes.

Regstrapped on x86-64 Linux, plus I ran selftests for
-ffinite-math-only.

gcc/ChangeLog:

* value-query.cc (range_query::get_tree_range): Remove check for 
overflow.
* value-range-pretty-print.cc (vrange_printer::visit): Move read
of type until after undefined_p is checked.
* value-range.cc (frange::set): Remove asserts for REAL_CST.
(frange::contains_p): Tidy up.
(range_tests_nan):  Add comment.
* value-range.h (frange::type): Check for undefined_p.
(frange::set_undefined): Remove set of endpoints.
---
 gcc/value-query.cc  |  3 ---
 gcc/value-range-pretty-print.cc |  3 +--
 gcc/value-range.cc  | 15 +--
 gcc/value-range.h   |  3 +--
 4 files changed, 7 insertions(+), 17 deletions(-)

diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index ad80db780c2..de83f469be4 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -217,9 +217,6 @@ range_query::get_tree_range (vrange &r, tree expr, gimple 
*stmt)
 
 case REAL_CST:
   {
-   if (TREE_OVERFLOW_P (expr))
- expr = drop_tree_overflow (expr);
-
frange &f = as_a  (r);
f.set (expr, expr);
 
diff --git a/gcc/value-range-pretty-print.cc b/gcc/value-range-pretty-print.cc
index 93e18d3c1b6..b124e46cb9e 100644
--- a/gcc/value-range-pretty-print.cc
+++ b/gcc/value-range-pretty-print.cc
@@ -122,14 +122,13 @@ vrange_printer::print_irange_bitmasks (const irange &r) 
const
 void
 vrange_printer::visit (const frange &r) const
 {
-  tree type = r.type ();
-
   pp_string (pp, "[frange] ");
   if (r.undefined_p ())
 {
   pp_string (pp, "UNDEFINED");
   return;
 }
+  tree type = r.type ();
   dump_generic_node (pp, type, 0, TDF_NONE, false);
   pp_string (pp, " ");
   if (r.varying_p ())
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 6f0609959b3..d40a4ebf657 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -357,15 +357,11 @@ frange::set_signbit (fp_prop::kind k)
 void
 frange::set (tree min, tree max, value_range_kind kind)
 {
-  gcc_checking_assert (TREE_CODE (min) == REAL_CST);
-  gcc_checking_assert (TREE_CODE (max) == REAL_CST);
-
   if (kind == VR_UNDEFINED)
 {
   set_undefined ();
   return;
 }
-
   // Treat VR_ANTI_RANGE and VR_VARYING as varying.
   if (kind != VR_RANGE)
 {
@@ -401,7 +397,6 @@ frange::set (tree min, tree max, value_range_kind kind)
   gcc_checking_assert (is_nan || tree_compare (LE_EXPR, min, max));
 
   normalize_kind ();
-
   if (flag_checking)
 verify_range ();
 }
@@ -612,17 +607,17 @@ frange::operator== (const frange &src) const
 bool
 frange::contains_p (tree cst) const
 {
+  gcc_checking_assert (m_kind != VR_ANTI_RANGE);
+  const REAL_VALUE_TYPE *rv = TREE_REAL_CST_PTR (cst);
+
   if (undefined_p ())
 return false;
 
   if (varying_p ())
 return true;
 
-  gcc_checking_assert (m_kind == VR_RANGE);
 
-  const REAL_VALUE_TYPE *rv = TREE_REAL_CST_PTR (cst);
-  if (real_compare (GE_EXPR, rv, &m_min)
-  && real_compare (LE_EXPR, rv, &m_max))
+  if (real_compare (GE_EXPR, rv, &m_min) && real_compare (LE_EXPR, rv, &m_max))
 {
   if (HONOR_SIGNED_ZEROS (m_type) && real_iszero (rv))
{
@@ -3652,7 +3647,7 @@ range_tests_nan ()
   ASSERT_FALSE (r0 == r0);
   ASSERT_TRUE (r0 != r0);
 
-  // [5,6] U NAN.
+  // [5,6] U NAN = [5,6] NAN.
   r0 = frange_float ("5", "6");
   r0.set_nan (fp_prop::NO);
   r1 = frange_nan (float_type_node);
diff --git a/gcc/value-range.h b/gcc/value-range.h
index f9a01ee7a05..0ba0193bc1f 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -1141,6 +1141,7 @@ frange::frange (tree min, tree max, value_range_kind kind)
 inline tree
 frange::type () const
 {
+  gcc_checking_assert (!undefined_p ());
   return m_type;
 }
 
@@ -1160,8 +1161,6 @@ frange::set_undefined ()
   m_kind = VR_UNDEFINED;
   m_type = NULL;
   m_props.set_undefined ();
-  memset (&m_min, 0, sizeof (m_min));
-  memset (&m_max, 0, sizeof (m_max));
 }
 
 // Set R to maximum representable value for TYPE.
-- 
2.37.1



Re: [PATCH Rust front-end v2 34/37] gccrs: add lang.opt

2022-09-14 Thread Thomas Schwinge
Hi!

On 2022-09-14T15:39:47+0200, Richard Biener via Gcc-patches 
 wrote:
> On Wed, Aug 24, 2022 at 2:13 PM  wrote:
>>
>> From: Philip Herron 
>>
>> We have some rust specific langugage options note -fwrapv is enabled by
>> default in the code. We are trying to respect options such as
>> -Wunused-result which we get by porting over c++ no-discard for rust's
>> must-use attribute, so we have enabled these by default directly here.
>
> LGTM

Actually, NACK.  ;-)

See 
"gccrs setting warn_unused_variable breaks thousands of non-Rust tests".
The 'Init(1)' in 'gcc/rust/lang.opt' are in conflict with any (default)
'Init(0)' in other '*.opt' files -- remember that all '*.opt' files are
processed together by GCC's "options machinery", and thus
'gcc/rust/lang.opt' may (and here, does) affect non-Rust front end code.

I do have a patch series adding a 'LangInit(@var{language}, @var{value})'
option property, and patches to use this in a lot of places (here and in
other front ends' '*.opt' files), where currently we implement such logic
in '*.cc' files; '[...]_init_options_struct' functions via
'LANG_HOOKS_INIT_OPTIONS_STRUCT' (those then largely become empty and may
be removed).  I assume this idea to be uncontroversial; I "just" need to
get it polished and submitted...


Grüße
 Thomas


>>  gcc/rust/lang.opt | 118 ++
>>  1 file changed, 118 insertions(+)
>>  create mode 100644 gcc/rust/lang.opt
>>
>> diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
>> new file mode 100644
>> index 000..1f6855ede1d
>> --- /dev/null
>> +++ b/gcc/rust/lang.opt
>> @@ -0,0 +1,118 @@
>> +; Options for the Rust front end.
>> +; Copyright (C) 2003-2022 Free Software Foundation, Inc.
>> +;
>> +; This file is part of GCC.
>> +;
>> +; GCC is free software; you can redistribute it and/or modify it under
>> +; the terms of the GNU General Public License as published by the Free
>> +; Software Foundation; either version 3, or (at your option) any later
>> +; version.
>> +;
>> +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>> +; WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> +; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>> +; for more details.
>> +;
>> +; You should have received a copy of the GNU General Public License
>> +; along with GCC; see the file COPYING3.  If not see
>> +; .
>> +
>> +; See the GCC internals manual for a description of this file's format.
>> +
>> +; Please try to keep this file in ASCII collating order.
>> +
>> +; Describes command-line options used by this frontend
>> +
>> +Language
>> +Rust
>> +
>> +I
>> +Rust Joined Separate
>> +; Documented in c.opt
>> +
>> +L
>> +Rust Joined Separate
>> +; Not documented
>> +
>> +Wall
>> +Rust
>> +; Documented in c.opt
>> +
>> +Wunused-variable
>> +Rust Var(warn_unused_variable) Init(1) Warning
>> +; documented in common.opt
>> +
>> +Wunused-const-variable
>> +Rust Warning Alias(Wunused-const-variable=, 2, 0)
>> +Warn when a const variable is unused.
>> +
>> +Wunused-const-variable=
>> +Rust Joined RejectNegative UInteger Var(warn_unused_const_variable) Init(1) 
>> Warning LangEnabledBy(Rust,Wunused-variable, 1, 0) IntegerRange(0, 2)
>> +Warn when a const variable is unused.
>> +
>> +Wunused-result
>> +Rust Var(warn_unused_result) Init(1) Warning
>> +Warn if a caller of a function, marked with attribute warn_unused_result, 
>> does not use its return value.
>> +
>> +frust-crate=
>> +Rust Joined RejectNegative
>> +-frust-crate= Set the crate name for the compilation
>> +
>> +frust-debug
>> +Rust Var(flag_rust_debug)
>> +Dump various Rust front end internals.
>> +
>> +frust-dump-
>> +Rust Joined RejectNegative
>> +-frust-dump- Dump Rust frontend internal information.
>> +
>> +frust-max-recursion-depth=
>> +Rust RejectNegative Type(int) Var(rust_max_recursion_depth) Init(64)
>> +-frust-max-recursion-depth=integer
>> +
>> +frust-mangling=
>> +Rust Joined RejectNegative Enum(frust_mangling) Var(flag_rust_mangling)
>> +-frust-mangling=[legacy|v0] Choose which version to use for name 
>> mangling
>> +
>> +Enum
>> +Name(frust_mangling) Type(int) UnknownError(unknown rust mangling option 
>> %qs)
>> +
>> +EnumValue
>> +Enum(frust_mangling) String(legacy) Value(0)
>> +
>> +EnumValue
>> +Enum(frust_mangling) String(v0) Value(1)
>> +
>> +frust-cfg=
>> +Rust Joined RejectNegative
>> +-frust-cfg= Set a config expansion option
>> +
>> +frust-edition=
>> +Rust Joined RejectNegative Enum(frust_edition) Var(flag_rust_edition)
>> +-frust-edition=[2015|2018|2021] Choose which edition to use 
>> when compiling rust code
>> +
>> +Enum
>> +Name(frust_edition) Type(int) UnknownError(unknown rust edition %qs)
>> +
>> +EnumValue
>> +Enum(frust_edition) String(2015) Value(0)
>> +
>> +EnumValue
>> +Enum(frust_edition) String(2018) Value(1)
>> +
>> +EnumValue
>> +Enum(frust_edition) 

Re: [PATCH v3 11/11] FYI/unfinished: OpenMP 5.0 "declare mapper" support for C++

2022-09-14 Thread Julian Brown
On Wed, 14 Sep 2022 16:58:28 +0200
Jakub Jelinek  wrote:

> On Tue, Sep 13, 2022 at 02:04:30PM -0700, Julian Brown wrote:
> > This patch implements OpenMP 5.0 "declare mapper" support for C++.
> > This hasn't been fully revised yet following previous review
> > comments, but I am including it in this series to demonstrate the
> > new approach to gimplifying map clauses after "declare mapper"
> > instantiation.
> > 
> > The "gimplify_scan_omp_clauses" function is still called twice:
> > firstly (before scanning the offload region's body) with
> > SUPPRESS_GIMPLIFICATION set to true.  This sets up variables in the
> > splay tree, etc. but does not gimplify anything.
> > 
> > Then, implicit "declare mappers" are instantiated after scanning the
> > region's body, then "gimplify_scan_omp_clauses" is called again, and
> > does the rest of its previous tasks -- builds struct sibling lists,
> > and gimplifies clauses. Then gimplify_adjust_omp_clauses is called,
> > and compilation continues.
> > 
> > Does this approach seem OK?  
> 
> As I wrote in
> https://gcc.gnu.org/pipermail/gcc-patches/2022-June/596444.html I
> don't see a reason for this 3 passes approach and it will be a
> maintainance problem.

Ack. I'll have another go at refactoring those bits when reworking this
patch.

Thanks,

Julian


[PATCH][_GLIBCXX_INLINE_VERSION] Cleanup gnu-versioned-namespace.ver

2022-09-14 Thread François Dumont via Gcc-patches
    libstdc++: [_GLIBCXX_INLINE_VERSION] Cleanup 
gnu-versioned-namespace.ver


    Remove expressions for symbols in std::__detail::__8 namespace, 
they are obsolete since

    version namespace applies only at std:: level, not at sub-levels.

    libstdc++-v3/ChangeLog:

    * config/abi/pre/gnu-versioned-namespace.ver: Remove 
obsolete std::__detail::__8

    symbols.

Tested under Linux x86_64.

Ok to commit ?

François
diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
index b37199ece72..06ccaa80a58 100644
--- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
+++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
@@ -76,20 +76,9 @@ GLIBCXX_8.0 {
 # locale
 _ZNSt3__89has_facetINS_*;
 
-# hash
-_ZNSt8__detail3__812__prime_listE;
-_ZNSt3tr18__detail3__812__prime_listE;
-
 # thread/mutex/condition_variable/future
 __once_proxy;
 
-# std::__detail::_List_node_base
-_ZNSt8__detail3__815_List_node_base7_M_hook*;
-_ZNSt8__detail3__815_List_node_base9_M_unhookEv;
-_ZNSt8__detail3__815_List_node_base10_M_reverseEv;
-_ZNSt8__detail3__815_List_node_base11_M_transfer*;
-_ZNSt8__detail3__815_List_node_base4swapER*;
-
 # std::__convert_to_v
 _ZNSt3__814__convert_to_v*;
 


[PATCH][_GLIBCXX_INLINE_VERSION] Fix test dg-prune-output

2022-09-14 Thread François Dumont via Gcc-patches

    libstdc++: [_GLIBCXX_INLINE_VERSION] Fix test dg-prune-output

    libstdc++-v3/ChangeLog:

    * 
testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc: Adapt 
dg-prune-output to

    _GLIBCXX_INLINE_VERSION mode.


With this patch all tests are Ok in _GLIBCXX_INLINE_VERSION mode (at the 
time I'm writing this).


Ok to commit ?

François
diff --git a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc
index fc0b70b319c..bc66c13feee 100644
--- a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc
@@ -1,6 +1,6 @@
 // { dg-do compile { target c++11 } }
 // { dg-prune-output "must be a complete" }
-// { dg-prune-output "'value' is not a member of 'std::is_move_cons" }
+// { dg-prune-output "'value' is not a member of 'std::(__8::)?is_move_cons" }
 // { dg-prune-output "invalid use of incomplete type" }
 
 // Copyright (C) 2019-2022 Free Software Foundation, Inc.


[PATCH] OpenMP: Enable vectorization in all OpenMP loops

2022-09-14 Thread Sandra Loosemore
GCC presently enables the loop vectorizer at lower optimization levels 
for OpenMP loops with the "simd" specifier than it does for loops 
without it.  The "simd" specifier isn't defined to be purely an 
optimization hint to the compiler; it also has semantic effects like 
changing the privatization of the loop variable.  It seems reasonable to 
decouple the additional vectorization from those semantic effects and 
apply it also to work-sharing loops without the "simd" specifier at the 
same optimization levels.


I've tested this patch on x86_64-linux-gnu-amdgcn, plain 
x86_64-linux-gnu, and aarch64-linux-gnu.  OK for mainline?


-SandraFrom 15c6f6b6bc396f53474ea380f506a7f74d7a05af Mon Sep 17 00:00:00 2001
From: Sandra Loosemore 
Date: Tue, 13 Sep 2022 23:50:27 +
Subject: [PATCH] OpenMP: Enable vectorization in all OpenMP loops

This patch marks all OpenMP worksharing loops (not just those with the
simd descriptor) as candidates for vectorization when -ftree-loop-optimize
is active and loop vectorization is not explicitly disabled with
-fno-tree-loop-vectorize.

gcc/ChangeLog:

	* omp-expand.cc (maybe_auto_vectorize_loop): New.
	(expand_omp_for_generic): Call it.
	(expand_omp_for_static_chunk): Likewise.
	(expand_omp_taskloop_for_inner): Likewise.
	(expand_oacc_for): Likewise.

gcc/testsuite/ChangeLog:
	* c-c++-common/gomp/vectorize-1.c: New.
	* c-c++-common/gomp/vectorize-2.c: New.
	* c-c++-common/gomp/vectorize-3.c: New.
	* c-c++-common/gomp/vectorize-s.c: New.
	* gcc.dg/gomp/pr46032-2.c: Compile with -fno-tree-loop-vectorize.
	* gcc.dg/gomp/pr46032-3.c: Likewise.
---
 gcc/omp-expand.cc | 23 ++
 gcc/testsuite/c-c++-common/gomp/vectorize-1.c | 31 +++
 gcc/testsuite/c-c++-common/gomp/vectorize-2.c | 31 +++
 gcc/testsuite/c-c++-common/gomp/vectorize-3.c | 31 +++
 gcc/testsuite/c-c++-common/gomp/vectorize-s.c | 31 +++
 gcc/testsuite/gcc.dg/gomp/pr46032-2.c |  2 +-
 gcc/testsuite/gcc.dg/gomp/pr46032-3.c |  2 +-
 7 files changed, 149 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/vectorize-1.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/vectorize-2.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/vectorize-3.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/vectorize-s.c

diff --git a/gcc/omp-expand.cc b/gcc/omp-expand.cc
index fcaf4f6d4e9..bc753814102 100644
--- a/gcc/omp-expand.cc
+++ b/gcc/omp-expand.cc
@@ -3711,6 +3711,22 @@ expand_omp_for_ordered_loops (struct omp_for_data *fd, tree *counts,
   return cont_bb;
 }
 
+/* Helper function for various subroutines of expand_omp_for.
+   If not -fno-tree-loop-vectorize and -ftree-loop-optimize,
+   hint that we want to vectorize the loop LOOP.  */
+static void
+maybe_auto_vectorize_loop (class loop *loop)
+{
+  if ((flag_tree_loop_vectorize
+   || !OPTION_SET_P (flag_tree_loop_vectorize))
+  && flag_tree_loop_optimize)
+{
+  loop->force_vectorize = true;
+  cfun->has_force_vectorize_loops = true;
+}
+}
+
+
 /* A subroutine of expand_omp_for.  Generate code for a parallel
loop with any schedule.  Given parameters:
 
@@ -4650,6 +4666,7 @@ expand_omp_for_generic (struct omp_region *region,
   new_loop->header = l0_bb;
   new_loop->latch = l2_bb;
   add_loop (new_loop, outer_loop);
+  maybe_auto_vectorize_loop (new_loop);
 
   /* Allocate a loop structure for the original loop unless we already
 	 had one.  */
@@ -4660,6 +4677,7 @@ expand_omp_for_generic (struct omp_region *region,
 	  orig_loop->header = l1_bb;
 	  /* The loop may have multiple latches.  */
 	  add_loop (orig_loop, new_loop);
+	  maybe_auto_vectorize_loop (orig_loop);
 	}
 }
 }
@@ -5551,6 +5569,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
   if (collapse_bb == NULL)
 	loop->latch = cont_bb;
   add_loop (loop, body_bb->loop_father);
+  maybe_auto_vectorize_loop (loop);
 }
 }
 
@@ -6268,6 +6287,7 @@ expand_omp_for_static_chunk (struct omp_region *region,
   trip_loop->header = iter_part_bb;
   trip_loop->latch = trip_update_bb;
   add_loop (trip_loop, iter_part_bb->loop_father);
+  maybe_auto_vectorize_loop (trip_loop);
 
   if (loop != entry_bb->loop_father)
 	{
@@ -6285,6 +6305,7 @@ expand_omp_for_static_chunk (struct omp_region *region,
 	  if (collapse_bb == NULL)
 	loop->latch = cont_bb;
 	  add_loop (loop, trip_loop);
+	  maybe_auto_vectorize_loop (loop);
 	}
 }
 }
@@ -7439,6 +7460,7 @@ expand_omp_taskloop_for_inner (struct omp_region *region,
   if (collapse_bb == NULL)
 	loop->latch = cont_bb;
   add_loop (loop, body_bb->loop_father);
+  maybe_auto_vectorize_loop (loop);
 }
 }
 
@@ -8006,6 +8028,7 @@ expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
 	  inner_loop->header = elem_body_bb;
 	  inner_loop->latch = elem_cont_bb;
 	  add_loop (inner_loop, body_loop)

OpenMP: Generate SIMD clones for functions with "declare target"

2022-09-14 Thread Sandra Loosemore
This patch is part of the ongoing effort to find more SIMD optimization 
opportunities in OpenMP code.  Here we are looking for functions that 
have the "omp declare target" attribute that are also suitable 
candidates for automatic SIMD cloning.  I've made the filter quite 
conservative, but maybe it could be improved with some further analysis. 
 I added a command-line flag to disable this in case it is buggy :-P or 
leads to excessive code bloat without improving performance in some 
cases, otherwise the SIMD clones are generated in the same way and at 
the same optimization levels as the existing simdclone pass.


I had to modify the TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN hook 
to add a boolean argument to control diagnostics, since GCC shouldn't 
complain about types the target doesn't support in cases where the user 
didn't explicitly ask for clones to be created.  I tested on 
x86_64-linux-gnu-amdgcn, plain x86_64-linux-gnu, and aarch64-linux-gnu 
to get coverage of all 3 backends that implement this hook.  OK for 
mainline?


-SandraFrom 77df203f8ec191e036580d17b7fa83ae517a8018 Mon Sep 17 00:00:00 2001
From: Sandra Loosemore 
Date: Wed, 14 Sep 2022 00:20:25 +
Subject: [PATCH] OpenMP: Generate SIMD clones for functions with "declare
 target"

This patch causes the IPA simdclone pass to generate clones for
functions with the "omp declare target" attribute as if they had
"omp declare simd", provided the function appears to be suitable for
SIMD execution.  The filter is conservative, rejecting functions
that write memory or that call other functions not known to be safe.
A new option -fopenmp-target-simd-clone is added to control this
transformation; it's enabled by default.

gcc/ChangeLog:

	* c-family/c.opt (fopenmp-target-simd-clone): New option.
	* fortran/lang.opt (fopenmp-target-simd-clone): New option.
	* doc/invoke.texi (-fno-openmp-target-simd-clone): Document.
	* omp-simd-clone.cc (auto_simd_check_stmt): New function.
	(mark_auto_simd_clone): New function.
	(expand_simd_clones): Also check for cloneable functions with
	"omp declare target".  Pass error_p argument to
	simd_clone.compute_vecsize_and_simdlen target hook.
	* target.def (TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN):
	Add bool error_p argument.
	* doc/tm.texi: Regenerated.
	* config/aarch64/aarch64.cc
	(aarch64_simd_clone_compute_vecsize_and_simdlen): Update.
	* config/gcn/gcn.cc
	(gcn_simd_clone_compute_vecsize_and_simdlen): Update.
	* config/i386/i386.cc
	(ix86_simd_clone_compute_vecsize_and_simdlen): Update.

gcc/testsuite/ChangeLog:

	* gcc.dg/gomp/target-simd-clone-1.c: New.
	* gcc.dg/gomp/target-simd-clone-2.c: New.
	* gcc.dg/gomp/target-simd-clone-3.c: New.
	* gcc.dg/gomp/target-simd-clone-4.c: New.
---
 gcc/c-family/c.opt|   4 +
 gcc/config/aarch64/aarch64.cc |  24 ++-
 gcc/config/gcn/gcn.cc |  10 +-
 gcc/config/i386/i386.cc   |  25 ++-
 gcc/doc/invoke.texi   |  13 +-
 gcc/doc/tm.texi   |   2 +-
 gcc/fortran/lang.opt  |   4 +
 gcc/omp-simd-clone.cc | 178 +-
 gcc/target.def|   2 +-
 .../gcc.dg/gomp/target-simd-clone-1.c |  19 ++
 .../gcc.dg/gomp/target-simd-clone-2.c |  18 ++
 .../gcc.dg/gomp/target-simd-clone-3.c |  17 ++
 .../gcc.dg/gomp/target-simd-clone-4.c |  16 ++
 13 files changed, 301 insertions(+), 31 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gomp/target-simd-clone-1.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/target-simd-clone-2.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/target-simd-clone-3.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/target-simd-clone-4.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index ff6fe861534..0be39ae7709 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1993,6 +1993,10 @@ fopenmp-simd
 C ObjC C++ ObjC++ Var(flag_openmp_simd)
 Enable OpenMP's SIMD directives.
 
+fopenmp-target-simd-clone
+C ObjC C++ ObjC++ Var(flag_openmp_target_simd_clone) Init(1)
+Generate SIMD clones for functions with the OpenMP declare target directive.
+
 foperator-names
 C++ ObjC++
 Recognize C++ keywords like \"compl\" and \"xor\".
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index f199e77cd42..42c5d281537 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -26612,7 +26612,8 @@ currently_supported_simd_type (tree t, tree b)
 static int
 aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
 	struct cgraph_simd_clone *clonei,
-	tree base_type, int num)
+	tree base_type, int num,
+	bool error_p)
 {
   tree t, ret_type;
   unsigned int elt_bits, count;
@@ -26630,8 +26631,9 @@ aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
 	  || const_simdlen > 1024
 	  || (const_simdlen & (cons

Re: [PATCH] OpenMP: Enable vectorization in all OpenMP loops

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Wed, Sep 14, 2022 at 11:31:34AM -0600, Sandra Loosemore wrote:
> GCC presently enables the loop vectorizer at lower optimization levels for
> OpenMP loops with the "simd" specifier than it does for loops without it.
> The "simd" specifier isn't defined to be purely an optimization hint to the
> compiler; it also has semantic effects like changing the privatization of
> the loop variable.  It seems reasonable to decouple the additional
> vectorization from those semantic effects and apply it also to work-sharing
> loops without the "simd" specifier at the same optimization levels.
> 
> I've tested this patch on x86_64-linux-gnu-amdgcn, plain x86_64-linux-gnu,
> and aarch64-linux-gnu.  OK for mainline?

I don't understand this.
Isn't -ftree-loop-optimize on by default at all optimization levels?
Why this would be a good idea for say -O0, or -Og, -Os, or -Oz?
People want the code be debuggable with -O0 or -Og, it doesn't help if
it is vectorized (not sure if the vectorizer gate is even reached in that
case though), and for -Os or -Oz want small code, which vectorized code
typically is not.
And the vectorizer is on by default for -O2 and higher, so is this just
about -O1?
The reason for setting force_vectorize for simd directive is that the user
asks explicitly for it.
For other constructs we can just guess on user intents.  For simd directive
the user also guarantees that there aren't inter-iteration dependencies
that would prevent vectorization, but that is expressed in loop->safelen
and loop->simdlen, for other loops we don't have such guarantees, so the
compiler just needs to analyze if they are vectorizable.  But doesn't
gcc already do that for -O2/-O3 by default?

As for loop->safelen, I think we might set it in some cases for other
OpenMP constructs, like distribute without dist_schedule or
worksharing-loops with certain set of clauses (I think without schedule
clause).

Jakub



[PATCH] mips: Add appropriate linker flags when compiling with -static-pie

2022-09-14 Thread linted via Gcc-patches
Hello,

This patch fixes missing flags when compiling with -static-pie on mips. I
made these modifications based on the previously submitted static pie patch
for arm as well as the working code for aarch64.

I tested with a host of mips-elf and checked with mips-sim. This patch was
also tested and used with uclibc-ng to generate static pie elfs.

This is my first patch for gcc, so please let me know if there is anything
I missed.



Signed-off-by: linted 
---
 gcc/config/mips/gnu-user.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gcc/config/mips/gnu-user.h b/gcc/config/mips/gnu-user.h
index 6aad7192e69..b1c665b7f37 100644
--- a/gcc/config/mips/gnu-user.h
+++ b/gcc/config/mips/gnu-user.h
@@ -56,11 +56,12 @@ along with GCC; see the file COPYING3.  If not see
 #define GNU_USER_TARGET_LINK_SPEC "\
   %{G*} %{EB} %{EL} %{mips*} %{shared} \
   %{!shared: \
-%{!static: \
+%{!static:%{!static-pie: \
   %{rdynamic:-export-dynamic} \
   %{mabi=n32: -dynamic-linker " GNU_USER_DYNAMIC_LINKERN32 "} \
   %{mabi=64: -dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "} \
-  %{mabi=32: -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}} \
+  %{mabi=32: -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}}} \
+%{static-pie:-Bstatic -pie --no-dynamic-linker -z text} \
 %{static}} \
   %{mabi=n32:-m" GNU_USER_LINK_EMULATIONN32 "} \
   %{mabi=64:-m" GNU_USER_LINK_EMULATION64 "} \
-- 
2.34.1


Re: OpenMP: Generate SIMD clones for functions with "declare target"

2022-09-14 Thread Jakub Jelinek via Gcc-patches
On Wed, Sep 14, 2022 at 11:32:11AM -0600, Sandra Loosemore wrote:
> This patch is part of the ongoing effort to find more SIMD optimization
> opportunities in OpenMP code.  Here we are looking for functions that have
> the "omp declare target" attribute that are also suitable candidates for
> automatic SIMD cloning.  I've made the filter quite conservative, but maybe
> it could be improved with some further analysis.  I added a command-line
> flag to disable this in case it is buggy :-P or leads to excessive code
> bloat without improving performance in some cases, otherwise the SIMD clones
> are generated in the same way and at the same optimization levels as the
> existing simdclone pass.
> 
> I had to modify the TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN hook to
> add a boolean argument to control diagnostics, since GCC shouldn't complain
> about types the target doesn't support in cases where the user didn't
> explicitly ask for clones to be created.  I tested on
> x86_64-linux-gnu-amdgcn, plain x86_64-linux-gnu, and aarch64-linux-gnu to
> get coverage of all 3 backends that implement this hook.  OK for mainline?

declare simd is an ABI relevant declarative directive, while declare target
is not, all the latter does is say whether the function should be also (or
only) compilable on an offloading target.
Creating simd clones under some option for random declare target functions
(note, declare target is partly auto-discovered property) is perhaps fine
for functions not exported from the translation unit where it is purely
an optimization, but otherwise it is a significant ABI problem,
you export whole new bunch of new exports on the definition side and expect
those to be exported on the use side.  If you compile one TU with
-fopenmp-target-simd-clone and another one without it, program might not
link anymore.  And worse, as it is decided based on the exact implementation
of the function, I assume you can't do that automatically for functions
not defined locally, but whether something has simd clones or not might
change over time based on how you change the implementation.
Say libfoo.so exports a declare target function foo, which is initially
implemented without say using inline asm (or calling one of the "bad"
functions or using exceptions etc.), but then a bugfix comes and needs
to use inline asm or something else in the implementation.  Previously
libfoo.so would export the simd clones, but now it doesn't, so the ABI
of the library changes.

If it is pure optimization thing and purely keyed on the definition,
all the simd clones should be local to the TU, never exported from it.

Jakub



[committed] libstdc++: Document LWG 1203 API change in manual

2022-09-14 Thread Jonathan Wakely via Gcc-patches
Pushed to trunk.

-- >8 --

libstdc++-v3/ChangeLog:

* doc/xml/manual/intro.xml: Document LWG 1203.
* doc/html/*: Regenerate.
---
 libstdc++-v3/doc/html/manual/bugs.html | 3 +++
 libstdc++-v3/doc/html/manual/debug_mode_using.html | 7 ++-
 libstdc++-v3/doc/html/manual/using_macros.html | 5 +
 libstdc++-v3/doc/xml/manual/intro.xml  | 6 ++
 4 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/doc/xml/manual/intro.xml 
b/libstdc++-v3/doc/xml/manual/intro.xml
index 290e5d3a74e..d341c3efe6d 100644
--- a/libstdc++-v3/doc/xml/manual/intro.xml
+++ b/libstdc++-v3/doc/xml/manual/intro.xml
@@ -852,6 +852,12 @@ requirements of the license of GCC.
by the resolution of the DR.
 
 
+http://www.w3.org/1999/xlink"; xlink:href="&DR;#1203">1203:
+   More useful rvalue stream insertion
+
+Return the stream as its original type, not the base class.
+
+
 http://www.w3.org/1999/xlink"; xlink:href="&DR;#1339">1339:
uninitialized_fill_n should return the end of its 
range
 
-- 
2.37.3



[committed] libstdc++: Add comment to 17_intro/names.cc test

2022-09-14 Thread Jonathan Wakely via Gcc-patches
Tested x86_64-linux, pushed to trunk.

-- >8 --

libstdc++-v3/ChangeLog:

* testsuite/17_intro/names.cc: Explain why poison pragma can't
be used.
---
 libstdc++-v3/testsuite/17_intro/names.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libstdc++-v3/testsuite/17_intro/names.cc 
b/libstdc++-v3/testsuite/17_intro/names.cc
index 86fb8f8999b..82e201c71b0 100644
--- a/libstdc++-v3/testsuite/17_intro/names.cc
+++ b/libstdc++-v3/testsuite/17_intro/names.cc
@@ -20,6 +20,8 @@
 
 // Define macros for some common variables names that we must not use for
 // naming variables, parameters etc. in the library.
+// N.B. we cannot use '#pragma GCC poison A' because that also prevents using
+// these names even as macro arguments, e.g. #define FOO(A) BAR(A)
 #define A (
 #define B (
 #define C (
-- 
2.37.3



[committed] libstdc++: Add assertion to std::promise::set_exception (LWG 2276)

2022-09-14 Thread Jonathan Wakely via Gcc-patches
Tested x86_64-linux, pushed to trunk.

-- >8 --

Without this assertion, the shared state is made ready, but contains
neither a value nor an exception. Add an assertion to prevent users from
accessing a value that was never initialized in the shared state.

libstdc++-v3/ChangeLog:

* include/std/future
(_State_baseV2::__setter(exception_ptr&, promise&)): Add
assertion for LWG 2276 precondition.
* testsuite/30_threads/promise/members/set_exception_neg.cc:
New test.
---
 libstdc++-v3/include/std/future|  1 +
 .../promise/members/set_exception_neg.cc   | 18 ++
 2 files changed, 19 insertions(+)
 create mode 100644 
libstdc++-v3/testsuite/30_threads/promise/members/set_exception_neg.cc

diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future
index ba1f28c6c75..a1b2d7f1d3a 100644
--- a/libstdc++-v3/include/std/future
+++ b/libstdc++-v3/include/std/future
@@ -559,6 +559,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 static _Setter<_Res, __exception_ptr_tag>
 __setter(exception_ptr& __ex, promise<_Res>* __prom) noexcept
 {
+  __glibcxx_assert(__ex != nullptr); // LWG 2276
   return _Setter<_Res, __exception_ptr_tag>{ __prom, &__ex };
 }
 
diff --git 
a/libstdc++-v3/testsuite/30_threads/promise/members/set_exception_neg.cc 
b/libstdc++-v3/testsuite/30_threads/promise/members/set_exception_neg.cc
new file mode 100644
index 000..16660931242
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/promise/members/set_exception_neg.cc
@@ -0,0 +1,18 @@
+// { dg-options "-D_GLIBCXX_ASSERTIONS" }
+// { dg-do run { xfail *-*-* } }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-effective-target c++11 }
+// { dg-require-gthreads "" }
+
+// LWG 2276. Missing requirement on std::promise::set_exception
+
+#include 
+
+int main()
+{
+  std::promise prom;
+  auto f = prom.get_future();
+  std::exception_ptr p;
+  prom.set_exception(p); // Preconditions: p is not null
+  f.get();
+}
-- 
2.37.3



Re: [PATCH] Optimize (X<

2022-09-14 Thread Marc Glisse via Gcc-patches

On Tue, 13 Sep 2022, Roger Sayle wrote:


This patch tweaks the match.pd transformation previously added to fold
(X<

In https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html , I 
read:


"Bitwise operators act on the representation of the value including both 
the sign and value bits, where the sign bit is considered immediately 
above the highest-value value bit. Signed ‘>>’ acts on negative numbers by 
sign extension.


As an extension to the C language, GCC does not use the latitude given in 
C99 and C11 only to treat certain aspects of signed ‘<<’ as undefined."


To me, this means that for instance INT_MIN<<1 is well defined and 
evaluates to 0. But with this patch we turn (INT_MIN<<1)+(INT_MIN<<1) into 
(INT_MIN+INT_MIN)<<1, which is UB.


If we decide not to support this extension anymore, I think we need to 
change the documentation first.


--
Marc Glisse


Re: OpenMP: Generate SIMD clones for functions with "declare target"

2022-09-14 Thread Thomas Schwinge
Hi Sandra!

Commenting on just one single item:

On 2022-09-14T11:32:11-0600, Sandra Loosemore  wrote:
> --- a/gcc/omp-simd-clone.cc
> +++ b/gcc/omp-simd-clone.cc

>  void
>  expand_simd_clones (struct cgraph_node *node)
>  {
> -  tree attr = lookup_attribute ("omp declare simd",
> - DECL_ATTRIBUTES (node->decl));
> -  if (attr == NULL_TREE
> -  || node->inlined_to
> +  tree attr;
> +  bool error_p = true;
> +
> +  if (node->inlined_to
>|| lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
>  return;
>
> +  attr = lookup_attribute ("omp declare simd",
> +DECL_ATTRIBUTES (node->decl));
> +
> +  /* See if we can add an "omp declare simd" directive implicitly
> + before giving up.  */
> +  /* FIXME: OpenACC "#pragma acc routine" translates into
> + "omp declare target", but appears also to have some other effects
> + that conflict with generating SIMD clones, causing ICEs.  So don't
> + do this if we've got OpenACC instead of OpenMP.  */

Uh, ICEs...  (But I suppose this processing is not relevant for OpenACC
'routine's.)

However, OpenACC and OpenMP support may be active at the same time...

> +  if (attr == NULL_TREE
> +  && flag_openmp_target_simd_clone && !flag_openacc)

..., so '!flag_openacc' is not the right check here.  Instead you'd do
'!oacc_get_fn_attrib (DECL_ATTRIBUTES (node->decl))' (untested) or
similar.

> +{
> +  attr = mark_auto_simd_clone (node);
> +  error_p = false;
> +}
> +  if (attr == NULL_TREE)
> +return;


Grüße
 Thomas
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955


[committed] libstdc++: Add missing header to

2022-09-14 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8 --

This is needed for std::nothrow and the nothrow operator new overload,
so should be included explicitly.

libstdc++-v3/ChangeLog:

* include/bits/stl_tempbuf.h: Include .
---
 libstdc++-v3/include/bits/stl_tempbuf.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h 
b/libstdc++-v3/include/bits/stl_tempbuf.h
index db7cdb14ca9..82f2dc8055f 100644
--- a/libstdc++-v3/include/bits/stl_tempbuf.h
+++ b/libstdc++-v3/include/bits/stl_tempbuf.h
@@ -56,6 +56,7 @@
 #ifndef _STL_TEMPBUF_H
 #define _STL_TEMPBUF_H 1
 
+#include 
 #include 
 #include 
 
-- 
2.37.3



[committed] libstdc++: Add TSan annotations to std::atomic>

2022-09-14 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8 --

This adds annotations to std::atomic> to enable TSan to
understand the custom locking. Without this, TSan reports data races for
accesses to the _M_ptr member, even though those are correctly
synchronized using atomic operations on the tagged pointer.

libstdc++-v3/ChangeLog:

* include/bits/shared_ptr_atomic.h (_GLIBCXX_TSAN_MUTEX_DESTROY)
(_GLIBCXX_TSAN_MUTEX_PRE_LOCK, _GLIBCXX_TSAN_MUTEX_POST_LOCK)
(_GLIBCXX_TSAN_MUTEX_PRE_UNLOCK, _GLIBCXX_TSAN_MUTEX_POST_UNLOCK)
(_GLIBCXX_TSAN_MUTEX_PRE_SIGNAL, _GLIBCXX_TSAN_MUTEX_POST_SIGNAL):
Define macros for TSan annotation functions.
(_Sp_atomic::_Atomic_count): Add annotations.
---
 libstdc++-v3/include/bits/shared_ptr_atomic.h | 38 +++
 1 file changed, 38 insertions(+)

diff --git a/libstdc++-v3/include/bits/shared_ptr_atomic.h 
b/libstdc++-v3/include/bits/shared_ptr_atomic.h
index d4bd712fc7d..4580807f42c 100644
--- a/libstdc++-v3/include/bits/shared_ptr_atomic.h
+++ b/libstdc++-v3/include/bits/shared_ptr_atomic.h
@@ -32,6 +32,30 @@
 
 #include 
 
+#if defined _GLIBCXX_TSAN && __has_include()
+#include 
+#define _GLIBCXX_TSAN_MUTEX_DESTROY(X) \
+  __tsan_mutex_destroy(X, __tsan_mutex_not_static)
+#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X) \
+  __tsan_mutex_pre_lock(X, __tsan_mutex_not_static)
+#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X) \
+  __tsan_mutex_post_lock(X, __tsan_mutex_not_static, 0)
+#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) \
+  __tsan_mutex_pre_unlock(X, __tsan_mutex_not_static)
+#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) \
+  __tsan_mutex_post_unlock(X, __tsan_mutex_not_static)
+#define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X) __tsan_mutex_pre_signal(X, 0)
+#define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X) __tsan_mutex_post_signal(X, 0)
+#else
+#define _GLIBCXX_TSAN_MUTEX_DESTROY(X)
+#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X)
+#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X)
+#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X)
+#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X)
+#define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X)
+#define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X)
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -377,6 +401,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
~_Atomic_count()
{
  auto __val = _M_val.load(memory_order_relaxed);
+ _GLIBCXX_TSAN_MUTEX_DESTROY(&_M_val);
  __glibcxx_assert(!(__val & _S_lock_bit));
  if (auto __pi = reinterpret_cast(__val))
{
@@ -406,6 +431,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  __current = _M_val.load(memory_order_relaxed);
}
 
+ _GLIBCXX_TSAN_MUTEX_PRE_LOCK(&_M_val);
+
  while (!_M_val.compare_exchange_strong(__current,
 __current | _S_lock_bit,
 __o,
@@ -416,6 +443,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
  __current = __current & ~_S_lock_bit;
}
+ _GLIBCXX_TSAN_MUTEX_POST_LOCK(&_M_val);
  return reinterpret_cast(__current);
}
 
@@ -423,7 +451,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
unlock(memory_order __o) const noexcept
{
+ _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val);
  _M_val.fetch_sub(1, __o);
+ _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val);
}
 
// Swaps the values of *this and __c, and unlocks *this.
@@ -434,7 +464,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  if (__o != memory_order_seq_cst)
__o = memory_order_release;
  auto __x = reinterpret_cast(__c._M_pi);
+ _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val);
  __x = _M_val.exchange(__x, __o);
+ _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val);
  __c._M_pi = reinterpret_cast(__x & ~_S_lock_bit);
}
 
@@ -443,20 +475,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_M_wait_unlock(memory_order __o) const noexcept
{
+ _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val);
  auto __v = _M_val.fetch_sub(1, memory_order_relaxed);
+ _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val);
  _M_val.wait(__v & ~_S_lock_bit, __o);
}
 
void
notify_one() noexcept
{
+ _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(&_M_val);
  _M_val.notify_one();
+ _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(&_M_val);
}
 
void
notify_all() noexcept
{
+ _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(&_M_val);
  _M_val.notify_all();
+ _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(&_M_val);
}
 #endif
 
-- 
2.37.3



Re: [committed] libstdc++: Add TSan annotations to std::atomic>

2022-09-14 Thread Jonathan Wakely via Gcc-patches
On Wed, 14 Sept 2022 at 23:05, Jonathan Wakely via Libstdc++
 wrote:
>
> Tested powerpc64le-linux, pushed to trunk.
>
> -- >8 --
>
> This adds annotations to std::atomic> to enable TSan to
> understand the custom locking. Without this, TSan reports data races for
> accesses to the _M_ptr member, even though those are correctly
> synchronized using atomic operations on the tagged pointer.
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/shared_ptr_atomic.h (_GLIBCXX_TSAN_MUTEX_DESTROY)
> (_GLIBCXX_TSAN_MUTEX_PRE_LOCK, _GLIBCXX_TSAN_MUTEX_POST_LOCK)
> (_GLIBCXX_TSAN_MUTEX_PRE_UNLOCK, _GLIBCXX_TSAN_MUTEX_POST_UNLOCK)
> (_GLIBCXX_TSAN_MUTEX_PRE_SIGNAL, _GLIBCXX_TSAN_MUTEX_POST_SIGNAL):
> Define macros for TSan annotation functions.
> (_Sp_atomic::_Atomic_count): Add annotations.
> ---
>  libstdc++-v3/include/bits/shared_ptr_atomic.h | 38 +++
>  1 file changed, 38 insertions(+)
>
> diff --git a/libstdc++-v3/include/bits/shared_ptr_atomic.h 
> b/libstdc++-v3/include/bits/shared_ptr_atomic.h
> index d4bd712fc7d..4580807f42c 100644
> --- a/libstdc++-v3/include/bits/shared_ptr_atomic.h
> +++ b/libstdc++-v3/include/bits/shared_ptr_atomic.h
> @@ -32,6 +32,30 @@
>
>  #include 
>
> +#if defined _GLIBCXX_TSAN && __has_include()
> +#include 
> +#define _GLIBCXX_TSAN_MUTEX_DESTROY(X) \
> +  __tsan_mutex_destroy(X, __tsan_mutex_not_static)
> +#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X) \
> +  __tsan_mutex_pre_lock(X, __tsan_mutex_not_static)
> +#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X) \
> +  __tsan_mutex_post_lock(X, __tsan_mutex_not_static, 0)
> +#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) \
> +  __tsan_mutex_pre_unlock(X, __tsan_mutex_not_static)
> +#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) \
> +  __tsan_mutex_post_unlock(X, __tsan_mutex_not_static)
> +#define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X) __tsan_mutex_pre_signal(X, 0)
> +#define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X) __tsan_mutex_post_signal(X, 0)
> +#else
> +#define _GLIBCXX_TSAN_MUTEX_DESTROY(X)
> +#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X)
> +#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X)
> +#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X)
> +#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X)
> +#define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X)
> +#define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X)
> +#endif
> +
>  namespace std _GLIBCXX_VISIBILITY(default)
>  {
>  _GLIBCXX_BEGIN_NAMESPACE_VERSION
> @@ -377,6 +401,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> ~_Atomic_count()
> {
>   auto __val = _M_val.load(memory_order_relaxed);
> + _GLIBCXX_TSAN_MUTEX_DESTROY(&_M_val);

After further thought, I'm not sure this is right. This tells tsan
that the "mutex" at &_M_val cannot be locked or unlocked again after
this. But what happens if the address is reused by a different
atomic> which happens to be at the same memory address?
Will tsan think that's an invalid use of the original "mutex" after
its destruction?

I will investigate.

We might need to stop using the __tsan_mutex_destroy call, and if so,
we can stop using the __tsan_mutex_not_static flag too. The pre/post
lock/unlock/signal pairs are still valuable without the lifetime
checking.



Re: [committed] libstdc++: Add TSan annotations to std::atomic>

2022-09-14 Thread Jonathan Wakely via Gcc-patches
On Wed, 14 Sept 2022 at 23:25, Jonathan Wakely wrote:
>
> On Wed, 14 Sept 2022 at 23:05, Jonathan Wakely via Libstdc++
>  wrote:
> >
> > Tested powerpc64le-linux, pushed to trunk.
> >
> > -- >8 --
> >
> > This adds annotations to std::atomic> to enable TSan to
> > understand the custom locking. Without this, TSan reports data races for
> > accesses to the _M_ptr member, even though those are correctly
> > synchronized using atomic operations on the tagged pointer.
> >
> > libstdc++-v3/ChangeLog:
> >
> > * include/bits/shared_ptr_atomic.h (_GLIBCXX_TSAN_MUTEX_DESTROY)
> > (_GLIBCXX_TSAN_MUTEX_PRE_LOCK, _GLIBCXX_TSAN_MUTEX_POST_LOCK)
> > (_GLIBCXX_TSAN_MUTEX_PRE_UNLOCK, _GLIBCXX_TSAN_MUTEX_POST_UNLOCK)
> > (_GLIBCXX_TSAN_MUTEX_PRE_SIGNAL, _GLIBCXX_TSAN_MUTEX_POST_SIGNAL):
> > Define macros for TSan annotation functions.
> > (_Sp_atomic::_Atomic_count): Add annotations.
> > ---
> >  libstdc++-v3/include/bits/shared_ptr_atomic.h | 38 +++
> >  1 file changed, 38 insertions(+)
> >
> > diff --git a/libstdc++-v3/include/bits/shared_ptr_atomic.h 
> > b/libstdc++-v3/include/bits/shared_ptr_atomic.h
> > index d4bd712fc7d..4580807f42c 100644
> > --- a/libstdc++-v3/include/bits/shared_ptr_atomic.h
> > +++ b/libstdc++-v3/include/bits/shared_ptr_atomic.h
> > @@ -32,6 +32,30 @@
> >
> >  #include 
> >
> > +#if defined _GLIBCXX_TSAN && __has_include()
> > +#include 
> > +#define _GLIBCXX_TSAN_MUTEX_DESTROY(X) \
> > +  __tsan_mutex_destroy(X, __tsan_mutex_not_static)
> > +#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X) \
> > +  __tsan_mutex_pre_lock(X, __tsan_mutex_not_static)
> > +#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X) \
> > +  __tsan_mutex_post_lock(X, __tsan_mutex_not_static, 0)
> > +#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) \
> > +  __tsan_mutex_pre_unlock(X, __tsan_mutex_not_static)
> > +#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) \
> > +  __tsan_mutex_post_unlock(X, __tsan_mutex_not_static)
> > +#define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X) __tsan_mutex_pre_signal(X, 0)
> > +#define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X) __tsan_mutex_post_signal(X, 0)
> > +#else
> > +#define _GLIBCXX_TSAN_MUTEX_DESTROY(X)
> > +#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X)
> > +#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X)
> > +#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X)
> > +#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X)
> > +#define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X)
> > +#define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X)
> > +#endif
> > +
> >  namespace std _GLIBCXX_VISIBILITY(default)
> >  {
> >  _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > @@ -377,6 +401,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > ~_Atomic_count()
> > {
> >   auto __val = _M_val.load(memory_order_relaxed);
> > + _GLIBCXX_TSAN_MUTEX_DESTROY(&_M_val);
>
> After further thought, I'm not sure this is right. This tells tsan
> that the "mutex" at &_M_val cannot be locked or unlocked again after
> this. But what happens if the address is reused by a different
> atomic> which happens to be at the same memory address?
> Will tsan think that's an invalid use of the original "mutex" after
> its destruction?

We can't easily add a call to __tsan_mutex_create, which would begin
the lifetime of a new object at that address, because the default
constructor is constexpr, and the create function isn't.

>
> I will investigate.
>
> We might need to stop using the __tsan_mutex_destroy call, and if so,
> we can stop using the __tsan_mutex_not_static flag too. The pre/post
> lock/unlock/signal pairs are still valuable without the lifetime
> checking.



float.h: Do not define INFINITY for C2x when infinities not supported

2022-09-14 Thread Joseph Myers
C2x has changed the rules for defining INFINITY in  so it is
no longer defined when float does not support infinities, instead of
being defined to an expression that overflows at translation time.
Thus, make the definition conditional on __FLT_HAS_INFINITY__ (this is
already inside a C2x-conditional part of , because previous C
standard versions only had this macro in ).

Bootstrapped with no regressions for x86_64-pc-linux-gnu.  Also did a
spot test of the case of no infinities supported by building cc1 for
vax-netbsdelf and testing compiling the new c2x-float-11.c test with
it.

gcc/
* ginclude/float.h (INFINITY): Define only if
[__FLT_HAS_INFINITY__].

gcc/testsuite/
* gcc.dg/c2x-float-2.c: Require inff effective-target.
* gcc.dg/c2x-float-11.c: New test.

diff --git a/gcc/ginclude/float.h b/gcc/ginclude/float.h
index 9d368c4afa5..afe4a712878 100644
--- a/gcc/ginclude/float.h
+++ b/gcc/ginclude/float.h
@@ -257,9 +257,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 #define DBL_IS_IEC_60559   __DBL_IS_IEC_60559__
 #define LDBL_IS_IEC_60559  __LDBL_IS_IEC_60559__
 
-/* Infinity in type float, or overflow if infinity not supported.  */
+/* Infinity in type float; not defined if infinity not supported.  */
+#if __FLT_HAS_INFINITY__
 #undef INFINITY
 #define INFINITY   (__builtin_inff ())
+#endif
 
 /* Quiet NaN, if supported for float.  */
 #if __FLT_HAS_QUIET_NAN__
diff --git a/gcc/testsuite/gcc.dg/c2x-float-11.c 
b/gcc/testsuite/gcc.dg/c2x-float-11.c
new file mode 100644
index 000..0e2f3c0c97a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-11.c
@@ -0,0 +1,9 @@
+/* Test INFINITY macro.  Test when infinities not supported.  */
+/* { dg-do compile { target { ! inff } } } */
+/* { dg-options "-std=c2x" } */
+
+#include 
+
+#ifdef INFINITY
+#error "INFINITY defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-float-2.c 
b/gcc/testsuite/gcc.dg/c2x-float-2.c
index 4f669fd39bc..61a77f6f2db 100644
--- a/gcc/testsuite/gcc.dg/c2x-float-2.c
+++ b/gcc/testsuite/gcc.dg/c2x-float-2.c
@@ -1,8 +1,8 @@
-/* Test INFINITY macro.  Generic test even if infinities not
-   supported.  */
+/* Test INFINITY macro.  Generic test.  */
 /* { dg-do run } */
 /* { dg-options "-std=c2x -w" } */
 /* { dg-add-options ieee } */
+/* { dg-require-effective-target inff } */
 
 #include 
 

-- 
Joseph S. Myers
jos...@codesourcery.com


[PATCH] i386: Fixed vec_init_dup_v16bf [PR106887]

2022-09-14 Thread Kong, Lingling via Gcc-patches
Hi

The patch is to fix vec_init_dup_v16bf, add correct handle for v16bf mode in 
ix86_expand_vector_init_duplicate.
Add testcase with sse2 without avx2.

OK for master? 

gcc/ChangeLog:

PR target/106887
* config/i386/i386-expand.cc (ix86_expand_vector_init_duplicate):
Fixed V16BF mode case.

gcc/testsuite/ChangeLog:

PR target/106887
* gcc.target/i386/vect-bfloat16-2c.c: New test.
---
 gcc/config/i386/i386-expand.cc|  1 +
 .../gcc.target/i386/vect-bfloat16-2c.c| 76 +++
 2 files changed, 77 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/vect-bfloat16-2c.c

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc 
index d7b49c99dc8..9451c561489 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -15111,6 +15111,7 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, 
machine_mode mode,
{
  machine_mode hvmode = (mode == V16HImode ? V8HImode
 : mode == V16HFmode ? V8HFmode
+: mode == V16BFmode ? V8BFmode
 : V16QImode);
  rtx x = gen_reg_rtx (hvmode);
 
diff --git a/gcc/testsuite/gcc.target/i386/vect-bfloat16-2c.c 
b/gcc/testsuite/gcc.target/i386/vect-bfloat16-2c.c
new file mode 100644
index 000..bead94e46a1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-bfloat16-2c.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-mf16c -msse2 -mno-avx2 -O2" } */
+
+typedef __bf16 v8bf __attribute__ ((__vector_size__ (16))); typedef 
+__bf16 v16bf __attribute__ ((__vector_size__ (32)));
+
+#define VEC_EXTRACT(V,S,IDX)   \
+  S\
+  __attribute__((noipa))   \
+  vec_extract_##V##_##IDX (V v)\
+  {\
+return v[IDX]; \
+  }
+
+#define VEC_SET(V,S,IDX)   \
+  V\
+  __attribute__((noipa))   \
+  vec_set_##V##_##IDX (V v, S s)   \
+  {\
+v[IDX] = s;\
+return v;  \
+  }
+
+v8bf
+vec_init_v8bf (__bf16 a1, __bf16 a2, __bf16 a3, __bf16 a4,
+  __bf16 a5,  __bf16 a6, __bf16 a7, __bf16 a8) {
+return __extension__ (v8bf) {a1, a2, a3, a4, a5, a6, a7, a8}; }
+
+v16bf
+vec_init_v16bf (__bf16 a1, __bf16 a2, __bf16 a3, __bf16 a4,
+  __bf16 a5,  __bf16 a6, __bf16 a7, __bf16 a8,
+  __bf16 a9,  __bf16 a10, __bf16 a11, __bf16 a12,
+  __bf16 a13,  __bf16 a14, __bf16 a15, __bf16 a16) {
+return __extension__ (v16bf) {a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16}; }
+
+v8bf
+vec_init_dup_v8bf (__bf16 a1)
+{
+return __extension__ (v8bf) {a1, a1, a1, a1, a1, a1, a1, a1}; }
+
+v16bf
+vec_init_dup_v16bf (__bf16 a1)
+{
+return __extension__ (v16bf) {a1, a1, a1, a1, a1, a1, a1, a1,
+ a1, a1, a1, a1, a1, a1, a1, a1};
+}
+
+/* { dg-final { scan-assembler-times "vpunpcklwd" 12 } } */
+/* { dg-final { scan-assembler-times "vpunpckldq" 6 } } */
+/* { dg-final { scan-assembler-times "vpunpcklqdq" 3 } } */
+
+VEC_EXTRACT (v8bf, __bf16, 0);
+VEC_EXTRACT (v8bf, __bf16, 4);
+VEC_EXTRACT (v16bf, __bf16, 0);
+VEC_EXTRACT (v16bf, __bf16, 3);
+VEC_EXTRACT (v16bf, __bf16, 8);
+VEC_EXTRACT (v16bf, __bf16, 15);
+/* { dg-final { scan-assembler-times "vpsrldq\[\t ]*\\\$8" 1 } } */
+/* { dg-final { scan-assembler-times "vpsrldq\[\t ]*\\\$6" 1 } } */
+/* { dg-final { scan-assembler-times "vpsrldq\[\t ]*\\\$14" 1 } } */
+/* { dg-final { scan-assembler-times "vextract" 4 } } */
+
+VEC_SET (v8bf, __bf16, 4);
+VEC_SET (v16bf, __bf16, 3);
+VEC_SET (v16bf, __bf16, 8);
+VEC_SET (v16bf, __bf16, 15);
+/* { dg-final { scan-assembler-times "vpblendw" 3 { target { ! ia32 } } 
+} } */
+
+/* { dg-final { scan-assembler-times "vpinsrw" 30 { target ia32 } } } 
+*/
+
--
2.18.2



Re: [PATCH] LoongArch: Prepare static PIE support

2022-09-14 Thread Lulu Cheng

LGTM!

Thanks.

在 2022/9/13 下午11:32, Xi Ruoyao 写道:

Static PIE allows us to extend the ASLR to cover static executables and
it's not too difficult to support it.  On GCC side, we just pass a group
of options to the linker, like other ports with static PIE support.

The real implementation of static PIE (rcrt1.o) will be added into Glibc
later.

gcc/ChangeLog:

* config/loongarch/gnu-user.h (GNU_USER_TARGET_LINK_SPEC): For
-static-pie, pass -static -pie --no-dynamic-linker -z text to
the linker, and do not pass --dynamic-linker.
---
  gcc/config/loongarch/gnu-user.h | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/config/loongarch/gnu-user.h b/gcc/config/loongarch/gnu-user.h
index 664dc9206ad..c5b1afe530d 100644
--- a/gcc/config/loongarch/gnu-user.h
+++ b/gcc/config/loongarch/gnu-user.h
@@ -40,8 +40,10 @@ along with GCC; see the file COPYING3.  If not see
  #undef GNU_USER_TARGET_LINK_SPEC
  #define GNU_USER_TARGET_LINK_SPEC \
"%{G*} %{shared} -m " GNU_USER_LINK_EMULATION \
-  "%{!shared: %{static} %{!static: %{rdynamic:-export-dynamic} " \
-  "-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}"
+  "%{!shared: %{static} " \
+  "%{!static: %{!static-pie: %{rdynamic:-export-dynamic} " \
+  "-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}} " \
+  "%{static-pie: -static -pie --no-dynamic-linker -z text}}"
  
  
  /* Similar to standard Linux, but adding -ffast-math support.  */




Re: [PATCH] i386: Fixed vec_init_dup_v16bf [PR106887]

2022-09-14 Thread Hongtao Liu via Gcc-patches
On Thu, Sep 15, 2022 at 11:36 AM Kong, Lingling via Gcc-patches
 wrote:
>
> Hi
>
> The patch is to fix vec_init_dup_v16bf, add correct handle for v16bf mode in 
> ix86_expand_vector_init_duplicate.
> Add testcase with sse2 without avx2.
>
> OK for master?
>
> gcc/ChangeLog:
>
> PR target/106887
> * config/i386/i386-expand.cc (ix86_expand_vector_init_duplicate):
> Fixed V16BF mode case.
>
> gcc/testsuite/ChangeLog:
>
> PR target/106887
> * gcc.target/i386/vect-bfloat16-2c.c: New test.
> ---
>  gcc/config/i386/i386-expand.cc|  1 +
>  .../gcc.target/i386/vect-bfloat16-2c.c| 76 +++
>  2 files changed, 77 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/i386/vect-bfloat16-2c.c
>
> diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc 
> index d7b49c99dc8..9451c561489 100644
> --- a/gcc/config/i386/i386-expand.cc
> +++ b/gcc/config/i386/i386-expand.cc
> @@ -15111,6 +15111,7 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, 
> machine_mode mode,
> {
>   machine_mode hvmode = (mode == V16HImode ? V8HImode
>  : mode == V16HFmode ? V8HFmode
> +: mode == V16BFmode ? V8BFmode
Can it be written as switch case?
>  : V16QImode);
>   rtx x = gen_reg_rtx (hvmode);
>
> diff --git a/gcc/testsuite/gcc.target/i386/vect-bfloat16-2c.c 
> b/gcc/testsuite/gcc.target/i386/vect-bfloat16-2c.c
> new file mode 100644
> index 000..bead94e46a1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/vect-bfloat16-2c.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mf16c -msse2 -mno-avx2 -O2" } */
> +
> +typedef __bf16 v8bf __attribute__ ((__vector_size__ (16))); typedef
> +__bf16 v16bf __attribute__ ((__vector_size__ (32)));
> +
> +#define VEC_EXTRACT(V,S,IDX)   \
> +  S\
> +  __attribute__((noipa))   \
> +  vec_extract_##V##_##IDX (V v)\
> +  {\
> +return v[IDX]; \
> +  }
> +
> +#define VEC_SET(V,S,IDX)   \
> +  V\
> +  __attribute__((noipa))   \
> +  vec_set_##V##_##IDX (V v, S s)   \
> +  {\
> +v[IDX] = s;\
> +return v;  \
> +  }
> +
> +v8bf
> +vec_init_v8bf (__bf16 a1, __bf16 a2, __bf16 a3, __bf16 a4,
> +  __bf16 a5,  __bf16 a6, __bf16 a7, __bf16 a8) {
> +return __extension__ (v8bf) {a1, a2, a3, a4, a5, a6, a7, a8}; }
> +
> +v16bf
> +vec_init_v16bf (__bf16 a1, __bf16 a2, __bf16 a3, __bf16 a4,
> +  __bf16 a5,  __bf16 a6, __bf16 a7, __bf16 a8,
> +  __bf16 a9,  __bf16 a10, __bf16 a11, __bf16 a12,
> +  __bf16 a13,  __bf16 a14, __bf16 a15, __bf16 a16) {
> +return __extension__ (v16bf) {a1, a2, a3, a4, a5, a6, a7, a8,
> + a9, a10, a11, a12, a13, a14, a15, a16}; }
> +
> +v8bf
> +vec_init_dup_v8bf (__bf16 a1)
> +{
> +return __extension__ (v8bf) {a1, a1, a1, a1, a1, a1, a1, a1}; }
> +
> +v16bf
> +vec_init_dup_v16bf (__bf16 a1)
> +{
> +return __extension__ (v16bf) {a1, a1, a1, a1, a1, a1, a1, a1,
> + a1, a1, a1, a1, a1, a1, a1, a1};
> +}
> +
> +/* { dg-final { scan-assembler-times "vpunpcklwd" 12 } } */
> +/* { dg-final { scan-assembler-times "vpunpckldq" 6 } } */
> +/* { dg-final { scan-assembler-times "vpunpcklqdq" 3 } } */
> +
> +VEC_EXTRACT (v8bf, __bf16, 0);
> +VEC_EXTRACT (v8bf, __bf16, 4);
> +VEC_EXTRACT (v16bf, __bf16, 0);
> +VEC_EXTRACT (v16bf, __bf16, 3);
> +VEC_EXTRACT (v16bf, __bf16, 8);
> +VEC_EXTRACT (v16bf, __bf16, 15);
> +/* { dg-final { scan-assembler-times "vpsrldq\[\t ]*\\\$8" 1 } } */
> +/* { dg-final { scan-assembler-times "vpsrldq\[\t ]*\\\$6" 1 } } */
> +/* { dg-final { scan-assembler-times "vpsrldq\[\t ]*\\\$14" 1 } } */
> +/* { dg-final { scan-assembler-times "vextract" 4 } } */
> +
> +VEC_SET (v8bf, __bf16, 4);
> +VEC_SET (v16bf, __bf16, 3);
> +VEC_SET (v16bf, __bf16, 8);
> +VEC_SET (v16bf, __bf16, 15);
> +/* { dg-final { scan-assembler-times "vpblendw" 3 { target { ! ia32 } }
> +} } */
> +
> +/* { dg-final { scan-assembler-times "vpinsrw" 30 { target ia32 } } }
> +*/
> +
> --
> 2.18.2
>


-- 
BR,
Hongtao


[PATCH] Rewrite NAN and sign handling in frange

2022-09-14 Thread Aldy Hernandez via Gcc-patches
Hi Richard.  Hi all.

The attatched patch rewrites the NAN and sign handling, dropping both
tristates in favor of a pair of boolean flags for NANs, and nothing at
all for signs.  The signs are tracked in the range itself, so now it's
possible to describe things like [-0.0, +0.0] +NAN, [+0, +0], [-5, +0],
[+0, 3] -NAN, etc.

There are a lot of changes, as the tristate was quite pervasive.  I
could use another pair of eyes.  The code IMO is cleaner and handles
all the cases we discussed.

Here is an example of the various ranges and how they are displayed:

[frange] float VARYING NAN ;; Varying includes NAN
[frange] UNDEFINED  ;; Empty set as always
[frange] float [] NAN   ;; Unknown sign NAN
[frange] float [] -NAN  ;; -NAN
[frange] float [] +NAN  ;; +NAN
[frange] float [-0.0, 0.0]  ;; All zeros.
[frange] float [-0.0, -0.0] NAN ;; -0 or NAN.
[frange] float [-5.0e+0, -1.0e+0] +NAN  ;; [-5, -1] or +NAN
[frange] float [-5.0e+0, -0.0] NAN  ;; [-5, -0] or +-NAN
[frange] float [-5.0e+0, -0.0]  ;; [-5, -0]
[frange] float [5.0e+0, 1.0e+1] ;; [5, 10]

We could represent an unknown sign with +NAN -NAN if preferred.

Notice the NAN signs are decoupled from the range, so we can represent
a negative range with a positive NAN.  For this range,
frange::known_bit() would return false, as only when the signs of the
NANs and range agree can we be certain.

There is no longer any pessimization of ranges for intersects
involving NANs.  Also, union and intersect work with signed zeros:

//   [-0,  x] U [+0,  x] => [-0,  x]
//   [ x, -0] U [ x, +0] => [ x, +0]
//   [-0,  x] ^ [+0,  x] => [+0,  x]
//   [ x, -0] ^ [ x, +0] => [ x, -0]

The special casing for signed zeros in the singleton code is gone in
favor of just making sure the signs in the range agree, that is
[-0, -0] for example.

I have removed the idea that a known NAN is a "range", so a NAN is no
longer in the endpoints itself.  Requesting the bound of a known NAN
is a hard fail.  For that matter, we don't store the actual NAN in the
range.  The only information we have are the set of boolean flags.
This way we make sure nothing seeps into the frange.  This also means
it's explicit that we don't track anything but the sign in NANs.  We
can revisit this if we desire to track signalling or whatever
concoction y'all can imagine.

All in all, I'm quite happy with this.  It does look better, and we
handle all the corner cases we couldn't before.  Thanks for the
suggestion.

Regstrapped with mpfr tests on x86-64 and ppc64le Linux.  Selftests
were also run with -ffinite-math-only on x86-64.

At Jakub's suggestion, I built lapack with associated tests.  They
pass on x86-64 and ppc64le Linux with no regressions from mainline.
As a sanity check, I also ran them for -ffinite-math-only on x86 which
(as expected) returned:

NaN arithmetic did not perform per the ieee spec

Otherwise, all tests pass for -ffinite-math-only.

How does this look?

gcc/ChangeLog:

* range-op-float.cc (frange_add_zeros): Replace set_signbit with
union of zero.
* value-query.cc (range_query::get_tree_range): Remove set_signbit
use.
* value-range-pretty-print.cc (vrange_printer::print_frange_prop):
Remove.
(vrange_printer::print_frange_nan): New.
* value-range-pretty-print.h (print_frange_prop): Remove.
(print_frange_nan): New.
* value-range-storage.cc (frange_storage_slot::set_frange): Set
kind and NAN fields.
(frange_storage_slot::get_frange): Restore kind and NAN fields.
* value-range-storage.h (class frange_storage_slot): Add kind and
NAN fields.
* value-range.cc (frange::update_nan): Remove.
(frange::set_signbit): Remove.
(frange::set): Adjust for NAN fields.
(frange::normalize_kind): Remove m_props.
(frange::combine_zeros): New.
(frange::union_nans): New.
(frange::union_): Handle new NAN fields.
(frange::intersect_nans): New.
(frange::intersect): Handle new NAN fields.
(frange::operator=): Same.
(frange::operator==): Same.
(frange::contains_p): Same.
(frange::singleton_p): Remove special case for signed zeros.
(frange::verify_range): Adjust for new NAN fields.
(frange::set_zero): Handle signed zeros.
(frange::set_nonnegative): Same.
(range_tests_nan): Adjust tests.
(range_tests_signed_zeros): Same.
(range_tests_signbit): Same.
(range_tests_floats): Same.
* value-range.h (class fp_prop): Remove.
(FP_PROP_ACCESSOR): Remove.
(class frange_props): Remove
(frange::lower_bound): NANs don't have endpoints.
(frange::upper_bound): Same.
(frange_props::operator==): Remove.
(frange_props::union_): Remove.
(frange_props::inters

Re: [PATCH Rust front-end v2 34/37] gccrs: add lang.opt

2022-09-14 Thread Richard Biener via Gcc-patches
On Wed, Sep 14, 2022 at 6:20 PM Thomas Schwinge  wrote:
>
> Hi!
>
> On 2022-09-14T15:39:47+0200, Richard Biener via Gcc-patches 
>  wrote:
> > On Wed, Aug 24, 2022 at 2:13 PM  wrote:
> >>
> >> From: Philip Herron 
> >>
> >> We have some rust specific langugage options note -fwrapv is enabled by
> >> default in the code. We are trying to respect options such as
> >> -Wunused-result which we get by porting over c++ no-discard for rust's
> >> must-use attribute, so we have enabled these by default directly here.
> >
> > LGTM
>
> Actually, NACK.  ;-)
>
> See 
> "gccrs setting warn_unused_variable breaks thousands of non-Rust tests".
> The 'Init(1)' in 'gcc/rust/lang.opt' are in conflict with any (default)
> 'Init(0)' in other '*.opt' files -- remember that all '*.opt' files are
> processed together by GCC's "options machinery", and thus
> 'gcc/rust/lang.opt' may (and here, does) affect non-Rust front end code.

Ah, I wondered about the duplicates adding to the list of supported FEs, I guess
that the awk script should check for obvious mismatches in other settings?

> I do have a patch series adding a 'LangInit(@var{language}, @var{value})'
> option property, and patches to use this in a lot of places (here and in
> other front ends' '*.opt' files), where currently we implement such logic
> in '*.cc' files; '[...]_init_options_struct' functions via
> 'LANG_HOOKS_INIT_OPTIONS_STRUCT' (those then largely become empty and may
> be removed).  I assume this idea to be uncontroversial; I "just" need to
> get it polished and submitted...
>
>
> Grüße
>  Thomas
>
>
> >>  gcc/rust/lang.opt | 118 ++
> >>  1 file changed, 118 insertions(+)
> >>  create mode 100644 gcc/rust/lang.opt
> >>
> >> diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
> >> new file mode 100644
> >> index 000..1f6855ede1d
> >> --- /dev/null
> >> +++ b/gcc/rust/lang.opt
> >> @@ -0,0 +1,118 @@
> >> +; Options for the Rust front end.
> >> +; Copyright (C) 2003-2022 Free Software Foundation, Inc.
> >> +;
> >> +; This file is part of GCC.
> >> +;
> >> +; GCC is free software; you can redistribute it and/or modify it under
> >> +; the terms of the GNU General Public License as published by the Free
> >> +; Software Foundation; either version 3, or (at your option) any later
> >> +; version.
> >> +;
> >> +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> >> +; WARRANTY; without even the implied warranty of MERCHANTABILITY or
> >> +; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> >> +; for more details.
> >> +;
> >> +; You should have received a copy of the GNU General Public License
> >> +; along with GCC; see the file COPYING3.  If not see
> >> +; .
> >> +
> >> +; See the GCC internals manual for a description of this file's format.
> >> +
> >> +; Please try to keep this file in ASCII collating order.
> >> +
> >> +; Describes command-line options used by this frontend
> >> +
> >> +Language
> >> +Rust
> >> +
> >> +I
> >> +Rust Joined Separate
> >> +; Documented in c.opt
> >> +
> >> +L
> >> +Rust Joined Separate
> >> +; Not documented
> >> +
> >> +Wall
> >> +Rust
> >> +; Documented in c.opt
> >> +
> >> +Wunused-variable
> >> +Rust Var(warn_unused_variable) Init(1) Warning
> >> +; documented in common.opt
> >> +
> >> +Wunused-const-variable
> >> +Rust Warning Alias(Wunused-const-variable=, 2, 0)
> >> +Warn when a const variable is unused.
> >> +
> >> +Wunused-const-variable=
> >> +Rust Joined RejectNegative UInteger Var(warn_unused_const_variable) 
> >> Init(1) Warning LangEnabledBy(Rust,Wunused-variable, 1, 0) IntegerRange(0, 
> >> 2)
> >> +Warn when a const variable is unused.
> >> +
> >> +Wunused-result
> >> +Rust Var(warn_unused_result) Init(1) Warning
> >> +Warn if a caller of a function, marked with attribute warn_unused_result, 
> >> does not use its return value.
> >> +
> >> +frust-crate=
> >> +Rust Joined RejectNegative
> >> +-frust-crate= Set the crate name for the compilation
> >> +
> >> +frust-debug
> >> +Rust Var(flag_rust_debug)
> >> +Dump various Rust front end internals.
> >> +
> >> +frust-dump-
> >> +Rust Joined RejectNegative
> >> +-frust-dump- Dump Rust frontend internal information.
> >> +
> >> +frust-max-recursion-depth=
> >> +Rust RejectNegative Type(int) Var(rust_max_recursion_depth) Init(64)
> >> +-frust-max-recursion-depth=integer
> >> +
> >> +frust-mangling=
> >> +Rust Joined RejectNegative Enum(frust_mangling) Var(flag_rust_mangling)
> >> +-frust-mangling=[legacy|v0] Choose which version to use for name 
> >> mangling
> >> +
> >> +Enum
> >> +Name(frust_mangling) Type(int) UnknownError(unknown rust mangling option 
> >> %qs)
> >> +
> >> +EnumValue
> >> +Enum(frust_mangling) String(legacy) Value(0)
> >> +
> >> +EnumValue
> >> +Enum(frust_mangling) String(v0) Value(1)
> >> +
> >> +frust-cfg=
> >> +Rust Joined RejectNegative
> >> +-frust-cfg= Set

Re: [PATCH] Optimize (X<

2022-09-14 Thread Richard Biener via Gcc-patches
On Wed, Sep 14, 2022 at 11:42 PM Marc Glisse via Gcc-patches
 wrote:
>
> On Tue, 13 Sep 2022, Roger Sayle wrote:
>
> > This patch tweaks the match.pd transformation previously added to fold
> > (X< > (wrapping) types, to also allow signed integer types provided that they
> > don't trap and the overflow needn't be preserved for sanitization.
> > i.e. this should now apply (by default) for "int x,y;", but is disabled
> > with -ftrapv.
>
> In https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html , I
> read:
>
> "Bitwise operators act on the representation of the value including both
> the sign and value bits, where the sign bit is considered immediately
> above the highest-value value bit. Signed ‘>>’ acts on negative numbers by
> sign extension.
>
> As an extension to the C language, GCC does not use the latitude given in
> C99 and C11 only to treat certain aspects of signed ‘<<’ as undefined."

Oh, I wasn't aware of that.

> To me, this means that for instance INT_MIN<<1 is well defined and
> evaluates to 0. But with this patch we turn (INT_MIN<<1)+(INT_MIN<<1) into
> (INT_MIN+INT_MIN)<<1, which is UB.
>
> If we decide not to support this extension anymore, I think we need to
> change the documentation first.

Or perform the (X+Y) operation in an unsigned type.

Richard.

> --
> Marc Glisse


Re: float.h: Do not define INFINITY for C2x when infinities not supported

2022-09-14 Thread Richard Biener via Gcc-patches
On Thu, Sep 15, 2022 at 1:02 AM Joseph Myers  wrote:
>
> C2x has changed the rules for defining INFINITY in  so it is
> no longer defined when float does not support infinities, instead of
> being defined to an expression that overflows at translation time.
> Thus, make the definition conditional on __FLT_HAS_INFINITY__ (this is
> already inside a C2x-conditional part of , because previous C
> standard versions only had this macro in ).
>
> Bootstrapped with no regressions for x86_64-pc-linux-gnu.  Also did a
> spot test of the case of no infinities supported by building cc1 for
> vax-netbsdelf and testing compiling the new c2x-float-11.c test with
> it.

Ok

> gcc/
> * ginclude/float.h (INFINITY): Define only if
> [__FLT_HAS_INFINITY__].
>
> gcc/testsuite/
> * gcc.dg/c2x-float-2.c: Require inff effective-target.
> * gcc.dg/c2x-float-11.c: New test.
>
> diff --git a/gcc/ginclude/float.h b/gcc/ginclude/float.h
> index 9d368c4afa5..afe4a712878 100644
> --- a/gcc/ginclude/float.h
> +++ b/gcc/ginclude/float.h
> @@ -257,9 +257,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. 
>  If not, see
>  #define DBL_IS_IEC_60559   __DBL_IS_IEC_60559__
>  #define LDBL_IS_IEC_60559  __LDBL_IS_IEC_60559__
>
> -/* Infinity in type float, or overflow if infinity not supported.  */
> +/* Infinity in type float; not defined if infinity not supported.  */
> +#if __FLT_HAS_INFINITY__
>  #undef INFINITY
>  #define INFINITY   (__builtin_inff ())
> +#endif
>
>  /* Quiet NaN, if supported for float.  */
>  #if __FLT_HAS_QUIET_NAN__
> diff --git a/gcc/testsuite/gcc.dg/c2x-float-11.c 
> b/gcc/testsuite/gcc.dg/c2x-float-11.c
> new file mode 100644
> index 000..0e2f3c0c97a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/c2x-float-11.c
> @@ -0,0 +1,9 @@
> +/* Test INFINITY macro.  Test when infinities not supported.  */
> +/* { dg-do compile { target { ! inff } } } */
> +/* { dg-options "-std=c2x" } */
> +
> +#include 
> +
> +#ifdef INFINITY
> +#error "INFINITY defined"
> +#endif
> diff --git a/gcc/testsuite/gcc.dg/c2x-float-2.c 
> b/gcc/testsuite/gcc.dg/c2x-float-2.c
> index 4f669fd39bc..61a77f6f2db 100644
> --- a/gcc/testsuite/gcc.dg/c2x-float-2.c
> +++ b/gcc/testsuite/gcc.dg/c2x-float-2.c
> @@ -1,8 +1,8 @@
> -/* Test INFINITY macro.  Generic test even if infinities not
> -   supported.  */
> +/* Test INFINITY macro.  Generic test.  */
>  /* { dg-do run } */
>  /* { dg-options "-std=c2x -w" } */
>  /* { dg-add-options ieee } */
> +/* { dg-require-effective-target inff } */
>
>  #include 
>
>
> --
> Joseph S. Myers
> jos...@codesourcery.com


[r13-2665 Regression] FAIL: c-c++-common/gomp/target-50.c -std=c++98 scan-tree-dump-times gimple "map\\(struct:\\*tmp \\[len: 1\\]\\) map\\(alloc:tmp[._0-9]*->arr \\[len: [0-9]+\\]\\) map\\(tofrom:\\

2022-09-14 Thread haochen.jiang via Gcc-patches
On Linux/x86_64,

23baa717c991d77f206a9358ce2c04960ccf9eea is the first bad commit
commit 23baa717c991d77f206a9358ce2c04960ccf9eea
Author: Julian Brown 
Date:   Wed Feb 16 09:15:39 2022 -0800

OpenMP/OpenACC struct sibling list gimplification extension and rework

caused

FAIL: c-c++-common/gomp/target-50.c scan-tree-dump-times gimple 
"map\\(struct:\\*tmp \\[len: 1\\]\\) map\\(alloc:tmp[._0-9]*->arr \\[len: 
[0-9]+\\]\\) map\\(tofrom:\\*_[0-9]+ \\[len: [0-9]+\\]\\) 
map\\(attach:tmp[._0-9]*->arr \\[bias: 0\\]\\)" 2
FAIL: c-c++-common/gomp/target-50.c  -std=c++14  scan-tree-dump-times gimple 
"map\\(struct:\\*tmp \\[len: 1\\]\\) map\\(alloc:tmp[._0-9]*->arr \\[len: 
[0-9]+\\]\\) map\\(tofrom:\\*_[0-9]+ \\[len: [0-9]+\\]\\) 
map\\(attach:tmp[._0-9]*->arr \\[bias: 0\\]\\)" 2
FAIL: c-c++-common/gomp/target-50.c  -std=c++17  scan-tree-dump-times gimple 
"map\\(struct:\\*tmp \\[len: 1\\]\\) map\\(alloc:tmp[._0-9]*->arr \\[len: 
[0-9]+\\]\\) map\\(tofrom:\\*_[0-9]+ \\[len: [0-9]+\\]\\) 
map\\(attach:tmp[._0-9]*->arr \\[bias: 0\\]\\)" 2
FAIL: c-c++-common/gomp/target-50.c  -std=c++20  scan-tree-dump-times gimple 
"map\\(struct:\\*tmp \\[len: 1\\]\\) map\\(alloc:tmp[._0-9]*->arr \\[len: 
[0-9]+\\]\\) map\\(tofrom:\\*_[0-9]+ \\[len: [0-9]+\\]\\) 
map\\(attach:tmp[._0-9]*->arr \\[bias: 0\\]\\)" 2
FAIL: c-c++-common/gomp/target-50.c  -std=c++98  scan-tree-dump-times gimple 
"map\\(struct:\\*tmp \\[len: 1\\]\\) map\\(alloc:tmp[._0-9]*->arr \\[len: 
[0-9]+\\]\\) map\\(tofrom:\\*_[0-9]+ \\[len: [0-9]+\\]\\) 
map\\(attach:tmp[._0-9]*->arr \\[bias: 0\\]\\)" 2

with GCC configured with

../../gcc/configure 
--prefix=/export/users/haochenj/src/gcc-bisect/master/master/r13-2665/usr 
--enable-clocale=gnu --with-system-zlib --with-demangler-in-ld 
--with-fpmath=sse --enable-languages=c,c++,fortran --enable-cet --without-isl 
--enable-libmpx x86_64-linux --disable-bootstrap

To reproduce:

$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="gomp.exp=c-c++-common/gomp/target-50.c 
--target_board='unix{-m32}'"
$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="gomp.exp=c-c++-common/gomp/target-50.c --target_board='unix{-m32\ 
-march=cascadelake}'"
$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="gomp.exp=c-c++-common/gomp/target-50.c 
--target_board='unix{-m64}'"
$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="gomp.exp=c-c++-common/gomp/target-50.c --target_board='unix{-m64\ 
-march=cascadelake}'"

(Please do not reply to this email, for question about this report, contact me 
at haochen dot jiang at intel.com)


[r13-2666 Regression] FAIL: g++.dg/goacc/mdc.C -std=c++98 (test for excess errors) on Linux/x86_64

2022-09-14 Thread haochen.jiang via Gcc-patches
On Linux/x86_64,

f469ce1d3ef94092647125662ddd93847712909f is the first bad commit
commit f469ce1d3ef94092647125662ddd93847712909f
Author: Julian Brown 
Date:   Tue Sep 6 22:34:38 2022 +

OpenMP/OpenACC: mapping group list-handling improvements

caused

FAIL: c-c++-common/goacc/mdc-2.c  -std=c++14 (test for excess errors)
FAIL: c-c++-common/goacc/mdc-2.c  -std=c++17 (test for excess errors)
FAIL: c-c++-common/goacc/mdc-2.c  -std=c++20 (test for excess errors)
FAIL: c-c++-common/goacc/mdc-2.c  -std=c++98 (test for excess errors)
FAIL: c-c++-common/goacc/mdc-2.c (test for excess errors)
FAIL: g++.dg/goacc/mdc.C  -std=c++14 (test for excess errors)
FAIL: g++.dg/goacc/mdc.C  -std=c++17 (test for excess errors)
FAIL: g++.dg/goacc/mdc.C  -std=c++20 (test for excess errors)
FAIL: g++.dg/goacc/mdc.C  -std=c++98 (test for excess errors)

with GCC configured with

../../gcc/configure 
--prefix=/export/users/haochenj/src/gcc-bisect/master/master/r13-2666/usr 
--enable-clocale=gnu --with-system-zlib --with-demangler-in-ld 
--with-fpmath=sse --enable-languages=c,c++,fortran --enable-cet --without-isl 
--enable-libmpx x86_64-linux --disable-bootstrap

To reproduce:

$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="goacc.exp=c-c++-common/goacc/mdc-2.c --target_board='unix{-m32}'"
$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="goacc.exp=c-c++-common/goacc/mdc-2.c --target_board='unix{-m32\ 
-march=cascadelake}'"
$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="goacc.exp=c-c++-common/goacc/mdc-2.c --target_board='unix{-m64}'"
$ cd {build_dir}/gcc && make check 
RUNTESTFLAGS="goacc.exp=c-c++-common/goacc/mdc-2.c --target_board='unix{-m64\ 
-march=cascadelake}'"
$ cd {build_dir}/gcc && make check RUNTESTFLAGS="goacc.exp=g++.dg/goacc/mdc.C 
--target_board='unix{-m32}'"
$ cd {build_dir}/gcc && make check RUNTESTFLAGS="goacc.exp=g++.dg/goacc/mdc.C 
--target_board='unix{-m32\ -march=cascadelake}'"
$ cd {build_dir}/gcc && make check RUNTESTFLAGS="goacc.exp=g++.dg/goacc/mdc.C 
--target_board='unix{-m64}'"
$ cd {build_dir}/gcc && make check RUNTESTFLAGS="goacc.exp=g++.dg/goacc/mdc.C 
--target_board='unix{-m64\ -march=cascadelake}'"

(Please do not reply to this email, for question about this report, contact me 
at haochen dot jiang at intel.com)


[PATCH] testsuite: Disable zero-scratch-regs-{7, 9, 11}.c on arm

2022-09-14 Thread Torbjörn SVENSSON via Gcc-patches
-fzero-call-used-regs=all and -fzero-call-used-regs=all-gpr are not
supported on arm*. On arm-none-eabi, the testcases fails with:

  sorry, unimplemented: '-fzero-call-used-regs' not supported on this target

2022-09-15  Torbjörn SVENSSON  

gcc/testsuite/ChangeLog:

* c-c++-common/zero-scratch-regs-7.c: Skip on arm.
* c-c++-common/zero-scratch-regs-9.c: Likewise.
* c-c++-common/zero-scratch-regs-11.c: Likewise.

Co-Authored-By: Yvan ROUX  
Signed-off-by: Torbjörn SVENSSON  
---
 gcc/testsuite/c-c++-common/zero-scratch-regs-11.c | 2 +-
 gcc/testsuite/c-c++-common/zero-scratch-regs-7.c  | 1 +
 gcc/testsuite/c-c++-common/zero-scratch-regs-9.c  | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c 
b/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
index b7739b2c6f6..6fd2a1dc382 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* loongarch64*-*-* } } } */
+/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* nvptx*-*-* s390*-*-* loongarch64*-*-* } } } */
 /* { dg-options "-O2 -fzero-call-used-regs=all" } */
 
 #include "zero-scratch-regs-10.c"
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-7.c 
b/gcc/testsuite/c-c++-common/zero-scratch-regs-7.c
index 2a4c8b2e73d..c684b4a02f9 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-7.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-7.c
@@ -1,5 +1,6 @@
 /* { dg-do run } */
 /* { dg-skip-if "not implemented" { ia64*-*-* } } */
+/* { dg-skip-if "not implemented" { arm*-*-* } } */
 /* { dg-options "-O2 -fzero-call-used-regs=all-gpr" } */
 
 #include "zero-scratch-regs-1.c"
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c 
b/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
index ea83bc146b7..0e8922053e8 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* loongarch64*-*-* } } } */
+/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* nvptx*-*-* s390*-*-* loongarch64*-*-* } } } */
 /* { dg-options "-O2 -fzero-call-used-regs=all" } */
 
 #include "zero-scratch-regs-1.c"
-- 
2.25.1