[PATCH] match.pd: Some build_nonstandard_integer_type tweaks

2023-09-19 Thread Jakub Jelinek via Gcc-patches
Hi!

As discussed earlier, using build_nonstandard_integer_type blindly for all
INTEGRAL_TYPE_Ps is problematic now that we have BITINT_TYPE, because it
always creates an INTEGRAL_TYPE with some possibly very large precision.
The following patch attempts to deal with 3 such spots in match.pd, others
still need looking at.

In the first case, I think it is quite expensive/undesirable to create
a non-standard INTEGER_TYPE with possibly huge precision and then
immediately just see type_has_mode_precision_p being false for it, or even
worse introducing a cast to TImode or OImode or XImode INTEGER_TYPE which
nothing will be able to actually handle.  128-bit or 64-bit (on 32-bit
targets) types are the largest supported by the backend, so the following
patch avoids creating and matching conversions to larger types, it is
an optimization anyway and so should be used when it is cheap that way.

In the second hunk, I believe the uses of build_nonstandard_integer_type
aren't useful at all.  It is when matching a ? -1 : 0 and trying to express
it as say -(type) (bool) a etc., but this is all GIMPLE only, where most of
integral types with same precision/signedness are compatible and we know
-1 is representable in that type, so I really don't see any reason not to
perform the negation of a [0, 1] valued expression in type, rather
than doing it in
build_nonstandard_integer_type (TYPE_PRECISION (type), TYPE_UNSIGNED (type))
(except that it breaks the BITINT_TYPEs).  I don't think we need to do
something like range_check_type.
While in there, I've also noticed it was using a (with {
tree booltrue = constant_boolean_node (true, boolean_type_node);
} and removed that + replaced uses of booltrue with boolean_true_node
which the above function always returns.

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

2023-09-19  Jakub Jelinek  

* match.pd ((x << c) >> c): Don't call build_nonstandard_integer_type
nor check type_has_mode_precision_p for width larger than [TD]Imode
precision.
(a ? CST1 : CST2): Don't use build_nonstandard_type, just convert
to type.  Use boolean_true_node instead of
constant_boolean_node (true, boolean_type_node).  Formatting fixes.

--- gcc/match.pd.jj 2023-09-18 10:37:56.002965361 +0200
+++ gcc/match.pd2023-09-18 12:14:32.321631010 +0200
@@ -4114,9 +4114,13 @@ (define_operator_list SYNC_FETCH_AND_AND
(if (INTEGRAL_TYPE_P (type))
 (with {
   int width = element_precision (type) - tree_to_uhwi (@1);
-  tree stype = build_nonstandard_integer_type (width, 0);
+  tree stype = NULL_TREE;
+  scalar_int_mode mode = (targetm.scalar_mode_supported_p (TImode)
+ ? TImode : DImode);
+  if (width <= GET_MODE_PRECISION (mode))
+   stype = build_nonstandard_integer_type (width, 0);
  }
- (if (width == 1 || type_has_mode_precision_p (stype))
+ (if (stype && (width == 1 || type_has_mode_precision_p (stype)))
   (convert (convert:stype @0
 
 /* Optimize x >> x into 0 */
@@ -5092,49 +5096,24 @@ (define_operator_list SYNC_FETCH_AND_AND
 /* a ? -1 : 0 -> -a.  No need to check the TYPE_PRECISION not being 1
here as the powerof2cst case above will handle that case correctly.  */
 (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@1))
+ (negate (convert:type (convert:boolean_type_node @0))
+  (if (integer_zerop (@1))
+   (switch
+/* a ? 0 : 1 -> !a. */
+(if (integer_onep (@2))
+ (convert (bit_xor (convert:boolean_type_node @0) { boolean_true_node; })))
+/* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */
+(if (INTEGRAL_TYPE_P (type) && integer_pow2p (@2))
  (with {
-   auto prec = TYPE_PRECISION (type);
-   auto unsign = TYPE_UNSIGNED (type);
-   tree inttype = build_nonstandard_integer_type (prec, unsign);
+   tree shift = build_int_cst (integer_type_node, tree_log2 (@2));
   }
-  (convert (negate (convert:inttype (convert:boolean_type_node @0
-  (if (integer_zerop (@1))
-   (with {
-  tree booltrue = constant_boolean_node (true, boolean_type_node);
-}
-(switch
- /* a ? 0 : 1 -> !a. */
- (if (integer_onep (@2))
-  (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } )))
- /* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */
- (if (INTEGRAL_TYPE_P (type) &&  integer_pow2p (@2))
-  (with {
-   tree shift = build_int_cst (integer_type_node, tree_log2 (@2));
-   }
-   (lshift (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } 
))
-{ shift; })))
- /* a ? -1 : 0 -> -(!a).  No need to check the TYPE_PRECISION not being 1
+  (lshift (convert (bit_xor (convert:boolean_type_node @0)
+   { boolean_true_node; })) { shift; })))
+/* a ? -1 : 0 -> -(!a).  No need to check the TYPE_PRECISION not being 1
here as the powerof2cst case above will handle that case 

[committed] libgomp: Handle NULL environ like pointer to NULL pointer [PR111413]

2023-09-19 Thread Jakub Jelinek via Gcc-patches
Hi!

clearenv function just sets environ to NULL (after sometimes freeing it),
rather than setting it to a pointer to NULL, and our code was assuming
it is always non-NULL.

Fixed thusly, the change seems to be large but actually is just
+  if (environ)
 for (env = environ; *env != 0; env++)
plus reindentation.  I've also noticed the block after this for loop
was badly indented (too much) and fixed that too.

No testcase added, as it needs clearenv + dlopen.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk.

2023-09-19  Jakub Jelinek  

PR libgomp/111413
* env.c (initialize_env): Don't dereference environ if it is NULL.
Reindent.

--- libgomp/env.c.jj2023-06-20 08:57:39.095494805 +0200
+++ libgomp/env.c   2023-09-18 10:53:21.976636936 +0200
@@ -2224,139 +2224,140 @@ initialize_env (void)
   none = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_NO_SUFFIX);
   initialize_icvs (>icvs);
 
-  for (env = environ; *env != 0; env++)
-{
-  if (!startswith (*env, "OMP_"))
-   continue;
-
- /* Name of the environment variable without suffix "OMP_".  */
- char *name = *env + sizeof ("OMP_") - 1;
- for (omp_var = 0; omp_var < OMP_VAR_CNT; omp_var++)
-   {
- if (startswith (name, envvars[omp_var].name))
-   {
- pos = envvars[omp_var].name_len;
- if (name[pos] == '=')
-   {
- pos++;
- flag_var_addr
-   = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_NO_SUFFIX,
-  envvars[omp_var].flag_vars[0],
-  params);
-   }
- else if (startswith ([pos], "_DEV=")
-  && envvars[omp_var].flag & GOMP_ENV_SUFFIX_DEV)
-   {
- pos += 5;
- flag_var_addr
-   = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_DEV,
-  envvars[omp_var].flag_vars[0],
-  params);
-   }
- else if (startswith ([pos], "_ALL=")
-  && envvars[omp_var].flag & GOMP_ENV_SUFFIX_ALL)
-   {
- pos += 5;
- flag_var_addr
-   = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_ALL,
-  envvars[omp_var].flag_vars[0],
-  params);
-   }
- else if (startswith ([pos], "_DEV_")
-  && envvars[omp_var].flag & GOMP_ENV_SUFFIX_DEV_X)
-   {
- pos += 5;
- if (!get_device_num (*env, [pos], _num,
-  _num_len))
-   break;
+  if (environ)
+for (env = environ; *env != 0; env++)
+  {
+   if (!startswith (*env, "OMP_"))
+ continue;
 
- pos += dev_num_len + 1;
- flag_var_addr
-   = add_initial_icv_to_list (dev_num,
-  envvars[omp_var].flag_vars[0],
-  params);
-   }
- else
-   {
- gomp_error ("Invalid environment variable in %s", *env);
- break;
-   }
- env_val = [pos];
-
- if (envvars[omp_var].parse_func (*env, env_val, params))
-   {
- for (i = 0; i < 3; ++i)
-   if (envvars[omp_var].flag_vars[i])
- gomp_set_icv_flag (flag_var_addr,
-envvars[omp_var].flag_vars[i]);
-   else
+   /* Name of the environment variable without suffix "OMP_".  */
+   char *name = *env + sizeof ("OMP_") - 1;
+   for (omp_var = 0; omp_var < OMP_VAR_CNT; omp_var++)
+ {
+   if (startswith (name, envvars[omp_var].name))
+ {
+   pos = envvars[omp_var].name_len;
+   if (name[pos] == '=')
+ {
+   pos++;
+   flag_var_addr
+ = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_NO_SUFFIX,
+envvars[omp_var].flag_vars[0],
+params);
+ }
+   else if (startswith ([pos], "_DEV=")
+&& envvars[omp_var].flag & GOMP_ENV_SUFFIX_DEV)
+ {
+   pos += 5;
+   flag_var_addr
+ = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_DEV,
+envvars[omp_var].flag_vars[0],
+params);
+ }
+   else if (startswith ([pos], "_ALL=")
+&& 

[PATCH] v2: small _BitInt tweaks

2023-09-19 Thread Jakub Jelinek via Gcc-patches
Hi!

On Tue, Sep 12, 2023 at 05:27:30PM +, Joseph Myers wrote:
> On Tue, 12 Sep 2023, Jakub Jelinek via Gcc-patches wrote:
> 
> > And by ensuring we never create 1-bit signed BITINT_TYPE e.g. the backends
> > don't need to worry about them.
> > 
> > But I admit I don't feel strongly about that.
> > 
> > Joseph, what do you think about this?
> 
> I think it's appropriate to avoid 1-bit signed BITINT_TYPE consistently.

Here is a patch which does that.  In addition to the previously changed two
hunks it also adds a checking assertion that we don't create
signed _BitInt(0), unsigned _BitInt(0) or signed _BitInt(1) types.

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

2023-09-18  Jakub Jelinek  

gcc/
* tree.cc (build_bitint_type): Assert precision is not 0, or
for signed types 1.
(signed_or_unsigned_type_for): Return INTEGER_TYPE for signed variant
of unsigned _BitInt(1).
gcc/c-family/
* c-common.cc (c_common_signed_or_unsigned_type): Return INTEGER_TYPE
for signed variant of unsigned _BitInt(1).

--- gcc/tree.cc.jj  2023-09-11 17:01:17.612714178 +0200
+++ gcc/tree.cc 2023-09-18 12:36:37.598912717 +0200
@@ -7179,6 +7179,8 @@ build_bitint_type (unsigned HOST_WIDE_IN
 {
   tree itype, ret;
 
+  gcc_checking_assert (precision >= 1 + !unsignedp);
+
   if (unsignedp)
 unsignedp = MAX_INT_CACHED_PREC + 1;
 
@@ -11096,7 +11098,7 @@ signed_or_unsigned_type_for (int unsigne
   else
 return NULL_TREE;
 
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (TREE_CODE (type) == BITINT_TYPE && (unsignedp || bits > 1))
 return build_bitint_type (bits, unsignedp);
   return build_nonstandard_integer_type (bits, unsignedp);
 }
--- gcc/c-family/c-common.cc.jj 2023-09-11 17:01:17.517715431 +0200
+++ gcc/c-family/c-common.cc2023-09-18 12:35:06.829126858 +0200
@@ -2739,7 +2739,9 @@ c_common_signed_or_unsigned_type (int un
   || TYPE_UNSIGNED (type) == unsignedp)
 return type;
 
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (TREE_CODE (type) == BITINT_TYPE
+  /* signed _BitInt(1) is invalid, avoid creating that.  */
+  && (unsignedp || TYPE_PRECISION (type) > 1))
 return build_bitint_type (TYPE_PRECISION (type), unsignedp);
 
 #define TYPE_OK(node)  \


Jakub



Patch ping: [PATCH] testsuite work-around compound-assignment-1.c C++ failures on various targets [PR111377]

2023-09-19 Thread Jakub Jelinek via Gcc-patches
Hi!

On Tue, Sep 12, 2023 at 09:02:55AM +0200, Jakub Jelinek via Gcc-patches wrote:
> On Mon, Sep 11, 2023 at 11:11:30PM +0200, Jakub Jelinek via Gcc-patches wrote:
> > On Mon, Sep 11, 2023 at 07:27:57PM +0200, Benjamin Priour via Gcc-patches 
> > wrote:
> > > Thanks for the report,
> > > 
> > > After investigation it seems the location of the new dejagnu directive for
> > > C++ differs depending on the configuration.
> > > The expected warning is still emitted, but its location differ slightly.
> > > I expect it to be not an issue per se of the analyzer, but a divergence in
> > > the FE between the two configurations.
> > 
> > I think the divergence is whether called_by_test_5b returns the struct
> > in registers or in memory.  If in memory (like in the x86_64 -m32 case), we 
> > have
> >   [compound-assignment-1.c:71:21] D.3191 = called_by_test_5b (); [return 
> > slot optimization]
> >   [compound-assignment-1.c:71:21 discrim 1] D.3191 ={v} {CLOBBER(eol)};
> >   [compound-assignment-1.c:72:1] return;
> > in the IL, while if in registers (like x86_64 -m64 case), just
> >   [compound-assignment-1.c:71:21] D.3591 = called_by_test_5b ();
> >   [compound-assignment-1.c:72:1] return;
> > 
> > If you just want to avoid the differences, putting } on the same line as the
> > call might be a usable workaround for that.
> 
> Here is the workaround in patch form.  Tested on x86_64-linux -m32/-m64, ok
> for trunk?

I'd like to ping this patch.

> 2023-09-12  Jakub Jelinek  
> 
>   PR testsuite/111377
>   * c-c++-common/analyzer/compound-assignment-1.c (test_5b): Move
>   closing } to the same line as the call to work-around differences in
>   diagnostics line.
> 
> --- gcc/testsuite/c-c++-common/analyzer/compound-assignment-1.c.jj
> 2023-09-11 11:05:47.523727789 +0200
> +++ gcc/testsuite/c-c++-common/analyzer/compound-assignment-1.c   
> 2023-09-12 08:58:52.854231161 +0200
> @@ -68,5 +68,8 @@ called_by_test_5b (void)
>  
>  void test_5b (void)
>  {
> -  called_by_test_5b ();
> -} /* { dg-warning "leak of '.ptr_wrapper::ptr'" "" { target c++ } 
> } */
> +  called_by_test_5b (); }
> +/* { dg-warning "leak of '.ptr_wrapper::ptr'" "" { target c++ } 
> .-1 } */
> +/* The closing } above is intentionally on the same line as the call, because
> +   otherwise the exact line of the diagnostics depends on whether the
> +   called_by_test_5b () call satisfies aggregate_value_p or not.  */
> 
> 
>   Jakub

Jakub



C++ patch ping

2023-09-19 Thread Jakub Jelinek via Gcc-patches
Hi!

I'd like to ping a couple of C++ patches.  All of them together
with the 2 updated patches posted yesterday have been
bootstrapped/regtested on x86_64-linux and i686-linux again yesterday.

- c++: Implement C++26 P2361R6 - Unevaluated strings [PR110342]
  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628375.html

- c++: Implement C++26 P2741R3 - user-generated static_assert messages 
[PR110348]
  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628378.html

- c++: Implement C++ DR 2406 - [[fallthrough]] attribute and iteration 
statements
  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628487.html
  (from this one Richi approved the middle-end changes)

- c++: Implement C++26 P1854R4 - Making non-encodable string literals 
ill-formed [PR110341]
  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628490.html

- libcpp, v2: Small incremental patch for P1854R4 [PR110341]
  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628586.html

Thanks

Jakub



[PATCH] c++, v2: Implement C++26 P2741R3 - user-generated static_assert messages [PR110348]

2023-09-18 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 24, 2023 at 04:30:51PM +0200, Jakub Jelinek via Gcc-patches wrote:
> The following patch on top of PR110349 patch (weak dependency,
> only for -Wc++26-extensions, I could split that part into an independent
> patch) and PR110342 patch (again weak dependency, this time mainly
> because it touches the same code in cp_parser_static_assert and
> nearby spot in udlit-error1.C testcase) implements the user generated
> static_assert messages next to string literals.
> 
> As I wrote already in the PR, in addition to looking through the paper
> I looked at the clang++ testcase for this feature implemented there from
> paper's author and on godbolt played with various parts of the testcase
> coverage below, and there are 4 differences between what the patch
> implements and what clang++ implements.
> 
> The first is that clang++ diagnoses if M.size () or M.data () methods
> are present, but aren't constexpr; while the paper introduction talks about
> that, the standard wording changes don't seem to require that, all they say
> is that those methods need to exist (assuming accessible and the like)
> and be implicitly convertible to std::size_t or const char *, but rest is
> only if the static assertion fails.  If there is intent to change that
> wording, the question is how far to go, e.g. while M.size () could be
> constexpr, they could e.g. return some class object which wouldn't have
> constexpr conversion operator to size_t/const char * and tons of other
> reasons why the constant evaluation could fail.  Without actually evaluating
> it I don't see how we could guarantee anything for non-failed static_assert.
> 
> The second and most important is that clang++ has a couple of tests (and the
> testcase below as well) where M.data () is not a core constant expression
> but M.data ()[0] ... M.data ()[M.size () - 1] is integer constant
> expression.  From my reading of http://eel.is/c++draft/dcl.pre#11.2.2
> that means those should be rejected (examples of these are e.g.
> static_assert (false, T{});
> in the testcase, where T{}.data () returns pointer returned from new
> expression, but T{}'s destructor then deletes it, making it point to
> no longer live object.  Or
> static_assert (false, a);
> where a.data () returns  but because a is constexpr automatic variable,
> that isn't valid core constant expression, while a.data ()[0] is.
> There are a couple of others.  Now, it seems allowing that is quite useful
> in real-world, but the question is with what standard changes to achieve
> that.  One possibility would be s/a core constant/an/; from implementation
> POV that would mean that if M.size () is 0, then M.data () doesn't have
> to be constexpr at all.  Otherwise, implementation could try to evaluate
> silently M.data () as constant expression, if it would be one, it could
> just use c_getstr in the GCC case as the patch does + optionally the 2
> M.data ()[0] and M.data ()[M.size () - 1] tests to verify boundary cases
> more carefully.  And if it wouldn't be one, it would need to evaluate
> M.data ()[i] for i in [0, M.size () - 1] to get all the characters one by
> one.  Another possibility would be to require that say ((void) (M.data ()), 0)
> is a constant expression, that doesn't help much with the optimized way
> to get at the message characters, but would require that data () is
> constexpr even for the 0 case etc.
> 
> The third difference is that 
> static_assert (false, "foo"_myd);
> in the testcase is normal failed static assertion and
> static_assert (true, "foo"_myd);
> would be accepted, while clang++ rejects it.  IMHO
> "foo"_myd doesn't match the syntactic requirements of unevaluated-string
> as mentioned in http://eel.is/c++draft/dcl.pre#10 , and because
> a constexpr udlit operator can return something which is valid, it shouldn't
> be rejected just in case.
> 
> Last is clang++ ICEs on non-static data members size/data.
> 
> The patch implements what I see in the paper, because it is unclear what
> further changes will be voted in (and the changes can be done at that
> point).
> The patch uses tf_none in 6 spots so that just the static_assert specific
> errors are emitted and not others, but it would certainly be possible to
> use complain instead of tf_none there, get more errors in some cases, but
> perhaps help users figure out what exactly is wrong in detail.

Here is an updated version of the patch.
Compared to the last version, based on the discussion in the PR, the patch
1) warns (but only that) if size()/data() methods aren't declared
   constexpr/consteval (or implicitly constexpr)
2) as I don't see a function which would determine if some expression
   is core constant expression (for the data() case), the patch just as an
   optim

[PATCH] c++, v2: Implement C++26 P2169R4 - Placeholder variables with no name [PR110349]

2023-09-18 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 22, 2023 at 09:39:11AM +0200, Jakub Jelinek via Gcc-patches wrote:
> The following patch implements the C++26 P2169R4 paper.
> As written in the PR, the patch expects that:
> 1) https://eel.is/c++draft/expr.prim.lambda.capture#2
>"Ignoring appearances in initializers of init-captures, an identifier
> or this shall not appear more than once in a lambda-capture."
>is adjusted such that name-independent lambda captures with initializers
>can violate this rule (but lambda captures which aren't name-independent
>can't appear after name-independent ones)
> 2) https://eel.is/c++draft/class.mem#general-5
>"A member shall not be declared twice in the member-specification,
> except that"
>having an exception that name-independent non-static data member
>declarations can appear multiple times (but again, if there is
>a member which isn't name-independent, it can't appear after
>name-independent ones)
> 3) it assumes that any name-independent declarations which weren't
>previously valid result in the _ lookups being ambiguous, not just
>if there are 2 _ declarations in the same scope, in particular the
>https://eel.is/c++draft/basic.scope#block-2 mentioned cases
> 4) it assumes that _ in static function/block scope structured bindings
>is never name-independent like in namespace scope structured bindings;
>it matches clang behavior and is consistent with e.g. static type _;
>not being name-independent both at namespace scope and at function/block
>scope
> 
> As you preferred in the PR, for local scope bindings, the ambiguous cases
> use a TREE_LIST with the ambiguous cases which can often be directly fed
> into print_candidates.  For member_vec after sorting/deduping, I chose to use
> instead OVERLOAD with a new flag but only internally inside of the
> member_vec, get_class_binding_direct turns it into a TREE_LIST.  There are
> 2 reasons for that, in order to keep the member_vec binary search fast, I
> think it is better to keep OVL_NAME usable on all elements because having
> to special case TREE_LIST would slow everything down, and the callers need
> to be able to chain the results anyway and so need an unshared TREE_LIST
> they can tweak/destroy anyway.
> name-independent declarations (even in older standards) will not have
> -Wunused{,-variable,-but-set-variable} or -Wshadow* warnings diagnosed, but
> unlike e.g. the clang implementation, this patch does diagnose
> -Wunused-parameter for parameters with _ names because they aren't
> name-independent and one can just omit their name instead.

The patch no longer applies, because of the check_local_shadow changes.

Here is a new version which applies and has testsuite adjusted for that.

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

2023-09-18  Jakub Jelinek  

PR c++/110349
gcc/
* doc/invoke.texi (-Wno-c++26-extensions): Document.
gcc/c-family/
* c.opt (Wc++26-extensions): New option.
* c-cppbuiltin.cc (c_cpp_builtins): Predefine
__cpp_placeholder_variables=202306L for C++26.
gcc/cp/
* cp-tree.h: Implement C++26 P2169R4 - Placeholder variables with no
name.
(OVL_PLACEHOLDER_P): Define.
(add_capture): Add unsigned * argument.
(name_independent_decl_p): New inline function.
* name-lookup.cc (class name_lookup): Make ambiguous and
add_value members public.
(placeholder_linear_search): New function.
(get_class_binding_direct): Handle member_vec_binary_search
returning OVL_PLACEHOLDER_P OVERLOAD.  Use
placeholder_linear_search rather than fields_linear_search
for linear lookup of _ name if !want_type.
(member_name_cmp): Sort name-independent declarations first.
(member_vec_dedup): Handle name-independent declarations.
(pop_local_binding): Handle binding->value being a TREE_LIST for
ambiguous name-independent declarations.
(supplement_binding): Handle name-independent declarations.
(update_binding): Likewise.
(check_local_shadow): Return tree rather than void, normally
NULL_TREE but old for name-independent declarations which used
to conflict with outer scope declaration.  Don't emit -Wshadow*
warnings for name-independent declarations.
(pushdecl): Handle name-independent declarations.
(lookup_name): Likewise.
* search.cc (lookup_field_r): Handle nval being a TREE_LIST.
* lambda.cc (build_capture_proxy): Adjust for ___.
names of members.
(add_capture): Add PLACEHOLDER_CNT argument.  Use ___.
name rather than ___ for second and following capture with
_ name.
(add_default_capture): Adjust add_capture caller.
* decl.cc (poplevel): D

Patch ping: Re: [PATCH] c, c++, v2: Accept __builtin_classify_type (typename)

2023-09-18 Thread Jakub Jelinek via Gcc-patches
Hi!

I'd like to ping this patch.
The C++ FE part has been approved by Jason already with a minor change
I've made in my copy.
Are the remaining parts ok for trunk?

On Fri, Aug 11, 2023 at 10:48:19AM +0200, Jakub Jelinek via Gcc-patches wrote:
> 2023-08-11  Jakub Jelinek  
> 
> gcc/
>   * builtins.h (type_to_class): Declare.
>   * builtins.cc (type_to_class): No longer static.  Return
>   int rather than enum.
>   * doc/extend.texi (__builtin_classify_type): Document.
> gcc/c/
>   * c-parser.cc (c_parser_postfix_expression_after_primary): Parse
>   __builtin_classify_type call with typename as argument.
> gcc/cp/
>   * parser.cc (cp_parser_postfix_expression): Parse
>   __builtin_classify_type call with typename as argument.
>   * pt.cc (tsubst_copy_and_build): Handle __builtin_classify_type
>   with dependent typename as argument.
> gcc/testsuite/
>   * c-c++-common/builtin-classify-type-1.c: New test.
>   * g++.dg/ext/builtin-classify-type-1.C: New test.
>   * g++.dg/ext/builtin-classify-type-2.C: New test.
>   * gcc.dg/builtin-classify-type-1.c: New test.

Thanks

Jakub



Re: [PATCH] MATCH: Make zero_one_valued_p non-recusive fully

2023-09-18 Thread Jakub Jelinek via Gcc-patches
On Mon, Sep 18, 2023 at 11:04:16AM +0200, Richard Biener via Gcc-patches wrote:
> > Note genmatch should warn (or error out) if this gets detected so I filed 
> > PR 111446
> > which I will be looking into next week or the week after so we don't run 
> > into
> > this issue again.
> >
> > PR tree-optimization/111442
> >
> > gcc/ChangeLog:
> >
> > * match.pd (zero_one_valued_p): Have the bit_and match not be
> > recusive.

s/recusive/recursive/g
s/recusion/recursion/g

> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index 887665633d4..773c3810f51 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -2183,8 +2183,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >
> >  /* (a&1) is always [0,1] too. This is useful again when
> > the range is not known. */
> > +/* Note this can't be recusive due to VN handling of equivalents,
> > +   VN and would cause an infinite recusion. */
> >  (match zero_one_valued_p
> > - (bit_and:c@0 @1 zero_one_valued_p))
> > + (bit_and:c@0 @1 integer_onep)
> > + (if (INTEGRAL_TYPE_P (type
> >
> >  /* A conversion from an zero_one_valued_p is still a [0,1].
> > This is useful when the range of a variable is not known */
> > diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111442-1.c 
> > b/gcc/testsuite/gcc.c-torture/compile/pr111442-1.c
> > new file mode 100644
> > index 000..5814ee938de
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.c-torture/compile/pr111442-1.c
> > @@ -0,0 +1,13 @@
> > +
> > +int *a, b;
> > +int main() {
> > +  int d = 1, e;
> > +  if (d)
> > +e = a ? 0 % 0 : 0;
> > +  if (d)
> > +a = 
> > +  d = -1;
> > +  b = d & e;
> > +  b = 2 * e ^ 1;
> > +  return 0;
> > +}
> > --
> > 2.31.1
> >

Jakub



Re: [PATCH] tree-optimization/111294 - backwards threader PHI costing

2023-09-18 Thread Jakub Jelinek via Gcc-patches
On Thu, Sep 14, 2023 at 01:23:13PM +, Richard Biener via Gcc-patches wrote:
> diff --git a/libgomp/team.c b/libgomp/team.c
> index 54dfca8080a..e5a86de1dd0 100644
> --- a/libgomp/team.c
> +++ b/libgomp/team.c
> @@ -756,8 +756,9 @@ gomp_team_start (void (*fn) (void *), void *data, 
> unsigned nthreads,
>attr = _attr;
>  }
>  
> -  start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
> - * (nthreads - i));
> +  if (i < nthreads)
> +start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
> +   * (nthreads - i));
>  
>/* Launch new threads.  */
>for (; i < nthreads; ++i)

Wouldn't just
  if (i >= nthreads)
__builtin_unreachable ();
do the trick as well?
I'd prefer not to add further runtime checks here if possible.

Jakub



Re: [pushed] c++: __integer_pack with class argument [PR111357]

2023-09-12 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 12, 2023 at 01:34:43PM -0400, Marek Polacek via Gcc-patches wrote:
> On Tue, Sep 12, 2023 at 01:27:44PM -0400, Jason Merrill via Gcc-patches wrote:
> > Tested x86_64-pc-linux-gnu, applying to trunk.
> > 
> > -- 8< --
> > 
> > The argument might not already be an integer.
> > 
> > PR c++/111357
> > 
> > gcc/cp/ChangeLog:
> > 
> > * pt.cc (expand_integer_pack): Convert argument to int.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/ext/integer-pack7.C: New test.
> > ---
> >  gcc/cp/pt.cc |  2 ++
> >  gcc/testsuite/g++.dg/ext/integer-pack7.C | 38 
> >  2 files changed, 40 insertions(+)
> >  create mode 100644 gcc/testsuite/g++.dg/ext/integer-pack7.C
> > 
> > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > index 838179d5fe3..b583c11eb99 100644
> > --- a/gcc/cp/pt.cc
> > +++ b/gcc/cp/pt.cc
> > @@ -3793,6 +3793,8 @@ expand_integer_pack (tree call, tree args, 
> > tsubst_flags_t complain,
> >  }
> >else
> >  {
> > +  hi = perform_implicit_conversion_flags (integer_type_node, hi, 
> > complain,
> > + LOOKUP_IMPLICIT);
> 
> FWIW, we have perform_implicit_conversion for this.

Is it correct to convert exactly to integer_type_node though?
Consider
#include 

using std::integer_sequence;
using std::make_integer_sequence;

template
void g(integer_sequence)
{}

template
struct c1
{
  static constexpr int value = 1;
  constexpr operator int() { return value; } 
  constexpr operator long() { return value + 1; }
};
template
struct R
{
using S = make_integer_sequence{}>;

R() noexcept(noexcept(g(S(
{}
};
int main()
{
R();
}
Shouldn't that invoke c1{}.operator long() rather than operator int()?
I thought the conversion was supposed to be done a few lines earlier,
instead of doing
  CALL_EXPR_ARG (call, 0) = hi;
do
  CALL_EXPR_ARG (call, 0)
= perform_implicit_conversion_flags (TREE_TYPE (ohi), hi,
 complain, LOOKUP_IMPLICIT);
or tsubst that TREE_TYPE (ohi) as well?  I.e. convert to type of the
template parameter.

Jakub



Re: [PATCH] small _BitInt tweaks

2023-09-12 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 12, 2023 at 10:27:18AM +, Richard Biener wrote:
> On Mon, 11 Sep 2023, Jakub Jelinek wrote:
> > And, also I think it is undesirable when being asked for signed_type_for
> > of unsigned _BitInt(1) (which is valid) to get signed _BitInt(1) (which is
> > invalid, the standard only allows signed _BitInt(2) and larger), so the
> > patch returns 1-bit signed INTEGER_TYPE for those cases.
> 
> I think the last bit is a bit surprising - do the frontends use
> signed_or_unsigned_type_for and would they be confused if getting
> back an INTEGER_TYPE here?

I see a single c-family/c-pretty-print.cc use of signed_or_unsigned_type_for
and none of signed_type_for in the C/C++ FEs (unsigned_type_for is used in a
couple of spots, but that isn't affected), c_common_signed_type
or c_common_signed_or_unsigned_type is used more than that, but I still
think it is mostly used for warning stuff and similar or when called with
some specific types like sizetype.  I don't think the FE uses (or should
use) those functions to decide e.g. on types of expressions etc., that is
what common_type etc. are for.
And, for the very small precisions the distinction between BITINT_TYPE and
INTEGER_TYPE should be limited to just loads/stores from memory (in case
there are different rules for what to do with padding bits in those cases if
any) and on function arguments/return values, I think none of this is really
affected by those signed_type_for/c_common_signed_type results.

And by ensuring we never create 1-bit signed BITINT_TYPE e.g. the backends
don't need to worry about them.

But I admit I don't feel strongly about that.

Joseph, what do you think about this?

Jakub



Re: [Patch] OpenMP (C only): omp allocate - extend parsing support, improve diagnostic

2023-09-12 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 12, 2023 at 09:04:16AM +0200, Tobias Burnus wrote:
> Done now. What's not caught is, e.g., a value change by calling a
> function which modifies its parameter:
> 
> omp_allocator_t a = ...; int v; foo(a); #pragma omp allocate(v) allocator(a)
> 
> as the current check is only whether 'a' is declared before 'v' or
> whether 'a' is assigned to between v's declaration and the pragma.
> 
> Any additional comments or suggestions?

As I said, we can't catch all the mistakes, the unfortunate thing is that
the syntax allows them.  I'll try to make omp::decl attribute working soon
and that will make that problem less severe when using that syntax.

Jakub



[PATCH] testsuite work-around compound-assignment-1.c C++ failures on various targets [PR111377]

2023-09-12 Thread Jakub Jelinek via Gcc-patches
On Mon, Sep 11, 2023 at 11:11:30PM +0200, Jakub Jelinek via Gcc-patches wrote:
> On Mon, Sep 11, 2023 at 07:27:57PM +0200, Benjamin Priour via Gcc-patches 
> wrote:
> > Thanks for the report,
> > 
> > After investigation it seems the location of the new dejagnu directive for
> > C++ differs depending on the configuration.
> > The expected warning is still emitted, but its location differ slightly.
> > I expect it to be not an issue per se of the analyzer, but a divergence in
> > the FE between the two configurations.
> 
> I think the divergence is whether called_by_test_5b returns the struct
> in registers or in memory.  If in memory (like in the x86_64 -m32 case), we 
> have
>   [compound-assignment-1.c:71:21] D.3191 = called_by_test_5b (); [return slot 
> optimization]
>   [compound-assignment-1.c:71:21 discrim 1] D.3191 ={v} {CLOBBER(eol)};
>   [compound-assignment-1.c:72:1] return;
> in the IL, while if in registers (like x86_64 -m64 case), just
>   [compound-assignment-1.c:71:21] D.3591 = called_by_test_5b ();
>   [compound-assignment-1.c:72:1] return;
> 
> If you just want to avoid the differences, putting } on the same line as the
> call might be a usable workaround for that.

Here is the workaround in patch form.  Tested on x86_64-linux -m32/-m64, ok
for trunk?

2023-09-12  Jakub Jelinek  

PR testsuite/111377
* c-c++-common/analyzer/compound-assignment-1.c (test_5b): Move
closing } to the same line as the call to work-around differences in
diagnostics line.

--- gcc/testsuite/c-c++-common/analyzer/compound-assignment-1.c.jj  
2023-09-11 11:05:47.523727789 +0200
+++ gcc/testsuite/c-c++-common/analyzer/compound-assignment-1.c 2023-09-12 
08:58:52.854231161 +0200
@@ -68,5 +68,8 @@ called_by_test_5b (void)
 
 void test_5b (void)
 {
-  called_by_test_5b ();
-} /* { dg-warning "leak of '.ptr_wrapper::ptr'" "" { target c++ } } 
*/
+  called_by_test_5b (); }
+/* { dg-warning "leak of '.ptr_wrapper::ptr'" "" { target c++ } .-1 
} */
+/* The closing } above is intentionally on the same line as the call, because
+   otherwise the exact line of the diagnostics depends on whether the
+   called_by_test_5b () call satisfies aggregate_value_p or not.  */


Jakub



Re: [r14-3823 Regression] FAIL: c-c++-common/analyzer/compound-assignment-1.c -std=c++98 (test for warnings, line 72) on Linux/x86_64

2023-09-11 Thread Jakub Jelinek via Gcc-patches
On Mon, Sep 11, 2023 at 07:27:57PM +0200, Benjamin Priour via Gcc-patches wrote:
> Thanks for the report,
> 
> After investigation it seems the location of the new dejagnu directive for
> C++ differs depending on the configuration.
> The expected warning is still emitted, but its location differ slightly.
> I expect it to be not an issue per se of the analyzer, but a divergence in
> the FE between the two configurations.

I think the divergence is whether called_by_test_5b returns the struct
in registers or in memory.  If in memory (like in the x86_64 -m32 case), we have
  [compound-assignment-1.c:71:21] D.3191 = called_by_test_5b (); [return slot 
optimization]
  [compound-assignment-1.c:71:21 discrim 1] D.3191 ={v} {CLOBBER(eol)};
  [compound-assignment-1.c:72:1] return;
in the IL, while if in registers (like x86_64 -m64 case), just
  [compound-assignment-1.c:71:21] D.3591 = called_by_test_5b ();
  [compound-assignment-1.c:72:1] return;

If you just want to avoid the differences, putting } on the same line as the
call might be a usable workaround for that.

Jakub



[PATCH] small _BitInt tweaks

2023-09-11 Thread Jakub Jelinek via Gcc-patches
Hi!

When discussing PR111369 with Andrew Pinski, I've realized that
I haven't added BITINT_TYPE handling to range_check_type.  Right now
(unsigned) max + 1 == (unsigned) min for signed _BitInt,l so I think we
don't need to do the extra hops for BITINT_TYPE (though possibly we don't
need them for INTEGER_TYPE either in the two's complement word and we don't
support anything else, though I really don't know if Ada or some other
FEs don't create weird INTEGER_TYPEs).
And, also I think it is undesirable when being asked for signed_type_for
of unsigned _BitInt(1) (which is valid) to get signed _BitInt(1) (which is
invalid, the standard only allows signed _BitInt(2) and larger), so the
patch returns 1-bit signed INTEGER_TYPE for those cases.

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

2023-09-11  Jakub Jelinek  

gcc/
* tree.cc (signed_or_unsigned_type_for): Return INTEGER_TYPE for
signed variant of unsigned _BitInt(1).
* fold-const.cc (range_check_type): Handle BITINT_TYPE like
OFFSET_TYPE.
gcc/c-family/
* c-common.cc (c_common_signed_or_unsigned_type): Return INTEGER_TYPE
for signed variant of unsigned _BitInt(1).

--- gcc/tree.cc.jj  2023-09-06 17:50:30.707589026 +0200
+++ gcc/tree.cc 2023-09-11 16:24:58.749625569 +0200
@@ -11096,7 +11096,7 @@ signed_or_unsigned_type_for (int unsigne
   else
 return NULL_TREE;
 
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (TREE_CODE (type) == BITINT_TYPE && (unsignedp || bits > 1))
 return build_bitint_type (bits, unsignedp);
   return build_nonstandard_integer_type (bits, unsignedp);
 }
--- gcc/c-family/c-common.cc.jj 2023-09-06 17:34:24.467254960 +0200
+++ gcc/c-family/c-common.cc2023-09-11 16:24:07.873300311 +0200
@@ -2739,7 +2739,9 @@ c_common_signed_or_unsigned_type (int un
   || TYPE_UNSIGNED (type) == unsignedp)
 return type;
 
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (TREE_CODE (type) == BITINT_TYPE
+  /* signed _BitInt(1) is invalid, avoid creating that.  */
+  && (unsignedp || TYPE_PRECISION (type) > 1))
 return build_bitint_type (TYPE_PRECISION (type), unsignedp);
 
 #define TYPE_OK(node)  \
--- gcc/fold-const.cc.jj2023-09-11 11:05:47.473728473 +0200
+++ gcc/fold-const.cc   2023-09-11 16:28:06.052141516 +0200
@@ -5565,7 +5565,12 @@ range_check_type (tree etype)
   else
return NULL_TREE;
 }
-  else if (POINTER_TYPE_P (etype) || TREE_CODE (etype) == OFFSET_TYPE)
+  else if (POINTER_TYPE_P (etype)
+  || TREE_CODE (etype) == OFFSET_TYPE
+  /* Right now all BITINT_TYPEs satisfy
+ (unsigned) max + 1 == (unsigned) min, so no need to verify
+ that like for INTEGER_TYPEs.  */
+  || TREE_CODE (etype) == BITINT_TYPE)
 etype = unsigned_type_for (etype);
   return etype;
 }

Jakub



[PATCH] sccvn: Avoid ICEs on _BitInt load BIT_AND_EXPR mask [PR111338]

2023-09-11 Thread Jakub Jelinek via Gcc-patches
Hi!

The following testcase ICEs, because vn_walk_cb_data::push_partial_def
uses a fixed size buffer (64 target bytes) for its
construction/deconstruction of partial stores and fails if larger precision
than that is needed, and the PR93582 changes assert push_partial_def
succeeds (and check the various other conditions much earlier when seeing
the BIT_AND_EXPR statement, like CHAR_BIT == 8, BITS_PER_UNIT == 8,
BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN, etc.).  So, just removing the assert
and allowing it fail there doesn't really work and ICEs later on.

The following patch moves the bufsize out of the method and tests it
together with the other checks.

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

BTW, perhaps we could increase the bufsize as well or in addition to
increasing it make the buffer allocated using XALLOCAVEC, but still I think
it is useful to have some upper bound and so I think this patch is useful
even in that case.

2023-09-11  Jakub Jelinek  

PR middle-end/111338
* tree-ssa-sccvn.cc (struct vn_walk_cb_data): Add bufsize non-static
data member.
(vn_walk_cb_data::push_partial_def): Remove bufsize variable.
(visit_nary_op): Avoid the BIT_AND_EXPR with constant rhs2
optimization if type's precision is too large for
vn_walk_cb_data::bufsize.

* gcc.dg/bitint-37.c: New test.

--- gcc/tree-ssa-sccvn.cc.jj2023-09-06 17:28:24.232977433 +0200
+++ gcc/tree-ssa-sccvn.cc   2023-09-08 13:22:27.928158846 +0200
@@ -1903,6 +1903,7 @@ struct vn_walk_cb_data
   alias_set_type first_base_set;
   splay_tree known_ranges;
   obstack ranges_obstack;
+  static constexpr HOST_WIDE_INT bufsize = 64;
 };
 
 vn_walk_cb_data::~vn_walk_cb_data ()
@@ -1973,7 +1974,6 @@ vn_walk_cb_data::push_partial_def (pd_da
   HOST_WIDE_INT offseti,
   HOST_WIDE_INT maxsizei)
 {
-  const HOST_WIDE_INT bufsize = 64;
   /* We're using a fixed buffer for encoding so fail early if the object
  we want to interpret is bigger.  */
   if (maxsizei > bufsize * BITS_PER_UNIT
@@ -5414,6 +5414,7 @@ visit_nary_op (tree lhs, gassign *stmt)
  && CHAR_BIT == 8
  && BITS_PER_UNIT == 8
  && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
+ && TYPE_PRECISION (type) <= vn_walk_cb_data::bufsize * BITS_PER_UNIT
  && !integer_all_onesp (gimple_assign_rhs2 (stmt))
  && !integer_zerop (gimple_assign_rhs2 (stmt)))
{
--- gcc/testsuite/gcc.dg/bitint-37.c.jj 2023-09-08 13:27:51.676882523 +0200
+++ gcc/testsuite/gcc.dg/bitint-37.c2023-09-08 13:27:22.460268614 +0200
@@ -0,0 +1,11 @@
+/* PR middle-end/111338 */
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-O1" } */
+
+_BitInt(575) e;
+
+_BitInt(575)
+foo (void)
+{
+  return e & 1;
+}

Jakub



Re: [PATH] [CLEANUP] Remove trailing whitespace characters

2023-09-11 Thread Jakub Jelinek via Gcc-patches
On Mon, Sep 11, 2023 at 09:27:48AM -0400, David Malcolm via Gcc-patches wrote:
> On Sun, 2023-09-10 at 16:36 +0200, Guillaume Gomez wrote:
> > When going through the code, I saw a lot of trailing whitespace
> > characters so I decided to write a small script that would remove
> > them. I didn't expect there would be so many though... Not sure if
> > patch with so many changes are accepted like this or if I should send
> > more focused one.
> 
> I'm not sure either.
> 
> Some notes on the patch:

IMHO testsuite shouldn't be touched at all, there are certainly tests
which test whether such sources are handled correctly.

Non-C/C++ sources shouldn't be changed this way either.

The ^L stuff should be preserved, not removed.

And even with that, I'm not sure it is a good idea to change it because
it will be a nightmare for git blame.

The usual way of fixing up formatting if it was committed in a broken way
is only when one is touching with real code changes something, fixing up
formatting on it or around it is fine.

If we decide to fix formatting in bulk, I think we should have a flag day
and change also other formatting mistakes at the same time (say 8 spaces
instead of tabs for start of line indentation (before first non-blank
character), = at the end of line except for static var initializers, etc.
But to make that worthwhile, it would be better to then have a pre-commit
hook that would enforce formatting.  And, we haven't managed to come up with
something like that yet.

Jakub



Re: [Patch] OpenMP (C only): omp allocate - extend parsing support, improve diagnostic (was: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic)

2023-09-11 Thread Jakub Jelinek via Gcc-patches
On Mon, Sep 11, 2023 at 03:21:54PM +0200, Tobias Burnus wrote:
> +  if (TREE_STATIC (var))
> + {
> +   if (allocator == NULL_TREE && allocator_loc == UNKNOWN_LOCATION)
> + error_at (loc, "% clause required for "
> +"static variable %qD", var);
> +   else if (allocator
> +&& (tree_int_cst_sgn (allocator) != 1
> +|| tree_to_shwi (allocator) > 8))

Has anything checked that in this case allocator is actually INTEGER_CST
which fits into shwi?  Otherwise tree_to_shwi will ICE.
Consider say allocator argument of
329857234985743598347598437598347594835743895743wb
or (((unsigned __int128) 0x123456789abcdef0) << 64)
Either tree_fits_shwi_p (allocator) check would do it, or perhaps
else if (allocator
 && TREE_CODE (allocator) == INTEGER_CST
 && wi::to_widest (allocator) > 0
 && wi::to_widest (allocator) <= 8)
?

> +  if (allocator
> +   && TREE_CODE (allocator) == VAR_DECL
> +   && c_check_in_current_scope (var))
> + {
> +   if (linemap_location_before_p (line_table, DECL_SOURCE_LOCATION (var),
> +  DECL_SOURCE_LOCATION (allocator)))
> + {
> +   error_at (OMP_CLAUSE_LOCATION (nl),
> + "allocator variable %qD must be declared before %qD",
> + allocator, var);
> +   inform (DECL_SOURCE_LOCATION (allocator),
> +   "allocator declared here");
> +   inform (DECL_SOURCE_LOCATION (var), "declared here");
> + }
> +   else
> +{
> +  gcc_assert (cur_stmt_list
> +  && TREE_CODE (cur_stmt_list) == STATEMENT_LIST);
> +  tree_stmt_iterator l = tsi_last (cur_stmt_list);
> +  while (!tsi_end_p (l))
> +{
> +  if (linemap_location_before_p (line_table, EXPR_LOCATION (*l),
> + DECL_SOURCE_LOCATION (var)))
> +break;
> +  if (TREE_CODE (*l) == MODIFY_EXPR
> +  && TREE_OPERAND (*l, 0) == allocator)
> +{
> +  error_at (EXPR_LOCATION (*l),
> +"allocator variable %qD, used in the "
> +"% directive for %qD, must not be "
> +"modified between declaration of %qD and its "
> +"% directive",
> +allocator, var, var);
> +  inform (DECL_SOURCE_LOCATION (var), "declared here");
> +  inform (OMP_CLAUSE_LOCATION (nl), "used here");
> +  break;
> +   }
> + --l;
> +  }
> +}

BTW, it doesn't necessarily have to be just the simple case which you catch
here, namely that allocator is a VAR_DECL defined after var in current
scope.
One can have an expression which uses those other vars, say
  int v;
  int a = 1;
  int b[n]; // VLA
  b[a] = 5;
  #pragma omp allocate (v) allocator (foo (a, [a]))
where foo would be some function which returns omp_allocator_handle_t.
Or it could be e.g. lambda declared later, etc.
I bet we can't catch everything, but perhaps e.g. doing the first
diagnostics from within walk_tree might be better.

Jakub



Re: [Patch] OpenMP (C only): omp allocate - extend parsing support, improve diagnostic (was: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic)

2023-09-11 Thread Jakub Jelinek via Gcc-patches
Hi!

One question to David below, CCed.

On Mon, Sep 11, 2023 at 01:44:07PM +0200, Tobias Burnus wrote:
> --- a/gcc/c/c-decl.cc
> +++ b/gcc/c/c-decl.cc
> @@ -681,6 +681,11 @@ decl_jump_unsafe (tree decl)
>if (VAR_P (decl) && C_DECL_COMPOUND_LITERAL_P (decl))
>  return false;
>  
> +  if (flag_openmp
> +  && VAR_P (decl)
> +  && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl)))
> +return true;
> +
>/* Always warn about crossing variably modified types.  */
>if ((VAR_P (decl) || TREE_CODE (decl) == TYPE_DECL)
>&& c_type_variably_modified_p (TREE_TYPE (decl)))
> @@ -724,6 +729,12 @@ c_print_identifier (FILE *file, tree node, int indent)
>c_binding_oracle = save;
>  }
>  

I think we want a function comment here.

> +void
> +c_mark_decl_jump_unsafe_in_current_scope ()
> +{
> +  current_scope->has_jump_unsafe_decl = 1;
> +}
> +
> +   if (DECL_SOURCE_LOCATION (allocator) > DECL_SOURCE_LOCATION (var))
> + {
> +   error_at (OMP_CLAUSE_LOCATION (nl),
> + "allocator variable %qD must be declared before %qD",
> + allocator, var);
> +   inform (DECL_SOURCE_LOCATION (allocator), "declared here");
> +   inform (DECL_SOURCE_LOCATION (var), "declared here");

I think this will be confusing to users when the inform is the same in both
cases.  I'd use "allocator declared here" in the first case.

And, am really not sure if one can just simply compare location_t like that.
Isn't there some function which determines what source location is before
another one?  David?

> +  if (EXPR_LOCATION (*l) < DECL_SOURCE_LOCATION (var))
> +break;

Likewise.

> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/gomp/allocate-12.c
> @@ -0,0 +1,46 @@
> +/* TODO: enable for C++ once implemented. */
> +/* { dg-do compile { target c } } */
> +
> +typedef enum omp_allocator_handle_t

I think all the c-c++-common tests declaring
omp_allocator_handle_t should have
#if __cplusplus >= 201103L
: __UINTPTR_TYPE__
#endif
here (even if they are just { target c } for now, we'd certainly
forget to adjust them).


Jakub



Re: [PATCH] libstdc++: Check if getent is available in git config script [PR111359]

2023-09-11 Thread Jakub Jelinek via Gcc-patches
On Mon, Sep 11, 2023 at 12:06:19PM +0100, Jonathan Wakely via Gcc-patches wrote:
> Tested x86_64-linux, powerpc-aix, and minimally tested on macOS 12.6
> (darwin 21.6.0).
> 
> OK for trunk?
> 
> -- >8 --
> 
> contrib/ChangeLog:
> 
>   PR other/111359
>   * gcc-git-customization.sh: Check for getent before using it.
>   Use id on macOS.

Ok, thanks.

Jakub



Re: [PATCH] libcpp: add function to check XID properties

2023-09-08 Thread Jakub Jelinek via Gcc-patches
On Fri, Sep 08, 2023 at 02:58:40PM +0200, Arthur Cohen wrote:
> From: Raiki Tamura 
> 
> libcpp/ChangeLog:
> 
>   * charset.cc (check_xid_property):new function to check XID_Start and 
> XID_Continue
>   * include/cpplib.h (check_xid_property):add enum representing XID 
> properties

Just random comments, not a proper review.
1) functions exported from libcpp should IMNSHO use the cpp_ prefix
2) similarly the enumerators should be prefixed with CPP_
3) formatting of the ChangeLog entry is incorrect.  There should be a space
after ): followed by uppercase rather than lowercase letter, descriptions
should end with . and there should be line wrapping so that it fits into 80
columns.  For a new function, one can just say New. or New function.,
doesn't need to describe what it is good for.  And the include/cpplib.h
changes don't describe what actually changed.  A new anonymous enum (why not
a named one?) was added, and check_xid_property declared.

> --- a/libcpp/include/cpplib.h
> +++ b/libcpp/include/cpplib.h
> @@ -1606,4 +1606,11 @@ bool cpp_valid_utf8_p (const char *data, size_t 
> num_bytes);
>  bool cpp_is_combining_char (cppchar_t c);
>  bool cpp_is_printable_char (cppchar_t c);
>  
> +enum {
> +   XID_START = 1,
> +   XID_CONTINUE = 2

Formatting.  There should be indentation just by 2 columns rather than 3.

Jakub



[PATCH] pretty-print: Fix up pp_wide_int [PR111329]

2023-09-08 Thread Jakub Jelinek via Gcc-patches
Hi!

The recent pp_wide_int changes for _BitInt support (because not all
wide_ints fit into the small fixed size digit_buffer anymore) apparently
broke
+FAIL: gcc.dg/analyzer/out-of-bounds-diagram-1-debug.c (test for excess errors)
+FAIL: gcc.dg/analyzer/out-of-bounds-diagram-1-debug.c 2 blank line(s) in output
+FAIL: gcc.dg/analyzer/out-of-bounds-diagram-1-debug.c expected multiline 
pattern lines 17-39
(and I couldn't reproduce that in bisect seed (which is -O0 compiled) and
thought it would be some analyzer diagnostic bug).

The problem is that analyzer uses pp_wide_int with a function call in the
second argument.  Previously, when pp_wide_int macro just did
  print_dec (W, pp_buffer (PP)->digit_buffer, SGN);
  pp_string (PP, pp_buffer (PP)->digit_buffer);
it worked, because the const wide_int_ref & first argument to print_dec
bound to a temporary, which was only destructed at the end of the full
statement after print_dec was called.
But with my changes where I need to first compare the precision of the
const wide_int_ref & to decide whether to use digit_buffer or XALLOCAVEC
something larger, this means that pp_wide_int_ref binds to a temporary
which is destroyed at the end of full statement which is the
  const wide_int_ref _wide_int_ref = (W);
declaration, so then invokes UB accessing a destructed temporary.

The following patch fixes it by rewriting pp_wide_int into an inline
function, so that the end of the full statement is the end of the inline
function call.  As functions using alloca aren't normally inlined, I've
also split that part into a separate out of line function.  Putting that
into pretty-print.cc didn't work, e.g. the gm2 binary doesn't link,
because pretty-print.o is in libcommon.a, but wide-print-print.o which
defines print_dec is not.  So I've put that out of line function into
wide-int-print.cc instead.

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

2023-09-08  Jakub Jelinek  

PR middle-end/111329
* pretty-print.h (pp_wide_int): Rewrite from macro into inline
function.  For printing values which don't fit into digit_buffer
use out-of-line function.
* wide-int-print.h (pp_wide_int_large): Declare.
* wide-int-print.cc: Include pretty-print.h.
(pp_wide_int_large): Define.

--- gcc/pretty-print.h.jj   2023-09-06 14:36:53.485246347 +0200
+++ gcc/pretty-print.h  2023-09-08 11:11:21.173649942 +0200
@@ -333,28 +333,6 @@ pp_get_prefix (const pretty_printer *pp)
 #define pp_decimal_int(PP, I)  pp_scalar (PP, "%d", I)
 #define pp_unsigned_wide_integer(PP, I) \
pp_scalar (PP, HOST_WIDE_INT_PRINT_UNSIGNED, (unsigned HOST_WIDE_INT) I)
-#define pp_wide_int(PP, W, SGN)\
-  do   \
-{  \
-  const wide_int_ref _wide_int_ref = (W);   \
-  unsigned int pp_wide_int_prec\
-   = pp_wide_int_ref.get_precision (); \
-  if ((pp_wide_int_prec + 3) / 4   \
- > sizeof (pp_buffer (PP)->digit_buffer) - 3)  \
-   {   \
- char *pp_wide_int_buf \
-   = XALLOCAVEC (char, (pp_wide_int_prec + 3) / 4 + 3);\
- print_dec (pp_wide_int_ref, pp_wide_int_buf, SGN);\
- pp_string (PP, pp_wide_int_buf);  \
-   }   \
-  else \
-   {   \
- print_dec (pp_wide_int_ref,   \
-pp_buffer (PP)->digit_buffer, SGN);\
- pp_string (PP, pp_buffer (PP)->digit_buffer); \
-   }   \
-}  \
-  while (0)
 #define pp_vrange(PP, R)   \
   do   \
 {  \
@@ -453,6 +431,19 @@ pp_wide_integer (pretty_printer *pp, HOS
   pp_scalar (pp, HOST_WIDE_INT_PRINT_DEC, i);
 }
 
+inline void
+pp_wide_int (pretty_printer *pp, const wide_int_ref , signop sgn)
+{
+  unsigned int prec = w.get_precision ();
+  if (UNLIKELY ((prec + 3) / 4 > sizeof (pp_buffer (pp)->digit_buffer) - 3))
+pp_wide_int_large (pp, w, sgn);
+  else
+{
+  print_dec (w, pp_buffer (pp)->digit_buffer, sgn);
+  pp_string (pp, pp_buffer (pp)->digit_buffer);
+}
+}
+
 template
 void pp_wide_integer (pretty_printer *pp, const poly_int_pod &);
 
--- gcc/wide-int-print.h.jj 2023-09-08 11:03:48.320944156 +0200
+++ gcc/wide-int-print.h2023-09-08 11:11:46.982292282 +0200
@@ -34,5 

Re: [Patch] contrib/gcc-changelog: Check whether revert-commit exists

2023-09-08 Thread Jakub Jelinek via Gcc-patches
On Fri, Sep 08, 2023 at 10:25:42AM +0200, Christophe Lyon wrote:
> Revert "libstdc++: Use GLIBCXX_CHECK_LINKER_FEATURES for cross-builds
> (PR111238)"
> 
> diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
> index 8f7b01e0563..0c60149d7f6 100644
> --- a/libstdc++-v3/ChangeLog
> +++ b/libstdc++-v3/ChangeLog
> @@ -4,6 +4,16 @@
> for freestanding.
> * configure: Regenerate.
> 
> +2023-09-04  Christophe Lyon  
> +
> +   Revert
> +   2023-09-04  Christophe Lyon  
> +
> +   PR libstdc++/111238
> +   * configure: Regenerate.
> +   * configure.ac: Call GLIBCXX_CHECK_LINKER_FEATURES in cross,
> +   non-Canadian builds.
> +
>  2023-09-04  Christophe Lyon  
> 
> PR libstdc++/111238
> 
> I inserted my "Revert"  ChangeLog entry between the entry I want to declare
> reverted and Jonathan's more recent patch about GLIBCXX_ENABLE_BACKTRACE.
> Is that OK for the commit hooks?

Yes, thanks.

Jakub



Re: [PATCH] OpenMP: Fix ICE in fixup_blocks_walker [PR111274]

2023-09-07 Thread Jakub Jelinek via Gcc-patches
On Thu, Sep 07, 2023 at 10:18:37AM -0600, Sandra Loosemore wrote:
> This ICE was caused by an invalid assumption that all BIND_EXPRs have
> a non-null BIND_EXPR_BLOCK.  In C++ these do exist and are used for
> temporaries introduced in expressions that are not full-expressions.
> Since they have no block to fix up, the traversal can just ignore
> these tree nodes.
> 
> gcc/cp/ChangeLog
>   * parser.cc (fixup_blocks_walker): Check for null BIND_EXPR_BLOCK.
> 
> gcc/testsuite/ChangeLog
>   * g++.dg/gomp/pr111274.C: New test case

Missing . at the end of the ChangeLog line.

Otherwise LGTM.

> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -44485,7 +44485,10 @@ fixup_blocks_walker (tree *tp, int *walk_subtrees, 
> void *dp)
>  {
>tree superblock = *(tree *)dp;
>  
> -  if (TREE_CODE (*tp) == BIND_EXPR)
> +  /* BIND_EXPR_BLOCK may be null if the expression is not a
> + full-expression; if there's no block, no patching is necessary
> + for this node.  */
> +  if (TREE_CODE (*tp) == BIND_EXPR && BIND_EXPR_BLOCK (*tp))
>  {
>tree block = BIND_EXPR_BLOCK (*tp);
>if (superblock)
> diff --git a/gcc/testsuite/g++.dg/gomp/pr111274.C 
> b/gcc/testsuite/g++.dg/gomp/pr111274.C
> new file mode 100644
> index 000..6d3414fc82c
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/gomp/pr111274.C
> @@ -0,0 +1,15 @@
> +// { dg-do "compile" }
> +
> +// This example used to ICE in fixup_blocks_walker due to a BIND_EXPR with
> +// null BIND_EXPR_BLOCK.
> +
> +struct _Vector_base {
> +  ~_Vector_base();
> +};
> +int ColumnSmallestLastOrdering_OMP_i_MaxNumThreads,
> +ColumnSmallestLastOrdering_OMP_i_MaxDegree;
> +void ColumnSmallestLastOrdering_OMP() {
> +#pragma omp for
> +  for (int i = 0; i < ColumnSmallestLastOrdering_OMP_i_MaxNumThreads; i++)
> +new _Vector_base[ColumnSmallestLastOrdering_OMP_i_MaxDegree];
> +}
> -- 
> 2.31.1

Jakub



Re: [Patch] contrib/gcc-changelog: Check whether revert-commit exists

2023-09-07 Thread Jakub Jelinek via Gcc-patches
On Thu, Sep 07, 2023 at 10:20:19AM +0200, Christophe Lyon via Gcc-patches wrote:
> On Tue, 5 Sept 2023 at 16:38, Tobias Burnus  wrote:
> 
> > That's based on the fail
> > https://gcc.gnu.org/pipermail/gccadmin/2023q3/020349.html
> > and on the discussion on IRC.
> >
> 
> Sorry I didn't notice the problem, nor the discussion on IRC, but I can see
> that my commits created the problem, sorry for that.
> 
> I'm not sure how your patch would have prevented me from doing this?
> What happened is that I had 3 patches on top of master
> - HEAD: the one I wanted to push
> - HEAD-1: revert of HEAD-2

git reset HEAD^
instead of committing a revert would be better I think.

> - HEAD-2:  libstdc-Use-GLIBCXX_CHECK_LINKER_FEATURES-for.patch
> 
> I had actually forgotten about HEAD-1 and HEAD-2, HEAD was unrelated to
> those, so when I pushed, I pushed 3 commits while I thought there was only
> one.
> I did run contrib/gcc-changelog/git_check_commit.py (I realize I'm not sure
> whether I used git_check_commit.py or git_commit.py), but only on HEAD
> since I had forgotten about the other two.

Could you please remove your
2023-09-04  Christophe Lyon  

PR libstdc++/111238
* configure: Regenerate.
* configure.ac: Call GLIBCXX_CHECK_LINKER_FEATURES in cross,
non-Canadian builds.
libstdc++-v3/ChangeLog entry if that commit is indeed not in (or add
a Revert: entry for it right after it if you think it needs to be in)?
That is a part I haven't done, my/Arsen's hacks to make the version update
get through basically ignored that revert commit.

ChangeLog files can be changed by commits which only touch ChangeLog files
and nothing else (ok, date stamp too, but please don't update that), no
ChangeLog in the message needs to be provided for such changes.

Jakub



Re: [Patch] contrib/gcc-changelog: Check whether revert-commit exists

2023-09-07 Thread Jakub Jelinek via Gcc-patches
On Thu, Sep 07, 2023 at 11:30:53AM +0200, Tobias Burnus wrote:
> contrib/gcc-changelog: Check whether revert-commit exists
> 
> contrib/ChangeLog:
> 
>   * gcc-changelog/git_commit.py (GitCommit.__init__):
>   Handle commit_to_info_hook = None; otherwise, if None,
>   regard it as error.
>   (to_changelog_entries): Handle commit_to_info_hook = None;
>   if info is None, create a warning for it.
>   * gcc-changelog/git_email.py (GitEmail.__init__):
>   call super() with commit_to_info_hook=None instead
>   of a lamda function.
> 
>  contrib/gcc-changelog/git_commit.py | 20 +++-
>  contrib/gcc-changelog/git_email.py  |  3 +--
>  2 files changed, 16 insertions(+), 7 deletions(-)
> 
> diff --git a/contrib/gcc-changelog/git_commit.py 
> b/contrib/gcc-changelog/git_commit.py
> index 4f3131021f2..4f1bd4d7293 100755
> --- a/contrib/gcc-changelog/git_commit.py
> +++ b/contrib/gcc-changelog/git_commit.py
> @@ -329,11 +329,15 @@ class GitCommit:
>  self.revert_commit = m.group('hash')
>  break
>  if self.revert_commit:
> +# The following happens for get_email.py:
> +if not self.commit_to_info_hook:
> +self.warnings.append(f"Invoked script can technically not 
> obtain info about "
> + f"reverted commits such as 
> '{self.revert_commit}'")

I think not should precede technically (or should we just drop technically)?

> +self.warnings.append(f"Invoked script can 
> technically not obtain info about "
> + f"cherry-picked commits such as 
> '{self.revert_commit}'")

Likewise.

>  timestamp = current_timestamp
>  elif not timestamp or use_commit_ts:
>  timestamp = current_timestamp
> diff --git a/contrib/gcc-changelog/git_email.py 
> b/contrib/gcc-changelog/git_email.py
> index 49f41f2ec99..93808dfabb6 100755
> --- a/contrib/gcc-changelog/git_email.py
> +++ b/contrib/gcc-changelog/git_email.py
> @@ -89,8 +89,7 @@ class GitEmail(GitCommit):
>  t = 'M'
>  modified_files.append((target if t != 'D' else source, t))
>  git_info = GitInfo(None, date, author, message, modified_files)
> -super().__init__(git_info,
> - commit_to_info_hook=lambda x: None)
> +super().__init__(git_info, commit_to_info_hook=None)
>  
>  
>  def show_help():

Otherwise LGTM, but it would be good after committing it try to commit
reversion commit of some non-existent hash (willing to handle ChangeLog
manually again if it makes it through).

Jakub



[committed] middle-end: Avoid calling targetm.c.bitint_type_info inside of gcc_assert [PR102989]

2023-09-07 Thread Jakub Jelinek via Gcc-patches
On Thu, Sep 07, 2023 at 10:36:02AM +0200, Thomas Schwinge wrote:
> Minor comment/question: are we doing away with the property that
> 'assert'-like "calls" must not have side effects?  Per 'gcc/system.h',
> this is "OK" for 'gcc_assert' for '#if ENABLE_ASSERT_CHECKING' or
> '#elif (GCC_VERSION >= 4005)' -- that is, GCC 4.5, which is always-true,
> thus the "offending" '#else' is never active.  However, it's different
> for standard 'assert' and 'gcc_checking_assert', so I'm not sure if
> that's a good property for 'gcc_assert' only?  For example, see also
>  "warn about asserts with side effects", or
> recent 
> "RFE: could -fanalyzer warn about assertions that have side effects?".

You're right, the
  #define gcc_assert(EXPR) ((void)(0 && (EXPR)))
fallback definition is incompatible with the way I've used it, so for
--disable-checking built by non-GCC it would not work properly.

Fixed thusly, committed to trunk as obvious.

2023-09-07  Jakub Jelinek  

PR c/102989
* expr.cc (expand_expr_real_1): Don't call targetm.c.bitint_type_info
inside gcc_assert, as later code relies on it filling info variable.
* gimple-fold.cc (clear_padding_bitint_needs_padding_p,
clear_padding_type): Likewise.
* varasm.cc (output_constant): Likewise.
* fold-const.cc (native_encode_int, native_interpret_int): Likewise.
* stor-layout.cc (finish_bitfield_representative, layout_type):
Likewise.
* gimple-lower-bitint.cc (bitint_precision_kind): Likewise.

--- gcc/expr.cc.jj  2023-09-06 17:28:24.216977643 +0200
+++ gcc/expr.cc 2023-09-07 11:11:57.761912944 +0200
@@ -11039,7 +11039,8 @@ expand_expr_real_1 (tree exp, rtx target
  {
unsigned int prec = TYPE_PRECISION (type);
struct bitint_info info;
-   gcc_assert (targetm.c.bitint_type_info (prec, ));
+   bool ok = targetm.c.bitint_type_info (prec, );
+   gcc_assert (ok);
scalar_int_mode limb_mode
  = as_a  (info.limb_mode);
unsigned int limb_prec = GET_MODE_PRECISION (limb_mode);
--- gcc/gimple-fold.cc.jj   2023-09-06 17:28:24.221977578 +0200
+++ gcc/gimple-fold.cc  2023-09-07 11:11:57.765912888 +0200
@@ -4602,7 +4602,8 @@ static bool
 clear_padding_bitint_needs_padding_p (tree type)
 {
   struct bitint_info info;
-  gcc_assert (targetm.c.bitint_type_info (TYPE_PRECISION (type), ));
+  bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), );
+  gcc_assert (ok);
   if (info.extended)
 return false;
   scalar_int_mode limb_mode = as_a  (info.limb_mode);
@@ -4880,7 +4881,8 @@ clear_padding_type (clear_padding_struct
 case BITINT_TYPE:
   {
struct bitint_info info;
-   gcc_assert (targetm.c.bitint_type_info (TYPE_PRECISION (type), ));
+   bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), );
+   gcc_assert (ok);
scalar_int_mode limb_mode = as_a  (info.limb_mode);
if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
  {
--- gcc/varasm.cc.jj2023-09-06 17:28:24.239977342 +0200
+++ gcc/varasm.cc   2023-09-07 11:11:57.769912832 +0200
@@ -5289,8 +5289,8 @@ output_constant (tree exp, unsigned HOST
{
  struct bitint_info info;
  tree type = TREE_TYPE (exp);
- gcc_assert (targetm.c.bitint_type_info (TYPE_PRECISION (type),
- ));
+ bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), );
+ gcc_assert (ok);
  scalar_int_mode limb_mode = as_a  (info.limb_mode);
  if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
{
--- gcc/fold-const.cc.jj2023-09-06 17:28:24.219977604 +0200
+++ gcc/fold-const.cc   2023-09-07 11:11:57.772912790 +0200
@@ -7731,8 +7731,8 @@ native_encode_int (const_tree expr, unsi
   if (TREE_CODE (type) == BITINT_TYPE)
 {
   struct bitint_info info;
-  gcc_assert (targetm.c.bitint_type_info (TYPE_PRECISION (type),
- ));
+  bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), );
+  gcc_assert (ok);
   scalar_int_mode limb_mode = as_a  (info.limb_mode);
   if (TYPE_PRECISION (type) > GET_MODE_PRECISION (limb_mode))
{
@@ -8661,8 +8661,8 @@ native_interpret_int (tree type, const u
   if (TREE_CODE (type) == BITINT_TYPE)
 {
   struct bitint_info info;
-  gcc_assert (targetm.c.bitint_type_info (TYPE_PRECISION (type),
- ));
+  bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), );
+  gcc_assert (ok);
   scalar_int_mode limb_mode = as_a  (info.limb_mode);
   if (TYPE_PRECISION (type) > GET_MODE_PRECISION (limb_mode))
{
--- gcc/stor-layout.cc.jj   2023-09-06 17:28:24.226977512 +0200
+++ gcc/stor-layout.cc  2023-09-07 11:11:57.775912748 +0200
@@ 

[committed 19/12] Additional _BitInt test coverage [PR102989]

2023-09-06 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 05, 2023 at 10:40:26PM +, Joseph Myers wrote:
> Additional tests I think should be added (for things I expect should 
> already work):
> 
> * Tests for BITINT_MAXWIDTH in .  Test that it's defined for 
> C2x, but not defined for C11/C17 (the latter independent of whether the 
> target has _BitInt support).  Test the value as well: _BitInt 
> (BITINT_MAXWIDTH) should be OK (both signed and unsigned) but _BitInt 
> (BITINT_MAXWIDTH + 1) should not be OK.  Also test that BITINT_MAXWIDTH >= 
> ULLONG_MAX.
> 
> * Test _BitInt (N) where N is a constexpr variable or enum constant (I 
> expect these should work - the required call to convert_lvalue_to_rvalue 
> for constexpr to work is present - but I don't see such tests in the 
> testsuite).
> 
> * Test that -funsigned-bitfields does not affect the signedness of _BitInt 
> (N) bit-fields (the standard wording isn't entirely clear, but that's 
> what's implemented in the patches).
> 
> * Test the errors for _Sat used with _BitInt (though such a test might not 
> actually run at present because no target supports both features).

Here is a patch which adds that test coverage.

> I looked at places in c-family/ and c/ that refer to INTEGER_TYPE to 
> consider whether they should handle BITINT_TYPE and whether that matches 
> what the patch does there.  I think the following places that don't handle 
> it probably should (with appropriate testcases added for the relevant 
> functionality, e.g. warnings) unless there is some specific reason in each 
> case why that's unnecessary or incorrect.  c-pretty-print.cc: 
> c_pretty_printer::direct_declarator and c_pretty_printer::declarator.  
> c-warn.cc throughout.  Maybe c-ada-spec.cc, though it might be best to ask 
> the Ada maintainers there.  c-common.cc: unsafe_conversion_p, 
> c_common_truthvalue_conversion warnings, c_common_get_alias_set, 
> check_builtin_function_arguments BUILT_IN_ASSUME_ALIGNED case.  
> c-aux-info.cc (might need other support for generating appropriate names 
> in output).  c-parser.cc:c_parser_omp_clause_schedule.  c-fold.cc 
> throughout.  c-typeck.c: the build_conditional_expr case where one operand 
> is EXCESS_PRECISION_EXPR; build_c_cast; convert_for_assignment checks for 
> integer/pointer conversions.

As well as what I've managed to come up for the above changes.

2023-09-06  Jakub Jelinek  

PR c/102989
* gcc.dg/bitint-2.c (foo): Add tests for constexpr var or enumerator
arguments of _BitInt.
* gcc.dg/bitint-31.c: Remove forgotten 0 &&.
* gcc.dg/bitint-32.c: New test.
* gcc.dg/bitint-33.c: New test.
* gcc.dg/bitint-34.c: New test.
* gcc.dg/bitint-35.c: New test.
* gcc.dg/bitint-36.c: New test.
* gcc.dg/fixed-point/bitint-1.c: New test.

--- gcc/testsuite/gcc.dg/bitint-2.c.jj  2023-09-06 10:57:48.771535739 +0200
+++ gcc/testsuite/gcc.dg/bitint-2.c 2023-09-06 12:17:39.764073758 +0200
@@ -14,6 +14,10 @@ foo (void)
   _BitInt(5) unsigned d = (unsigned _BitInt(5)) 4;
   _BitInt(32) e = (_BitInt(32)) 5;
   _BitInt(32) unsigned f = (unsigned _BitInt(32)) 6;
+  constexpr int g = 43;
+  enum E { F = 44 };
+  _BitInt(g) h;
+  unsigned _BitInt(F) i;
   static_assert (expr_has_type (a, signed _BitInt(42)), "");
   static_assert (expr_has_type (a, _BitInt(42)), "");
   static_assert (!expr_has_type (a, unsigned _BitInt(42)), "");
@@ -66,6 +70,8 @@ foo (void)
   static_assert (expr_has_type (-1UWB, unsigned _BitInt(1)), "");
   static_assert (expr_has_type (1uWB, unsigned _BitInt(1)), "");
   static_assert (expr_has_type (2Uwb, unsigned _BitInt(2)), "");
+  static_assert (expr_has_type (h, signed _BitInt(43)), "");
+  static_assert (expr_has_type (i, unsigned _BitInt(44)), "");
   static_assert (0wb == 0, "");
   static_assert (-1wb == -1, "");
   static_assert (0xwb == 4294967295wb, "");
--- gcc/testsuite/gcc.dg/bitint-31.c.jj 2023-09-06 10:57:48.799535349 +0200
+++ gcc/testsuite/gcc.dg/bitint-31.c2023-09-06 11:52:57.675594550 +0200
@@ -255,7 +255,7 @@ main ()
   check_round (testfltu_192 (340282356779733661637539395458142568448uwb), 
__builtin_inff (), 0xffp+104f, __builtin_inff (), 0xffp+104f);
   check_round (testfltu_192 
(627710173538668076383578942320766641610235564034512895uwb), __builtin_inff 
(), 0xffp+104f, __builtin_inff (), 0xffp+104f);
 #endif
-#if 0 && __BITINT_MAXWIDTH__ >= 575
+#if __BITINT_MAXWIDTH__ >= 575
   check_round (testflt_575 (10633823015541376812058405359715352575wb), 
0xfep+99f, 0xfep+99f, 0xffp+99f, 0xfep+99f);
   check_round (testflt_575 (10633823015541376812058405359715352576wb), 
0xfep+99f, 0xfep+99f, 0xffp+99f, 0xfep+99f);
   check_round (testflt_575 (10633823015541376812058405359715352577wb), 
0xffp+99f, 0xfep+99f, 0xffp+99f, 0xfep+99f);
--- gcc/testsuite/gcc.dg/bitint-32.c.jj 2023-09-06 11:57:24.391907466 +0200
+++ gcc/testsuite/gcc.dg/bitint-32.c2023-09-06 12:00:04.885688154 

[committed 10/12 v2] C _BitInt support [PR102989]

2023-09-06 Thread Jakub Jelinek via Gcc-patches
Hi!

Thanks for the patch reviews (and to Richi and Uros as well) and everyone
who participated in discussions.

Here is the updated version of the C _BitInt support [PR102989] patch
I've committed to trunk in addition to the rest of the series (except the
_BitInt a ? ~b : b match.pd fix patch, which will need to be resolved
eventually).

On Tue, Sep 05, 2023 at 10:40:26PM +, Joseph Myers wrote:
> Maybe c-ada-spec.cc, though it might be best to ask 
> the Ada maintainers there.

I've skipped c-ada-spec.cc and will file a PR for Ada maintainers,
it is up to them to decide what they want and how to implement that.

2023-09-06  Jakub Jelinek  

PR c/102989
gcc/
* glimits.h (BITINT_MAXWIDTH): Define if __BITINT_MAXWIDTH__ is
predefined.
gcc/c-family/
* c-common.cc (c_common_reswords): Add _BitInt as keyword.
(unsafe_conversion_p): Handle BITINT_TYPE like INTEGER_TYPE.
(c_common_signed_or_unsigned_type): Handle BITINT_TYPE.
(c_common_truthvalue_conversion, c_common_get_alias_set,
check_builtin_function_arguments): Handle BITINT_TYPE like
INTEGER_TYPE.
(sync_resolve_size): Add ORIG_FORMAT argument.  If
FETCH && !ORIG_FORMAT, type is BITINT_TYPE, return -1 if size isn't
one of 1, 2, 4, 8 or 16 or if it is 16 but TImode is not supported.
(atomic_bitint_fetch_using_cas_loop): New function.
(resolve_overloaded_builtin): Adjust sync_resolve_size caller.  If
-1 is returned, use atomic_bitint_fetch_using_cas_loop to lower it.
Formatting fix.
(keyword_begins_type_specifier): Handle RID_BITINT.
* c-common.h (enum rid): Add RID_BITINT enumerator.
* c-cppbuiltin.cc (c_cpp_builtins): For C call
targetm.c.bitint_type_info and predefine __BITINT_MAXWIDTH__
and for -fbuilding-libgcc also __LIBGCC_BITINT_LIMB_WIDTH__ and
__LIBGCC_BITINT_ORDER__ macros if _BitInt is supported.
* c-lex.cc (interpret_integer): Handle CPP_N_BITINT.
* c-pretty-print.cc (c_pretty_printer::simple_type_specifier,
c_pretty_printer::direct_abstract_declarator,
c_pretty_printer::direct_declarator, c_pretty_printer::declarator):
Handle BITINT_TYPE.
(pp_c_integer_constant): Handle printing of large precision wide_ints
which would buffer overflow digit_buffer.
* c-warn.cc (conversion_warning, warnings_for_convert_and_check,
warnings_for_convert_and_check): Handle BITINT_TYPE like
INTEGER_TYPE.
gcc/c/
* c-convert.cc (c_convert): Handle BITINT_TYPE like INTEGER_TYPE.
* c-decl.cc (check_bitfield_type_and_width): Allow BITINT_TYPE
bit-fields.
(finish_struct): Prefer to use BITINT_TYPE for BITINT_TYPE bit-fields
if possible.
(declspecs_add_type): Formatting fixes.  Handle cts_bitint.  Adjust
for added union in *specs.  Handle RID_BITINT.
(finish_declspecs): Handle cts_bitint.  Adjust for added union
in *specs.
* c-parser.cc (c_keyword_starts_typename, c_token_starts_declspecs,
c_parser_declspecs, c_parser_gnu_attribute_any_word): Handle
RID_BITINT.
(c_parser_omp_clause_schedule): Handle BITINT_TYPE like INTEGER_TYPE.
* c-tree.h (enum c_typespec_keyword): Mention _BitInt in comment.
Add cts_bitint enumerator.
(struct c_declspecs): Move int_n_idx and floatn_nx_idx into a union
and add bitint_prec there as well.
* c-typeck.cc (c_common_type, comptypes_internal):
Handle BITINT_TYPE.
(perform_integral_promotions): Promote BITINT_TYPE bit-fields to
their declared type.
(build_array_ref, build_unary_op, build_conditional_expr,
build_c_cast, convert_for_assignment, digest_init, build_binary_op):
Handle BITINT_TYPE.
* c-fold.cc (c_fully_fold_internal): Handle BITINT_TYPE like
INTEGER_TYPE.
* c-aux-info.cc (gen_type): Handle BITINT_TYPE.
libcpp/
* expr.cc (interpret_int_suffix): Handle wb and WB suffixes.
* include/cpplib.h (CPP_N_BITINT): Define.

--- gcc/glimits.h.jj2023-09-05 16:44:32.269305435 +0200
+++ gcc/glimits.h   2023-09-06 09:14:53.950335938 +0200
@@ -157,6 +157,11 @@ see the files COPYING3 and COPYING.RUNTI
 # undef BOOL_WIDTH
 # define BOOL_WIDTH 1
 
+# ifdef __BITINT_MAXWIDTH__
+#  undef BITINT_MAXWIDTH
+#  define BITINT_MAXWIDTH __BITINT_MAXWIDTH__
+# endif
+
 # define __STDC_VERSION_LIMITS_H__ 202311L
 #endif
 
--- gcc/c-family/c-common.cc.jj 2023-09-05 16:44:32.110307593 +0200
+++ gcc/c-family/c-common.cc2023-09-06 09:55:30.836992346 +0200
@@ -349,6 +349,7 @@ const struct c_common_resword c_common_r
   { "_Alignas",RID_ALIGNAS,   D_CONLY },
   { "_Alignof",RID_ALIGNOF,   D_CONLY },
   { "_Atomic", RID_ATOMIC,D_CONLY },
+  { "_BitInt", RID_BITINT,D_CONLY },
   { "_Bool",   RID_BOOL,  D_CONLY 

Re: [PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989]

2023-09-06 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 05, 2023 at 03:07:15PM -0700, Andrew Pinski wrote:
> Note I notice another all to build_nonstandard_integer_type in this
> match pattern which might also need to be fixed:
> /* For (x << c) >> c, optimize into x & ((unsigned)-1 >> c) for
>unsigned x OR truncate into the precision(type) - c lowest bits
>of signed x (if they have mode precision or a precision of 1).  */
> (simplify
>  (rshift (nop_convert? (lshift @0 INTEGER_CST@1)) @@1)
>  (if (wi::ltu_p (wi::to_wide (@1), element_precision (type)))
>   (if (TYPE_UNSIGNED (type))
>(bit_and (convert @0) (rshift { build_minus_one_cst (type); } @1))
>(if (INTEGRAL_TYPE_P (type))
> (with {
>   int width = element_precision (type) - tree_to_uhwi (@1);
>   tree stype = build_nonstandard_integer_type (width, 0);
>  }
>  (if (width == 1 || type_has_mode_precision_p (stype))
>   (convert (convert:stype @0
> 
> Do we have ranges on BITINT_TYPEs? If so the two_value_replacement
> pattern in match.pd has a similar issue too.
> (that is where I copied the code to use build_nonstandard_integer_type
> from originally too.

BITINT_TYPEs do have ranges like any other integral types.  But the larger
ones should be lowered shortly after IPA and arithmetics etc. on them
shouldn't appear in later passes.
Most BITINT_TYPEs or for the above cases overly large INTEGER_TYPEs
will not satisfy type_has_mode_precision_p (but it isn't a good idea
to create such types only to throw them away).
But some BITINT_TYPEs do have non-BLKmode TYPE_MODE, they follow what modes
get similarly sized structures, so on some targets one could get OImode or
XImode.  For the above case, I think we definitely don't want to emit
integral types with such modes because nothing during expansion will support
them.  So, I wonder if the above shouldn't do
  tree stype = NULL_TREE;
  if (width <= (targetm.scalar_mode_supported_p (TImode)
? TImode : DImode))
stype = build_nonstandard_integer_type (width, 0);
and || (stype && type_has_mode_precision_p (stype)))
so that we don't create types which wouldn't work.

Jakub



Re: [PATCH 18/12] Handle BITINT_TYPE in build_{, minus_}one_cst [PR102989]

2023-09-05 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 05, 2023 at 02:42:39PM -0700, Andrew Pinski wrote:
> On Tue, Sep 5, 2023 at 12:31 AM Jakub Jelinek via Gcc-patches
> > Recent match.pd changes trigger ICE in build_minus_one_cst, apparently
> > I forgot to handle BITINT_TYPE in these (while I've handled it in
> > build_zero_cst).
> >
> > Will commit as obvious together with the rest of the series when the last
> > patches are approved.
> 
> I assume there was a testcase that will be added when _BitInt
> front-end support gets added.

After working around the build_nonstandard_integer_type in match.pd (in that
case the single one, I know there are some others) the ICE was on
dg-torture/bitint-42.c at -O1/-Os, so no new testcase needs to be added.

Jakub



Re: [PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989]

2023-09-05 Thread Jakub Jelinek via Gcc-patches
On Tue, Sep 05, 2023 at 02:27:10PM -0700, Andrew Pinski wrote:
> > I admit it isn't really clear to me what do you want to achieve by the
> > above build_nonstandard_integer_type.  Is it because of BOOLEAN_TYPE
> > or perhaps ENUMERAL_TYPE as well?
> 
> Yes I was worried about types where the precision was set but MIN/MAX
> of that type was not over the full precision and would not include
> both 0 and allones in that range.
> There is another match.pd pattern where we do a similar thing with
> calling build_nonstandard_integer_type for a similar reason but
> because we don't know if the type includes 0, 1, and allones in their
> range.

Ah, in that case you should use range_check_type, that is used already
in multiple spots in match.pd for the same purpose.  It can return NULL and
in that case one should punt on the optimization.  Otherwise, that is the
function which ensures that the type is unsigned and max + 1 is min and min
- 1 is max.
And for me, I should add BITINT_TYPE handling to that function.

> > If type is INTEGER_TYPE or BITINT_TYPE, one doesn't really need to create a
> > new type, type already is an integral type with that precision and
> > signedness.  In other places using unsigned_type_for or signed_type_for
> > might be better than using build_nonstandard_integer_type if that is what
> > one wants to achieve, those functions handle BITINT_TYPE.
> 
> Maybe here we should just use `signed_or_unsigned_type_for (type,
> TYPE_SIGN (type));`
> instead of build_nonstandard_integer_type.

No, signed_or_unsigned_type_for (TYPE_UNSIGNED (type), type) will just return
type.
  if (ANY_INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) == unsignedp)
return type;

Jakub



[PATCH] c: Don't pedwarn on _FloatN{,x} or {f,F}N{,x} suffixes for C2X

2023-09-05 Thread Jakub Jelinek via Gcc-patches
Hi!

Now that _Float{16,32,64,128,32x,64x,128x} and
{f,F}{16,32,64,128,32x,64x,128x} literal suffixes are in C23 standard,
I think it is undesirable to pedwarn about these for -std=c2x, so this
patch uses pedwarn_c11 instead.  In c-family/, we don't have that function
and am not sure it would be very clean to define dummy pedwarn_c11 in the
C++ FE, so the patch just does what pedwarn_c11 does using pedwarn/warning.

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

2023-09-05  Jakub Jelinek  

gcc/c-family/
* c-lex.cc (interpret_float): For C diagnostics on FN and FNx suffixes
append " before C2X" to diagnostics text and follow behavior of
pedwarn_c11.
gcc/c/
* c-decl.cc (declspecs_add_type): Use pedwarn_c11 rather than pedwarn
for _FloatN{,x} diagnostics and append " before C2X" to the diagnostic
text.
gcc/testsuite/
* gcc.dg/c11-floatn-1.c: New test.
* gcc.dg/c11-floatn-2.c: New test.
* gcc.dg/c11-floatn-3.c: New test.
* gcc.dg/c11-floatn-4.c: New test.
* gcc.dg/c11-floatn-5.c: New test.
* gcc.dg/c11-floatn-6.c: New test.
* gcc.dg/c11-floatn-7.c: New test.
* gcc.dg/c11-floatn-8.c: New test.
* gcc.dg/c2x-floatn-1.c: New test.
* gcc.dg/c2x-floatn-2.c: New test.
* gcc.dg/c2x-floatn-3.c: New test.
* gcc.dg/c2x-floatn-4.c: New test.
* gcc.dg/c2x-floatn-5.c: New test.
* gcc.dg/c2x-floatn-6.c: New test.
* gcc.dg/c2x-floatn-7.c: New test.
* gcc.dg/c2x-floatn-8.c: New test.

--- gcc/c-family/c-lex.cc.jj2023-09-04 09:45:44.528902928 +0200
+++ gcc/c-family/c-lex.cc   2023-09-05 09:54:29.060725832 +0200
@@ -1185,7 +1185,25 @@ interpret_float (const cpp_token *token,
error ("unsupported non-standard suffix on floating constant");
return error_mark_node;
  }
-   else if (c_dialect_cxx () && !extended)
+   else if (!c_dialect_cxx ())
+ {
+   if (warn_c11_c2x_compat > 0)
+ {
+   if (pedantic && !flag_isoc2x)
+ pedwarn (input_location, OPT_Wc11_c2x_compat,
+  "non-standard suffix on floating constant "
+  "before C2X");
+   else
+ warning (OPT_Wc11_c2x_compat,
+  "non-standard suffix on floating constant "
+  "before C2X");
+ }
+   else if (warn_c11_c2x_compat != 0 && pedantic && !flag_isoc2x)
+ pedwarn (input_location, OPT_Wpedantic,
+  "non-standard suffix on floating constant "
+  "before C2X");
+ }
+   else if (!extended)
  {
if (cxx_dialect < cxx23)
  pedwarn (input_location, OPT_Wpedantic,
--- gcc/c/c-decl.cc.jj  2023-09-04 09:45:47.998853807 +0200
+++ gcc/c/c-decl.cc 2023-09-05 09:43:28.384918043 +0200
@@ -12140,12 +12140,13 @@ declspecs_add_type (location_t loc, stru
CASE_RID_FLOATN_NX:
  specs->u.floatn_nx_idx = i - RID_FLOATN_NX_FIRST;
  if (!in_system_header_at (input_location))
-   pedwarn (loc, OPT_Wpedantic,
-"ISO C does not support the %<_Float%d%s%> type",
-floatn_nx_types[specs->u.floatn_nx_idx].n,
-(floatn_nx_types[specs->u.floatn_nx_idx].extended
- ? "x"
- : ""));
+   pedwarn_c11 (loc, OPT_Wpedantic,
+"ISO C does not support the %<_Float%d%s%> type"
+" before C2X",
+floatn_nx_types[specs->u.floatn_nx_idx].n,
+(floatn_nx_types[specs->u.floatn_nx_idx].extended
+ ? "x"
+ : ""));
 
  if (specs->long_p)
error_at (loc,
--- gcc/testsuite/gcc.dg/c11-floatn-1.c.jj  2023-09-05 10:07:09.062110156 
+0200
+++ gcc/testsuite/gcc.dg/c11-floatn-1.c 2023-09-05 10:10:57.288912286 +0200
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+/* { dg-add-options float32 } */
+/* { dg-add-options float64 } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32 } */
+/* { dg-require-effective-target float32x } */
+/* { dg-require-effective-target float64 } */
+
+_Float32 a /* { dg-error "ISO C does not support the '_Float32' 
type before C2X" } */
+  = 1.0F32;/* { dg-error "non-standard suffix on floating constant 
before C2X" } */
+_Float64 b /* { dg-error "ISO C does not support the '_Float64' 
type before C2X" } */
+  = 1.0F64;/* { dg-error "non-standard suffix on floating constant 
before C2X" } */
+_Float32x c/* { dg-error "ISO C does not support the '_Float32x' 
type before C2X" } */
+  = 

Re: [PATCH v2 1/2] strlen: fold strstr() even if the length isn't previously known [PR96601]

2023-09-05 Thread Jakub Jelinek via Gcc-patches
On Mon, Sep 04, 2023 at 11:14:41PM -0600, Jeff Law wrote:
> 
> 
> On 9/4/23 14:58, Hamza Mahfooz wrote:
> > Currently, we give up in fold_strstr_to_strncmp() if the length of the
> > the second argument to strstr() isn't known to us by the time we hit
> > that function. However, we can instead insert a strlen() in ourselves
> > and continue trying to fold strstr() into strlen()+strncmp().
> > 
> > PR tree-optimization/96601
> > 
> > gcc/ChangeLog:
> > 
> > * tree-ssa-strlen.cc (fold_strstr_to_strncmp): If arg1_len == NULL,
> > insert a strlen() for strstr()'s arg1 and use it as arg1_len.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * gcc.dg/strlenopt-30.c: Modify test.
> I'm not sure it's necessarily a win to convert to strncmp as aggressively as
> this patch would do.  Essentially when you have large needles that are
> partially matched repeatedly, performance can significantly suffer.

For -Os/-Oz I think this is never a desirable optimization, turning one call
into 2 with all the argument setup etc. (unless we have the length constant
or already computed).

Otherwise, consider say 2GB long needle, it will take quite long to even
compute strlen of that.
Now, looking at current glibc strstr implementation, it starts with
  /* Handle short needle special cases first.  */
  if (ne[0] == '\0')
return (char *)hs;
  hs = (const unsigned char *)strchr ((const char*)hs, ne[0]);
  if (hs == NULL || ne[1] == '\0')
return (char*)hs;
  if (ne[2] == '\0')
return strstr2 (hs, ne);
  if (ne[3] == '\0')
return strstr3 (hs, ne);

  /* Ensure haystack length is at least as long as needle length.
 Since a match may occur early on in a huge haystack, use strnlen
 and read ahead a few cachelines for improved performance.  */
  size_t ne_len = strlen ((const char*)ne);
  size_t hs_len = __strnlen ((const char*)hs, ne_len | 512);
So, if needle is very long but first character of the needle doesn't
appear in haystack at all and haystack is shorter than needle, this will also
not be desirable optimization, because strstr would just return NULL after
walking haystack, while with the optimization you need to compute the
length.  Otherwise I think the optimization is desirable, because typically
haystack is longer than needle and walking it completely using strchr will
be already more expensive than strlen on needle and otherwise strstr
computes the strlen anyway later.  But perhaps if strlen isn't known it
might be better to guard the strlen + strncmp on inline comparison of the
first character, so that one rules out the above mentioned special case,
so that we won't compute the strlen unnecessarily at least in that case.
Still strstr (32b_string, 2147483647b_string) == 32b_string will be
serious slowdown if 32b_string[0] == 2147483647b_string[0], but perhaps the
common case is more important.

Or do we want to add to the C library some kind of asymetric strcmp,
which will be equivalent to strncmp (p1, p2, strlen (p2)) but will actually
not compute the strlen but only compare the characters and just handle the
case where p2 has as the first different character '\0' as return 0 rather
than difference?

Jakub



[committed] tree-ssa-tail-merge: Fix a comment typo

2023-09-05 Thread Jakub Jelinek via Gcc-patches
Hi!

I've noticed a typo in a comment, fixed thusly.
Committed to trunk as obvious.

2023-09-05  Jakub Jelinek  

* tree-ssa-tail-merge.cc (replace_block_by): Fix a comment typo:
avreage -> average.

--- gcc/tree-ssa-tail-merge.cc.jj   2023-07-11 13:40:40.253431941 +0200
+++ gcc/tree-ssa-tail-merge.cc  2023-09-04 22:46:50.035269079 +0200
@@ -1605,7 +1605,7 @@ replace_block_by (basic_block bb1, basic
 
/* If probabilities are same, we are done.
   If counts are nonzero we can distribute accordingly. In remaining
-  cases just avreage the values and hope for the best.  */
+  cases just average the values and hope for the best.  */
e2->probability = e1->probability.combine_with_count
 (bb1->count, e2->probability, bb2->count);
   }

Jakub



[PATCH 18/12] Handle BITINT_TYPE in build_{, minus_}one_cst [PR102989]

2023-09-05 Thread Jakub Jelinek via Gcc-patches
Hi!

Recent match.pd changes trigger ICE in build_minus_one_cst, apparently
I forgot to handle BITINT_TYPE in these (while I've handled it in
build_zero_cst).

Will commit as obvious together with the rest of the series when the last
patches are approved.

2023-09-05  Jakub Jelinek  

PR c/102989
* tree.cc (build_one_cst, build_minus_one_cst): Handle BITINT_TYPE
like INTEGER_TYPE.

--- gcc/tree.cc.jj  2023-09-04 09:45:33.444059843 +0200
+++ gcc/tree.cc 2023-09-05 08:57:31.420059962 +0200
@@ -2546,7 +2546,7 @@ build_one_cst (tree type)
 {
 case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
 case POINTER_TYPE: case REFERENCE_TYPE:
-case OFFSET_TYPE:
+case OFFSET_TYPE: case BITINT_TYPE:
   return build_int_cst (type, 1);
 
 case REAL_TYPE:
@@ -2599,7 +2599,7 @@ build_minus_one_cst (tree type)
 {
 case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
 case POINTER_TYPE: case REFERENCE_TYPE:
-case OFFSET_TYPE:
+case OFFSET_TYPE: case BITINT_TYPE:
   return build_int_cst (type, -1);
 
 case REAL_TYPE:

Jakub



[PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989]

2023-09-05 Thread Jakub Jelinek via Gcc-patches
On Wed, Aug 09, 2023 at 12:19:54PM -0700, Andrew Pinski via Gcc-patches wrote:
>   PR tree-optimization/110937
>   PR tree-optimization/100798
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -6460,6 +6460,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>(if (cmp == NE_EXPR)
> { constant_boolean_node (true, type); })))
>  
> +#if GIMPLE
> +/* a?~t:t -> (-(a))^t */
> +(simplify
> + (cond @0 @1 @2)
> + (if (INTEGRAL_TYPE_P (type)
> +  && bitwise_inverted_equal_p (@1, @2))
> +  (with {
> +auto prec = TYPE_PRECISION (type);
> +auto unsign = TYPE_UNSIGNED (type);
> +tree inttype = build_nonstandard_integer_type (prec, unsign);
> +   }
> +   (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype @2))
> +#endif

This broke one bitint test - bitint-42.c for -O1 and -Os (in admittedly not yet
committed series).
Using build_nonstandard_integer_type this way doesn't work well for larger
precision BITINT_TYPEs, because it always creates an INTEGER_TYPE and
say 467-bit INTEGER_TYPE doesn't work very well.  To get a BITINT_TYPE, one
needs to use build_bitint_type instead (but similarly to
build_nonstandard_integer_type one should first make sure such a type
actually can be created).

I admit it isn't really clear to me what do you want to achieve by the
above build_nonstandard_integer_type.  Is it because of BOOLEAN_TYPE
or perhaps ENUMERAL_TYPE as well?

If type is INTEGER_TYPE or BITINT_TYPE, one doesn't really need to create a
new type, type already is an integral type with that precision and
signedness.  In other places using unsigned_type_for or signed_type_for
might be better than using build_nonstandard_integer_type if that is what
one wants to achieve, those functions handle BITINT_TYPE.

Or shall we instead test for == BOOLEAN_TYPE (or if ENUMERAL_TYPE for
some reason needs the same treatment also || == ENUMERAL_TYPE)?

2023-09-05  Jakub Jelinek  

PR c/102989
* match.pd (a ? ~b : b): Don't use build_nonstandard_integer_type
for INTEGER_TYPE or BITINT_TYPE.

--- gcc/match.pd.jj 2023-09-04 09:45:33.553058301 +0200
+++ gcc/match.pd2023-09-05 08:45:53.258078971 +0200
@@ -6631,7 +6631,9 @@ (define_operator_list SYNC_FETCH_AND_AND
(with {
  auto prec = TYPE_PRECISION (type);
  auto unsign = TYPE_UNSIGNED (type);
- tree inttype = build_nonstandard_integer_type (prec, unsign);
+ tree inttype = type;
+ if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != BITINT_TYPE)
+   inttype = build_nonstandard_integer_type (prec, unsign);
 }
 (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype @2)))
 #endif


Jakub



[PATCH 16/12] _BitInt profile fixes [PR102989]

2023-09-05 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 24, 2023 at 03:14:32PM +0200, Jan Hubicka via Gcc-patches wrote:
> this patch extends verifier to check that all probabilities and counts are
> initialized if profile is supposed to be present.  This is a bit complicated
> by the posibility that we inline !flag_guess_branch_probability function
> into function with profile defined and in this case we need to stop
> verification.  For this reason I added flag to cfg structure tracking this.

This patch broke a couple of _BitInt tests (in the admittedly still
uncommitted series - still waiting for review of the C FE bits).

Here is a minimal patch to make it work again, though I'm not sure
if in the if_then_else and if_then_if_then_else cases I shouldn't scale
count of the other bbs as well.  if_then method creates
if (COND) new_bb1;
in a middle of some pre-existing bb (with PROB that COND is true), if_then_else
if (COND) new_bb1; else new_bb2;
and if_then_if_then_else
if (COND1) { if (COND2) new_bb2; else new_bb1; }
with PROB1 and PROB2 probabilities that COND1 and COND2 are true.
The lowering happens shortly after IPA.

Ok for trunk with rest of the series?

2023-09-05  Jakub Jelinek  

PR c/102989
* gimple-lower-bitint.cc (bitint_large_huge::if_then_else,
bitint_large_huge::if_then_if_then_else): Use make_single_succ_edge
rather than make_edge, initialize bb->count.

--- gcc/gimple-lower-bitint.cc.jj   2023-09-04 09:45:37.357004452 +0200
+++ gcc/gimple-lower-bitint.cc  2023-09-04 22:53:30.343756938 +0200
@@ -683,9 +683,10 @@ bitint_large_huge::if_then_else (gimple
   e1->flags = EDGE_FALSE_VALUE;
   e3->probability = prob;
   e1->probability = prob.invert ();
+  bb->count = e1->src->count.apply_probability (prob);
   set_immediate_dominator (CDI_DOMINATORS, bb, e1->src);
   set_immediate_dominator (CDI_DOMINATORS, e2->dest, e1->src);
-  edge_true = make_edge (bb, e2->dest, EDGE_FALLTHRU);
+  edge_true = make_single_succ_edge (bb, e2->dest, EDGE_FALLTHRU);
   edge_false = e2;
   m_gsi = gsi_after_labels (bb);
 }
@@ -741,7 +742,8 @@ bitint_large_huge::if_then_if_then_else
   e4->probability = prob2;
   e2->flags = EDGE_FALSE_VALUE;
   e2->probability = prob2.invert ();
-  e4 = make_edge (bb, e3->dest, EDGE_FALLTHRU);
+  bb->count = e2->src->count.apply_probability (prob2);
+  e4 = make_single_succ_edge (bb, e3->dest, EDGE_FALLTHRU);
   e2 = find_edge (e2->dest, e3->dest);
   edge_true_true = e4;
   edge_true_false = e2;


Jakub



Re: [PATCH 9/12] libgcc _BitInt support [PR102989]

2023-09-02 Thread Jakub Jelinek via Gcc-patches
On Fri, Sep 01, 2023 at 09:48:22PM +, Joseph Myers wrote:
> This patch is OK with these fixes.

Thanks, here is an updated patch, thanks for catching the _Decimal128
bug.  Will post testsuite additions/adjustment patch as follow-up on Monday.

2023-09-02  Jakub Jelinek  

PR c/102989
libgcc/
* config/aarch64/t-softfp (softfp_extras): Use += rather than :=.
* config/i386/64/t-softfp (softfp_extras): Likewise.
* config/i386/libgcc-glibc.ver (GCC_14.0.0): Export _BitInt support
routines.
* config/i386/t-softfp (softfp_extras): Add fixxfbitint and
bf, hf and xf mode floatbitint.
(CFLAGS-floatbitintbf.c, CFLAGS-floatbitinthf.c): Add -msse2.
* config/riscv/t-softfp32 (softfp_extras): Use += rather than :=.
* config/rs6000/t-e500v1-fp (softfp_extras): Likewise.
* config/rs6000/t-e500v2-fp (softfp_extras): Likewise.
* config/t-softfp (softfp_floatbitint_funcs): New.
(softfp_bid_list): New.
(softfp_func_list): Add sf and df mode from and to _BitInt libcalls.
(softfp_bid_file_list): New.
(LIB2ADD_ST): Add $(softfp_bid_file_list).
* config/t-softfp-sfdftf (softfp_extras): Add fixtfbitint and
floatbitinttf.
* config/t-softfp-tf (softfp_extras): Likewise.
* libgcc2.c (bitint_reduce_prec): New inline function.
(BITINT_INC, BITINT_END): Define.
(bitint_mul_1, bitint_addmul_1): New helper functions.
(__mulbitint3): New function.
(bitint_negate, bitint_submul_1): New helper functions.
(__divmodbitint4): New function.
* libgcc2.h (LIBGCC2_UNITS_PER_WORD): When building _BitInt support
libcalls, redefine depending on __LIBGCC_BITINT_LIMB_WIDTH__.
(__mulbitint3, __divmodbitint4): Declare.
* libgcc-std.ver.in (GCC_14.0.0): Export _BitInt support routines.
* Makefile.in (lib2funcs): Add _mulbitint3.
(LIB2_DIVMOD_FUNCS): Add _divmodbitint4.
* soft-fp/bitint.h: New file.
* soft-fp/fixdfbitint.c: New file.
* soft-fp/fixsfbitint.c: New file.
* soft-fp/fixtfbitint.c: New file.
* soft-fp/fixxfbitint.c: New file.
* soft-fp/floatbitintbf.c: New file.
* soft-fp/floatbitintdf.c: New file.
* soft-fp/floatbitinthf.c: New file.
* soft-fp/floatbitintsf.c: New file.
* soft-fp/floatbitinttf.c: New file.
* soft-fp/floatbitintxf.c: New file.
* soft-fp/op-common.h (_FP_FROM_INT): Add support for rsize up to
4 * _FP_W_TYPE_SIZE rather than just 2 * _FP_W_TYPE_SIZE.
* soft-fp/bitintpow10.c: New file.
* soft-fp/fixsdbitint.c: New file.
* soft-fp/fixddbitint.c: New file.
* soft-fp/fixtdbitint.c: New file.
* soft-fp/floatbitintsd.c: New file.
* soft-fp/floatbitintdd.c: New file.
* soft-fp/floatbitinttd.c: New file.

--- libgcc/config/aarch64/t-softfp.jj   2023-08-08 15:54:35.737595343 +0200
+++ libgcc/config/aarch64/t-softfp  2023-08-08 16:12:02.346939560 +0200
@@ -3,7 +3,7 @@ softfp_int_modes := si di ti
 softfp_extensions := sftf dftf hftf bfsf
 softfp_truncations := tfsf tfdf tfhf tfbf dfbf sfbf hfbf
 softfp_exclude_libgcc2 := n
-softfp_extras := fixhfti fixunshfti floattihf floatuntihf \
+softfp_extras += fixhfti fixunshfti floattihf floatuntihf \
 floatdibf floatundibf floattibf floatuntibf
 
 TARGET_LIBGCC2_CFLAGS += -Wno-missing-prototypes
--- libgcc/config/i386/64/t-softfp.jj   2023-08-08 15:54:35.766594936 +0200
+++ libgcc/config/i386/64/t-softfp  2023-08-08 16:12:02.346939560 +0200
@@ -1,4 +1,4 @@
-softfp_extras := fixhfti fixunshfti floattihf floatuntihf \
+softfp_extras += fixhfti fixunshfti floattihf floatuntihf \
 floattibf floatuntibf
 
 CFLAGS-fixhfti.c += -msse2
--- libgcc/config/i386/libgcc-glibc.ver.jj  2023-08-08 15:54:35.831594026 
+0200
+++ libgcc/config/i386/libgcc-glibc.ver 2023-08-08 16:12:02.347939546 +0200
@@ -226,3 +226,13 @@ GCC_13.0.0 {
   __truncxfbf2
   __trunchfbf2
 }
+
+%inherit GCC_14.0.0 GCC_13.0.0
+GCC_14.0.0 {
+  __PFX__fixxfbitint
+  __PFX__fixtfbitint
+  __PFX__floatbitintbf
+  __PFX__floatbitinthf
+  __PFX__floatbitintxf
+  __PFX__floatbitinttf
+}
--- libgcc/config/i386/t-softfp.jj  2023-08-08 15:55:09.819118062 +0200
+++ libgcc/config/i386/t-softfp 2023-08-08 16:12:02.347939546 +0200
@@ -10,7 +10,7 @@ softfp_extensions := hfsf hfdf hftf hfxf
 softfp_truncations := tfhf xfhf dfhf sfhf tfsf dfsf tfdf tfxf \
  tfbf xfbf dfbf sfbf hfbf
 
-softfp_extras += eqhf2
+softfp_extras += eqhf2 fixxfbitint $(foreach m,hf bf xf,floatbitint$(m))
 
 CFLAGS-extendhfsf2.c += -msse2
 CFLAGS-extendhfdf2.c += -msse2
@@ -28,6 +28,9 @@ CFLAGS-truncxfbf2.c += -msse2
 CFLAGS-trunctfbf2.c += -msse2
 CFLAGS-trunchfbf2.c += -msse2
 
+CFLAGS-floatbitintbf.c += -msse2
+CFLAGS-floatbitinthf.c += -msse2
+
 CFLAGS-eqhf2.c += -msse2
 CFLAGS-_divhc3.c += -msse2
 

Re: [PATCH 14/12] libgcc _BitInt helper documentation [PR102989]

2023-09-02 Thread Jakub Jelinek via Gcc-patches
On Fri, Sep 01, 2023 at 09:32:22PM +, Joseph Myers wrote:
> This patch is OK with those fixes.

Thanks, here is the updated patch.  Queued with the rest of approved
patches.

2023-09-02  Jakub Jelinek  

PR c/102989
gcc/
* doc/libgcc.texi (Bit-precise integer arithmetic functions):
Document general rules for _BitInt support library functions
and document __mulbitint3 and __divmodbitint4.
(Conversion functions): Document __fix{s,d,x,t}fbitint,
__floatbitint{s,d,x,t,h,b}f, __bid_fix{s,d,t}dbitint and
__bid_floatbitint{s,d,t}d.
libgcc/
* libgcc2.c (bitint_negate): Add function comment.
* soft-fp/bitint.h (bitint_negate): Add function comment.
(FP_TO_BITINT, FP_FROM_BITINT): Add comment explaining the macros.

--- gcc/doc/libgcc.texi.jj  2023-01-16 11:52:16.115733593 +0100
+++ gcc/doc/libgcc.texi 2023-08-22 12:35:08.561348126 +0200
@@ -218,6 +218,51 @@ These functions return the number of bit
 These functions return the @var{a} byteswapped.
 @end deftypefn
 
+@subsection Bit-precise integer arithmetic functions
+
+@code{_BitInt(@var{n})} library functions operate on arrays of limbs, where
+each limb has @code{__LIBGCC_BITINT_LIMB_WIDTH__} bits and the limbs are
+ordered according to @code{__LIBGCC_BITINT_ORDER__} ordering.  The most
+significant limb if @var{n} is not divisible by
+@code{__LIBGCC_BITINT_LIMB_WIDTH__} contains padding bits which should be
+ignored on read (sign or zero extended), but extended on write.  For the
+library functions, all bit-precise integers regardless of @var{n} are
+represented like that, even when the target ABI says that for some small
+@var{n} they should be represented differently in memory.  A pointer
+to the array of limbs argument is always accompanied with a bit size
+argument.  If that argument is positive, it is number of bits and the
+number is assumed to be zero-extended to infinite precision, if that
+argument is negative, it is negated number of bits above which all bits
+are assumed to be sign-extended to infinite precision.  These number of bits
+arguments don't need to match actual @var{n} for the operation used in the
+source, they could be lowered because of sign or zero extensions on the
+input or because value-range optimization figures value will need certain
+lower number of bits.  For big-endian ordering of limbs, when lowering
+the bit size argument the pointer argument needs to be adjusted as well.
+Negative bit size argument should be always smaller or equal to @code{-2},
+because @code{signed _BitInt(1)} is not valid.
+For output arguments, either the corresponding bit size argument should
+be always positive (for multiplication and division), or is negative when
+the output of conversion from floating-point value is signed and positive
+when unsigned.  The arrays of limbs output arguments point to should not
+overlap any inputs, while input arrays of limbs can overlap.
+@code{UBILtype} below stands for unsigned integer type with
+@code{__LIBGCC_BITINT_LIMB_WIDTH__} bit precision.
+
+@deftypefn {Runtime Function} void __mulbitint3 (@code{UBILtype} *@var{ret}, 
int32_t @var{retprec}, const @code{UBILtype} *u, int32_t @var{uprec}, const 
@code{UBILtype} *v, int32_t @var{vprec})
+This function multiplies bit-precise integer operands @var{u} and @var{v} and 
stores
+result into @var{retprec} precision bit-precise integer result @var{ret}.
+@end deftypefn
+
+@deftypefn {Runtime Function} void __divmodbitint4 (@code{UBILtype} *@var{q}, 
int32_t @var{qprec}, @code{UBILtype} *@var{r}, int32_t @var{rprec},  const 
@code{UBILtype} *u, int32_t @var{uprec}, const @code{UBILtype} *v, int32_t 
@var{vprec})
+This function divides bit-precise integer operands @var{u} and @var{v} and 
stores
+quotient into @var{qprec} precision bit-precise integer result @var{q}
+(unless @var{q} is @code{NULL} and @var{qprec} is 0, in that case quotient
+is not stored anywhere) and remainder into @var{rprec} precision bit-precise
+integer result @var{r} (similarly, unless @var{r} is @code{NULL} and 
@var{rprec}
+is 0).
+@end deftypefn
+
 @node Soft float library routines
 @section Routines for floating point emulation
 @cindex soft float library
@@ -384,6 +429,27 @@ These functions convert @var{i}, an unsi
 These functions convert @var{i}, an unsigned long long, to floating point.
 @end deftypefn
 
+@deftypefn {Runtime Function} void __fixsfbitint (@code{UBILtype} *@var{r}, 
int32_t @var{rprec}, float @var{a})
+@deftypefnx {Runtime Function} void __fixdfbitint (@code{UBILtype} *@var{r}, 
int32_t @var{rprec}, double @var{a})
+@deftypefnx {Runtime Function} void __fixxfbitint (@code{UBILtype} *@var{r}, 
int32_t @var{rprec}, __float80 @var{a})
+@deftypefnx {Runtime Function} void __fixtfbitint (@code{UBILtype} *@var{r}, 
int32_t @var{rprec}, _Float128 @var{a})
+These functions convert @var{a} to bit-precise integer @var{r}, rounding 
toward zero.
+If @var{rprec} is positive, it converts to unsigned 

[PATCH] c++, v3: Diagnose [basic.scope.block]/2 violations even in compound-stmt of function-try-block [PR52953]

2023-09-01 Thread Jakub Jelinek via Gcc-patches
On Fri, Sep 01, 2023 at 03:24:54PM +0200, Jakub Jelinek via Gcc-patches wrote:
> So like this?
> 
> It actually changes behaviour on the
> void foo (int x) try {} catch (int x) {} case, where previously
> this triggered the
>|| (TREE_CODE (old) == PARM_DECL
>&& (current_binding_level->kind == sk_catch
>|| current_binding_level->level_chain->kind == 
> sk_catch)
>&& in_function_try_handler))
> {
>   auto_diagnostic_group d;
>   if (permerror (DECL_SOURCE_LOCATION (decl),
>  "redeclaration of %q#D", decl))
> inform (DECL_SOURCE_LOCATION (old),
> "%q#D previously declared here", old);
> diagnostics (note, just the current_binding_level->kind == sk_catch
> case), while now it triggers already the earlier
>   if (b->kind == sk_function_parms)
> {
>   error_at (DECL_SOURCE_LOCATION (decl),
> "declaration of %q#D shadows a parameter", decl);
>   inform (DECL_SOURCE_LOCATION (old),
>   "%q#D previously declared here", old);
> error.  If you think it is important to differentiate that,
> I guess I could guard the while (b->artificial) loop with say
> +   if (!in_function_try_handler
> +   || current_binding_level->kind != sk_catch)
>   while (b->artificial)
> b = b->level_chain;
> and adjust the 2 testcases.

BTW, that in_function_try_handler case doesn't work correctly
(before/after this patch),
void
foo (int x)
try {
}
catch (int)
{
  try {
  } catch (int x)
  {
  }
  try {
  } catch (int)
  {
int x;
  }
}
(which is valid) is rejected, because
|| (TREE_CODE (old) == PARM_DECL
&& (current_binding_level->kind == sk_catch
|| current_binding_level->level_chain->kind == sk_catch)
&& in_function_try_handler))
is true but nothing verified that for the first case
current_binding_level->level_chain->kind == sk_function_params
(with perhaps artificial scopes in between and in the latter case
with one extra level in between).

Here is an untested variant of the patch which does diagnostics of the
in_function_try_handler cases only if it is proven there are no intervening
non-artificial scopes, but uses the old wording + permerror for that case
like before.

Another possibility would be to use permerror for that case but the
"declaration of %q#D shadows a parameter" wording (then we'd need to adjust
both testcases, each on one line).

2023-09-01  Jakub Jelinek  

PR c++/52953
* name-lookup.h (struct cp_binding_level): Add artificial bit-field.
Formatting fixes.
* name-lookup.cc (check_local_shadow): Skip artificial bindings when
checking if parameter scope is parent scope.  Don't special case
FUNCTION_NEEDS_BODY_BLOCK.  Diagnose the in_function_try_handler
cases in the b->kind == sk_function_parms test, verify no
non-artificial intervening scopes but use permerror for that case with
different wording.  Add missing auto_diagnostic_group.
* decl.cc (begin_function_body): Set
current_binding_level->artificial.
* semantics.cc (begin_function_try_block): Likewise.

* g++.dg/diagnostic/redeclaration-3.C: New test.

--- gcc/cp/name-lookup.h.jj 2023-09-01 12:15:22.574619674 +0200
+++ gcc/cp/name-lookup.h2023-09-01 16:11:47.838401045 +0200
@@ -292,11 +292,11 @@ struct GTY(()) cp_binding_level {
   only valid if KIND == SK_TEMPLATE_PARMS.  */
   BOOL_BITFIELD explicit_spec_p : 1;
 
-  /* true means make a BLOCK for this level regardless of all else.  */
+  /* True means make a BLOCK for this level regardless of all else.  */
   unsigned keep : 1;
 
   /* Nonzero if this level can safely have additional
-  cleanup-needing variables added to it.  */
+ cleanup-needing variables added to it.  */
   unsigned more_cleanups_ok : 1;
   unsigned have_cleanups : 1;
 
@@ -308,9 +308,13 @@ struct GTY(()) cp_binding_level {
   unsigned defining_class_p : 1;
 
   /* True for SK_FUNCTION_PARMS of a requires-expression.  */
-  unsigned requires_expression: 1;
+  unsigned requires_expression : 1;
 
-  /* 22 bits left to fill a 32-bit word.  */
+  /* True for artificial blocks which should be ignored when finding
+ parent scope.  */
+  unsigned artificial : 1;
+
+  /* 21 bits left to fill a 32-bit word.  */
 };
 
 /* The binding level currently in effect.  */
--- gcc/cp/name-lookup.cc.jj2023-09-01 12:15:22.566619785 +0200
+++ gcc/cp/name-lookup.cc   2023-09-01 16:19:12.567335710 +0200
@@ -3146,18 +3146,34 @@ check_local_shadow 

[PATCH] c++, v2: Diagnose [basic.scope.block]/2 violations even for block externs [PR52953]

2023-09-01 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 31, 2023 at 05:46:28PM -0400, Jason Merrill wrote:
> I've suggested this to Core.

Thanks.

> > So, I'm not really sure what to do.  Intuitively the patch seems right
> > because even block externs redeclare stuff and change meaning of the
> > identifiers and void foo () { int i; extern int i (int); } is rejected
> > by all compilers.
> 
> I think this direction makes sense, though we might pedwarn on these rather
> than error to reduce possible breakage.

It wasn't clear to me whether you want to make those pedwarns just for the
DECL_EXTERNAL cases, ones that actually changed, or all others as well
(which were errors or permerrors depending on the case).
I've implemented the former, kept existing behavior of !DECL_EXTERNAL.

> > 2023-08-31  Jakub Jelinek  
> > 
> > PR c++/52953
> > * name-lookup.cc (check_local_shadow): Defer punting on
> > DECL_EXTERNAL (decl) from the start of function to right before
> > the -Wshadow* checks.
> 
> Don't we want to consider externs for the -Wshadow* checks as well?

I think that is a good idea (though dunno how much it will trigger in
real-world), but there is one case I've excluded, the global variable
shadowing case, because warning that
int z;
void foo () { extern int z; z = 1; }
shadows the global var would be incorrect, it is the same var.
It is true that
int y; namespace N { void bar () { extern int y; y = 1; } }
shadows ::y but it is unclear how to differentiate those two cases with
the information we have at check_local_shadow time.

I've also found one spot which wasn't using auto_diagnostic_group d;
on a pair of error_at/inform.

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

2023-09-01  Jakub Jelinek  

PR c++/52953
* name-lookup.cc (check_local_shadow): Don't punt early for
DECL_EXTERNAL decls, instead just disable the shadowing of namespace
decls check for those and emit a pedwarn rather than error_at for
those.  Add missing auto_diagnostic_group.  Formatting fix.

* g++.dg/diagnostic/redeclaration-4.C: New test.
* g++.dg/diagnostic/redeclaration-5.C: New test.
* g++.dg/warn/Wshadow-19.C: New test.

--- gcc/cp/name-lookup.cc.jj2023-09-01 10:21:03.658118594 +0200
+++ gcc/cp/name-lookup.cc   2023-09-01 11:30:10.868516494 +0200
@@ -3096,10 +3096,6 @@ check_local_shadow (tree decl)
   if (TREE_CODE (decl) == PARM_DECL && !DECL_CONTEXT (decl))
 return;
 
-  /* External decls are something else.  */
-  if (DECL_EXTERNAL (decl))
-return;
-
   tree old = NULL_TREE;
   cp_binding_level *old_scope = NULL;
   if (cxx_binding *binding = outer_binding (DECL_NAME (decl), NULL, true))
@@ -3130,11 +3126,9 @@ check_local_shadow (tree decl)
  && DECL_CONTEXT (old) == lambda_function (current_lambda_expr ())
  && TREE_CODE (old) == PARM_DECL
  && DECL_NAME (decl) != this_identifier)
-   {
- error_at (DECL_SOURCE_LOCATION (old),
-   "lambda parameter %qD "
-   "previously declared as a capture", old);
-   }
+   error_at (DECL_SOURCE_LOCATION (old),
+ "lambda parameter %qD "
+ "previously declared as a capture", old);
  return;
}
   /* Don't complain if it's from an enclosing function.  */
@@ -3156,10 +3150,18 @@ check_local_shadow (tree decl)
 in the outermost block of the function definition.  */
  if (b->kind == sk_function_parms)
{
- error_at (DECL_SOURCE_LOCATION (decl),
-   "declaration of %q#D shadows a parameter", decl);
- inform (DECL_SOURCE_LOCATION (old),
- "%q#D previously declared here", old);
+ auto_diagnostic_group d;
+ bool emit = true;
+ if (DECL_EXTERNAL (decl))
+   emit = pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic,
+   "declaration of %q#D shadows a parameter",
+   decl);
+ else
+   error_at (DECL_SOURCE_LOCATION (decl),
+ "declaration of %q#D shadows a parameter", decl);
+ if (emit)
+   inform (DECL_SOURCE_LOCATION (old),
+   "%q#D previously declared here", old);
  return;
}
}
@@ -3185,10 +3187,16 @@ check_local_shadow (tree decl)
   && (old_scope->kind == sk_cond || old_scope->kind == sk_for))
{
  auto_diagnostic_group d;
- error_at (DECL_SOURCE_LOCATION (decl),
-   "redeclaration of %q#D", decl);
- inform (DECL_SOURCE_LOCATION (old),
- "%q#D previously declared here", old);
+ bool emit = true;
+ if (DECL_EXTERNAL (decl))
+   emit = pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic,
+   "redeclaration of 

[PATCH] c++, v2: Diagnose [basic.scope.block]/2 violations even in compound-stmt of function-try-block [PR52953]

2023-09-01 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 31, 2023 at 03:52:22PM -0400, Jason Merrill wrote:
> On 8/31/23 03:20, Jakub Jelinek wrote:
> > As the following testcase shows, while check_local_shadow diagnoses most of
> > the [basic.scope.block]/2 violations, it doesn't diagnose when parameter's
> > name is redeclared inside of the compound-stmt of a function-try-block.
> > 
> > There is in that case an extra scope (sk_try with parent artificial
> > sk_block with for FUNCTION_NEEDS_BODY_BLOCK another sk_block and only then
> > sk_function_param).
> > 
> > The following patch fixes that.
> > 
> > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> > 
> > 2023-08-31  Jakub Jelinek  
> > 
> > PR c++/52953
> > * cp-tree.h (struct language_function): Add x_in_function_try_block
> > member.
> 
> How about adding a flag to cp_binding_level instead?  Maybe to mark the
> artificial sk_block level as such, which we could use for both this case and
> the FUNCTION_NEEDS_BODY_BLOCK cases.

So like this?

It actually changes behaviour on the
void foo (int x) try {} catch (int x) {} case, where previously
this triggered the
   || (TREE_CODE (old) == PARM_DECL
   && (current_binding_level->kind == sk_catch
   || current_binding_level->level_chain->kind == sk_catch)
   && in_function_try_handler))
{
  auto_diagnostic_group d;
  if (permerror (DECL_SOURCE_LOCATION (decl),
 "redeclaration of %q#D", decl))
inform (DECL_SOURCE_LOCATION (old),
"%q#D previously declared here", old);
diagnostics (note, just the current_binding_level->kind == sk_catch
case), while now it triggers already the earlier
  if (b->kind == sk_function_parms)
{
  error_at (DECL_SOURCE_LOCATION (decl),
"declaration of %q#D shadows a parameter", decl);
  inform (DECL_SOURCE_LOCATION (old),
  "%q#D previously declared here", old);
error.  If you think it is important to differentiate that,
I guess I could guard the while (b->artificial) loop with say
+ if (!in_function_try_handler
+ || current_binding_level->kind != sk_catch)
while (b->artificial)
  b = b->level_chain;
and adjust the 2 testcases.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk
or with modification?

2023-09-01  Jakub Jelinek  

PR c++/52953
* name-lookup.h (struct cp_binding_level): Add artificial bit-field.
Formatting fixes.
* name-lookup.cc (check_local_shadow): Skip artificial bindings when
checking if parameter scope is parent scope.  Don't special case
FUNCTION_NEEDS_BODY_BLOCK.
* decl.cc (begin_function_body): Set
current_binding_level->artificial.
* semantics.cc (begin_function_try_block): Likewise.

* g++.dg/diagnostic/redeclaration-3.C: New test.
* g++.dg/parse/pr31952-3.C: Expect different diagnostic wording.

--- gcc/cp/name-lookup.h.jj 2023-08-21 11:57:33.105460770 +0200
+++ gcc/cp/name-lookup.h2023-09-01 10:15:20.137943395 +0200
@@ -292,11 +292,11 @@ struct GTY(()) cp_binding_level {
   only valid if KIND == SK_TEMPLATE_PARMS.  */
   BOOL_BITFIELD explicit_spec_p : 1;
 
-  /* true means make a BLOCK for this level regardless of all else.  */
+  /* True means make a BLOCK for this level regardless of all else.  */
   unsigned keep : 1;
 
   /* Nonzero if this level can safely have additional
-  cleanup-needing variables added to it.  */
+ cleanup-needing variables added to it.  */
   unsigned more_cleanups_ok : 1;
   unsigned have_cleanups : 1;
 
@@ -308,9 +308,13 @@ struct GTY(()) cp_binding_level {
   unsigned defining_class_p : 1;
 
   /* True for SK_FUNCTION_PARMS of a requires-expression.  */
-  unsigned requires_expression: 1;
+  unsigned requires_expression : 1;
 
-  /* 22 bits left to fill a 32-bit word.  */
+  /* True for artificial blocks which should be ignored when finding
+ parent scope.  */
+  unsigned artificial : 1;
+
+  /* 21 bits left to fill a 32-bit word.  */
 };
 
 /* The binding level currently in effect.  */
--- gcc/cp/name-lookup.cc.jj2023-08-31 14:31:06.055762306 +0200
+++ gcc/cp/name-lookup.cc   2023-09-01 10:21:03.658118594 +0200
@@ -3146,8 +3146,10 @@ check_local_shadow (tree decl)
 them there.  */
  cp_binding_level *b = current_binding_level->level_chain;
 
- if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
-   /* Skip the ctor/dtor cleanup level.  */
+ /* Skip artificially added scopes which aren't present
+in the C++ standard, e.g. for function-try-block or
+ctor/dtor cleanups.  */
+ while (b->artificial)
b = b->level_chain;
 
  /* [basic.scope.param] A parameter name shall not be redeclared
--- gcc/cp/decl.cc.jj   2023-08-31 

[committed] testsuite: Fix vectcond-1.C FAIL on i686-linux [PR19832]

2023-09-01 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 31, 2023 at 10:24:10AM -0700, Andrew Pinski via Gcc-patches wrote:
> This patch adds the following match patterns to optimize these:
>  /* (a != b) ? (a - b) : 0 -> (a - b) */

These tests FAIL on i686-linux, with
.../gcc/testsuite/gcc.dg/pr110915-1.c:8:1: warning: MMX vector return without 
MMX enabled changes the ABI [-Wpsabi]
.../gcc/testsuite/gcc.dg/pr110915-1.c:7:15: warning: MMX vector argument 
without MMX enabled changes the ABI [-Wpsabi]
excess warnings.  I've added -Wno-psabi to quiet that up, plus I think
it is undesirable to define macros like vector before including C library
headers in case the header would use that identifier in non-obfuscated
form somewhere.

Tested with
make check-g++ RUNTESTFLAGS='--target_board=unix\{-m32,-m32/-march=i686,-m64\} 
dg.exp=vectcond-1.C'
on x86_64-linux which previously FAILed, committed to trunk as obvious.

2023-09-01  Jakub Jelinek  

PR tree-optimization/19832
* g++.dg/opt/vectcond-1.C: Add -Wno-psabi to dg-options.

--- gcc/testsuite/g++.dg/opt/vectcond-1.C.jj2023-09-01 12:15:36.072430927 
+0200
+++ gcc/testsuite/g++.dg/opt/vectcond-1.C   2023-09-01 14:20:22.688739458 
+0200
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-ccp1 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-ccp1 -fdump-tree-optimized -Wno-psabi" } */
 /* This is the vector version of these optimizations. */
 /* PR tree-optimization/19832 */
 

Jakub



[committed] testsuite: Fix up pr110915* tests on i686-linux [PR110915]

2023-09-01 Thread Jakub Jelinek via Gcc-patches
On Wed, Aug 30, 2023 at 03:25:11PM -0700, Andrew Pinski via Gcc-patches wrote:
> This simple patch extends the min_value/max_value match to vector integer 
> types.
> Using uniform_integer_cst_p makes this easy.

These tests FAIL on i686-linux, with
.../gcc/testsuite/gcc.dg/pr110915-1.c:8:1: warning: MMX vector return without 
MMX enabled changes the ABI [-Wpsabi]
.../gcc/testsuite/gcc.dg/pr110915-1.c:7:15: warning: MMX vector argument 
without MMX enabled changes the ABI [-Wpsabi]
excess warnings.  I've added -Wno-psabi to quiet that up, plus I think
it is undesirable to define macros like vector before including C library
headers in case the header would use that identifier in non-obfuscated
form somewhere.

Tested on x86_64-linux with
make check-gcc RUNTESTFLAGS='--target_board=unix\{-m32,-m32/-march=i686,-m64\} 
dg.exp=pr110915*'
which previously FAILed, committed to trunk as obvious.

2023-09-01  Jakub Jelinek  

PR tree-optimization/110915
* gcc.dg/pr110915-1.c: Add -Wno-psabi to dg-options.  Move vector
macro definition after limits.h inclusion.
* gcc.dg/pr110915-2.c: Likewise.
* gcc.dg/pr110915-3.c: Likewise.
* gcc.dg/pr110915-4.c: Likewise.
* gcc.dg/pr110915-5.c: Likewise.
* gcc.dg/pr110915-6.c: Likewise.
* gcc.dg/pr110915-7.c: Likewise.
* gcc.dg/pr110915-8.c: Likewise.
* gcc.dg/pr110915-9.c: Likewise.
* gcc.dg/pr110915-10.c: Likewise.
* gcc.dg/pr110915-11.c: Likewise.
* gcc.dg/pr110915-12.c: Likewise.

--- gcc/testsuite/gcc.dg/pr110915-1.c.jj2023-08-31 19:52:16.889305069 
+0200
+++ gcc/testsuite/gcc.dg/pr110915-1.c   2023-09-01 14:12:47.937873487 +0200
@@ -1,9 +1,10 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-ifcombine" } */
-#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+/* { dg-options "-O2 -fdump-tree-ifcombine -Wno-psabi" } */
 
 #include 
 
+#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+
 vector signed and1(vector unsigned x, vector unsigned y)
 {
   /* (x > y) & (x != 0)  --> x > y */
--- gcc/testsuite/gcc.dg/pr110915-2.c.jj2023-08-31 19:52:16.889305069 
+0200
+++ gcc/testsuite/gcc.dg/pr110915-2.c   2023-09-01 14:12:52.791808013 +0200
@@ -1,9 +1,10 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
-#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+/* { dg-options "-O2 -fdump-tree-optimized -Wno-psabi" } */
 
 #include 
 
+#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+
 vector signed and1(vector unsigned x, vector unsigned y)
 {
   /* (x > y)   &   (x != 0)  --> x > y */
--- gcc/testsuite/gcc.dg/pr110915-3.c.jj2023-08-31 19:52:16.889305069 
+0200
+++ gcc/testsuite/gcc.dg/pr110915-3.c   2023-09-01 14:12:57.514744307 +0200
@@ -1,9 +1,10 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-ifcombine" } */
-#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+/* { dg-options "-O2 -fdump-tree-ifcombine -Wno-psabi" } */
 
 #include 
 
+#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+
 vector signed and1(vector unsigned x, vector unsigned y)
 {
   /* (x > y)   &   (x == 0)  --> false */
--- gcc/testsuite/gcc.dg/pr110915-4.c.jj2023-08-31 19:52:16.889305069 
+0200
+++ gcc/testsuite/gcc.dg/pr110915-4.c   2023-09-01 14:13:02.094682529 +0200
@@ -1,9 +1,10 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
-#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+/* { dg-options "-O2 -fdump-tree-optimized -Wno-psabi" } */
 
 #include 
 
+#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+
 vector signed and1(vector unsigned x, vector unsigned y)
 {
   /* (x > y)   &   (x == 0)  --> false */
--- gcc/testsuite/gcc.dg/pr110915-5.c.jj2023-08-31 19:52:16.889305069 
+0200
+++ gcc/testsuite/gcc.dg/pr110915-5.c   2023-09-01 14:13:06.609621628 +0200
@@ -1,9 +1,10 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-ifcombine" } */
-#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+/* { dg-options "-O2 -fdump-tree-ifcombine -Wno-psabi" } */
 
 #include 
 
+#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+
 vector signed and1(vector unsigned x, vector unsigned y)
 {
   /* (x <= y)   &   (x == 0)  --> x == 0 */
--- gcc/testsuite/gcc.dg/pr110915-6.c.jj2023-08-31 19:52:16.889305069 
+0200
+++ gcc/testsuite/gcc.dg/pr110915-6.c   2023-09-01 14:13:11.175560039 +0200
@@ -1,9 +1,10 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
-#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+/* { dg-options "-O2 -fdump-tree-optimized -Wno-psabi" } */
 
 #include 
 
+#define vector __attribute__((vector_size(sizeof(unsigned)*2)))
+
 vector signed and1(vector unsigned x, vector unsigned y)
 {
   /* (x <= y)   &   (x == 0)  --> x == 0 */
--- gcc/testsuite/gcc.dg/pr110915-7.c.jj2023-08-31 

Re: [PATCH 08/13] [APX EGPR] Handle GPR16 only vector move insns

2023-09-01 Thread Jakub Jelinek via Gcc-patches
On Fri, Sep 01, 2023 at 07:34:16PM +0800, Hongyu Wang wrote:
> > On Fri, Sep 01, 2023 at 05:07:53PM +0800, Hongyu Wang wrote:
> > > Jakub Jelinek via Gcc-patches  于2023年8月31日周四 
> > > 17:44写道:
> > > >
> > > > On Thu, Aug 31, 2023 at 04:20:19PM +0800, Hongyu Wang via Gcc-patches 
> > > > wrote:
> > > > > For vector move insns like vmovdqa/vmovdqu, their evex counterparts
> > > > > requrire explicit suffix 64/32/16/8. The usage of these instruction
> > > > > are prohibited under AVX10_1 or AVX512F, so for AVX2+APX_F we select
> > > > > vmovaps/vmovups for vector load/store insns that contains EGPR.
> > > >
> > > > Why not make it dependent on AVX512VL?
> > > > I.e. if egpr_p && TARGET_AVX512VL, still use vmovdqu16 or vmovdqa16
> > > > and the like, and only if !evex_reg_p && egpr_p && !TARGET_AVX512VL
> > > > fall back to what you're doing?
> > >
> > > I'm not sure if it is necessary, as on hardware there is no difference 
> > > between
> > > vmovdqu16/vmovups. If vmovups already has the capability to represent
> > > EGPR why do we need to distinguish them under VL?
> >
> > On the Intel HW you're currently planning.
> > Will that be the case for AMD as well?
> > Some insns are documented to move float or double vectors while others
> > integer vectors (of different element sizes).
> > Or is vmovups with GPR32 at least encoded smaller than vmovdqu{16,32,64}?
> 
> With GPR32 they have same encoding size. If we need to strictly follow
> the meaning of mnemonics,
> I will adjust as you suggested. Thanks.

I think it is useful, even if just for those who try to read the
assembler/disassembler.  Of course, if there are cases where only one of
those has to be used (say -mavx -mno-avx2 and 256-bit integer vector moves),
there is no way around that and one just uses what is available.

Jakub



Re: [PATCH 08/13] [APX EGPR] Handle GPR16 only vector move insns

2023-09-01 Thread Jakub Jelinek via Gcc-patches
On Fri, Sep 01, 2023 at 05:07:53PM +0800, Hongyu Wang wrote:
> Jakub Jelinek via Gcc-patches  于2023年8月31日周四 17:44写道:
> >
> > On Thu, Aug 31, 2023 at 04:20:19PM +0800, Hongyu Wang via Gcc-patches wrote:
> > > For vector move insns like vmovdqa/vmovdqu, their evex counterparts
> > > requrire explicit suffix 64/32/16/8. The usage of these instruction
> > > are prohibited under AVX10_1 or AVX512F, so for AVX2+APX_F we select
> > > vmovaps/vmovups for vector load/store insns that contains EGPR.
> >
> > Why not make it dependent on AVX512VL?
> > I.e. if egpr_p && TARGET_AVX512VL, still use vmovdqu16 or vmovdqa16
> > and the like, and only if !evex_reg_p && egpr_p && !TARGET_AVX512VL
> > fall back to what you're doing?
> 
> I'm not sure if it is necessary, as on hardware there is no difference between
> vmovdqu16/vmovups. If vmovups already has the capability to represent
> EGPR why do we need to distinguish them under VL?

On the Intel HW you're currently planning.
Will that be the case for AMD as well?
Some insns are documented to move float or double vectors while others
integer vectors (of different element sizes).
Or is vmovups with GPR32 at least encoded smaller than vmovdqu{16,32,64}?

Jakub



[PATCH] c++, v3: Fix up mangling of function/block scope static structured bindings and emit abi tags [PR111069]

2023-08-31 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 31, 2023 at 01:11:57PM -0400, Jason Merrill wrote:
> > 2023-08-28  Jakub Jelinek  
> > 
> > PR c++/111069
> > gcc/
> > * common.opt (fabi-version=): Document version 19.
> > * doc/invoke.texi (-fabi-version=): Likewise.
> > gcc/c-family/
> > * c-opts.cc (c_common_post_options): Change latest_abi_version to 19.
> > gcc/cp/
> > * cp-tree.h (determine_local_discriminator): Add NAME argument with
> > NULL_TREE default.
> > (struct cp_decomp): New type.
> 
> Maybe cp_finish_decomp should take this as well?  And tsubst_decomp_names,
> and various other functions with decomp_first_name/decomp_cnt parms?

Ok, done below.

> > +  if (tree tags = get_abi_tags (decl))
> > +{
> > +  /* We didn't emit ABI tags for structured bindings before ABI 19.  */
> > +  if (!G.need_abi_warning
> > +  && abi_warn_or_compat_version_crosses (19))
> > +   G.need_abi_warning = 1;
> 
> In general we should probably only warn about mangling changes if
> TREE_PUBLIC (decl).

I have done that but I think it ought to be unnecessary, because
check_abi_tags starts with
  if (!TREE_PUBLIC (decl))
/* No need to worry about things local to this TU.  */
return NULL_TREE;

Here is an updated patch, so far just tested with
make check-g++ GXX_TESTSUITE_STDS=98,11,14,17,20,2b,2c 
RUNTESTFLAGS="dg.exp='*decomp*'"
ok for trunk if it passes full bootstrap/regtest?

2023-08-31  Jakub Jelinek  

PR c++/111069
gcc/
* common.opt (fabi-version=): Document version 19.
* doc/invoke.texi (-fabi-version=): Likewise.
gcc/c-family/
* c-opts.cc (c_common_post_options): Change latest_abi_version to 19.
gcc/cp/
* cp-tree.h (determine_local_discriminator): Add NAME argument with
NULL_TREE default.
(struct cp_decomp): New type.
(cp_finish_decl): Add DECOMP argument defaulted to nullptr.
(cp_maybe_mangle_decomp): Remove declaration.
(cp_finish_decomp): Add cp_decomp * argument, remove tree and unsigned
args.
(cp_convert_range_for): Likewise.
* decl.cc (determine_local_discriminator): Add NAME argument, use it
if non-NULL, otherwise compute it the old way.
(maybe_commonize_var): Don't return early for structured bindings.
(cp_finish_decl): Add DECOMP argument, if non-NULL, call
cp_maybe_mangle_decomp.
(cp_maybe_mangle_decomp): Make it static with a forward declaration.
Call determine_local_discriminator.  Replace FIRST and COUNT arguments
with DECOMP argument.
(cp_finish_decomp): Replace FIRST and COUNT arguments with DECOMP
argument.
* mangle.cc (find_decomp_unqualified_name): Remove.
(write_unqualified_name): Don't call find_decomp_unqualified_name.
(mangle_decomp): Handle mangling of static function/block scope
structured bindings.  Don't call decl_mangling_context twice.  Call
check_abi_tags, call write_abi_tags for abi version >= 19 and emit
-Wabi warnings if needed.
(write_guarded_var_name): Handle structured bindings.
(mangle_ref_init_variable): Use write_guarded_var_name.
* parser.cc (cp_parser_range_for): Adjust do_range_for_auto_deduction
and cp_convert_range_for callers.
(do_range_for_auto_deduction): Replace DECOMP_FIRST_NAME and
DECOMP_CNT arguments with DECOMP.  Adjust cp_finish_decomp caller.
(cp_convert_range_for): Replace DECOMP_FIRST_NAME and
DECOMP_CNT arguments with DECOMP.  Don't call cp_maybe_mangle_decomp,
adjust cp_finish_decl and cp_finish_decomp callers.
(cp_parser_decomposition_declaration): Don't call
cp_maybe_mangle_decomp, adjust cp_finish_decl and cp_finish_decomp
callers.
(cp_convert_omp_range_for): Adjust do_range_for_auto_deduction
and cp_finish_decomp callers.
(cp_finish_omp_range_for): Don't call cp_maybe_mangle_decomp,
adjust cp_finish_decl and cp_finish_decomp callers.
* pt.cc (tsubst_omp_for_iterator): Adjust tsubst_decomp_names
caller.
(tsubst_decomp_names): Replace FIRST and CNT arguments with DECOMP.
(tsubst_expr): Don't call cp_maybe_mangle_decomp, adjust
tsubst_decomp_names, cp_finish_decl, cp_finish_decomp and
cp_convert_range_for callers.
gcc/testsuite/
* g++.dg/cpp2a/decomp8.C: New test.
* g++.dg/cpp2a/decomp9.C: New test.
* g++.dg/abi/macro0.C: Expect __GXX_ABI_VERSION 1019 rather than
1018.

--- gcc/common.opt.jj   2023-08-28 13:55:55.670370386 +0200
+++ gcc/common.opt  2023-08-31 19:53:31.186280641 +0200
@@ -1010,6 +1010,9 @@ Driver Undocumented
 ; 18: Corrects errors in mangling of lambdas with additional context.
 ; Default in G++ 13.
 ;
+; 19: Emits ABI tags if needed in structured binding mangled names.
+; Default in G++ 14.
+;
 ; Additional positive integers will be assigned as new versions of
 ; the ABI become 

Re: [PATCH] middle-end/111253 - partly revert r11-6508-gabb1b6058c09a7

2023-08-31 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 31, 2023 at 12:37:59PM +, Richard Biener via Gcc-patches wrote:
> The following keeps dumping SSA def stmt RHS during diagnostic
> reporting only for gimple_assign_single_p defs which means
> memory loads.  This avoids diagnostics containing PHI nodes
> like
> 
>   warning: 'realloc' called on pointer '*_42 = PHI  lcs.19_48(30)>.t_mem_caches' with nonzero offset 40
> 
> instead getting back the previous behavior:
> 
>   warning: 'realloc' called on pointer '*.t_mem_caches' with nonzero 
> offset 40
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu, OK?
> 
> Thanks,
> Richard.
> 
>   PR middle-end/111253
> gcc/c-family/
>   * c-pretty-print.cc (c_pretty_printer::primary_expression):
>   Only dump gimple_assign_single_p SSA def RHS.
> 
>   * gcc.dg/Wfree-nonheap-object-7.c: New testcase.

Ok.

Jakub



Re: [RFC] gimple ssa: SCCP - A new PHI optimization pass

2023-08-31 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 31, 2023 at 01:26:37PM +0200, Filip Kastl wrote:
> Regarding debug info coverage: I didn't notice any additional guality 
> testcases
> failing after I applied the patch. *Is there any other way how I should check
> debug info coverage?*

I'm usually using https://github.com/pmachata/dwlocstat
for that, usually on cc1plus from the last stage of gcc bootstrap.
Though of course, if one tree is unpatched and one patched, that results in
different code not just because the optimization did something, but because
it is different source.  So, for such purposes, I usually after one of the
2 bootstraps apply resp. revert the patch, make a copy of the cc1plus binary
and do make -jN cc1plus in the last stage directory (only there, not attempt
to rebootstrap).

Jakub



Re: [PATCH 08/13] [APX EGPR] Handle GPR16 only vector move insns

2023-08-31 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 31, 2023 at 04:20:19PM +0800, Hongyu Wang via Gcc-patches wrote:
> For vector move insns like vmovdqa/vmovdqu, their evex counterparts
> requrire explicit suffix 64/32/16/8. The usage of these instruction
> are prohibited under AVX10_1 or AVX512F, so for AVX2+APX_F we select
> vmovaps/vmovups for vector load/store insns that contains EGPR.

Why not make it dependent on AVX512VL?
I.e. if egpr_p && TARGET_AVX512VL, still use vmovdqu16 or vmovdqa16
and the like, and only if !evex_reg_p && egpr_p && !TARGET_AVX512VL
fall back to what you're doing?
> 
> gcc/ChangeLog:
> 
>   * config/i386/i386.cc (ix86_get_ssemov): Check if egpr is used,
>   adjust mnemonic for vmovduq/vmovdqa.
>   * config/i386/sse.md 
> (*_vinsert_0):
>   Check if egpr is used, adjust mnemonic for vmovdqu/vmovdqa.
>   (avx_vec_concat): Likewise, and separate alternative 0 to
>   avx_noavx512f.

Jakub



Re: [PATCH 11/13] [APX EGPR] Handle legacy insns that only support GPR16 (3/5)

2023-08-31 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 31, 2023 at 11:26:26AM +0200, Richard Biener wrote:
> On Thu, Aug 31, 2023 at 10:25 AM Hongyu Wang via Gcc-patches
>  wrote:
> >
> > From: Kong Lingling 
> >
> > Disable EGPR usage for below legacy insns in opcode map2/3 that have vex
> > but no evex counterpart.
> >
> > insn list:
> > 1. phminposuw/vphminposuw
> > 2. ptest/vptest
> > 3. roundps/vroundps, roundpd/vroundpd,
> >roundss/vroundss, roundsd/vroundsd
> > 4. pcmpestri/vpcmpestri, pcmpestrm/vpcmpestrm
> > 5. pcmpistri/vpcmpistri, pcmpistrm/vpcmpistrm
> 
> How are GPRs involved in the above?  Or did I misunderstand something?

Those instructions allow memory operands, and say vptest (%r18), %xmm7
isn't supported.

Jakub



Re: [PATCH 06/13] [APX EGPR] Map reg/mem constraints in inline asm to non-EGPR constraint.

2023-08-31 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 31, 2023 at 04:20:17PM +0800, Hongyu Wang via Gcc-patches wrote:
> From: Kong Lingling 
> 
> In inline asm, we do not know if the insn can use EGPR, so disable EGPR
> usage by default from mapping the common reg/mem constraint to non-EGPR
> constraints. Use a flag mapx-inline-asm-use-gpr32 to enable EGPR usage
> for inline asm.
> 
> gcc/ChangeLog:
> 
>   * config/i386/i386.cc (INCLUDE_STRING): Add include for
>   ix86_md_asm_adjust.
>   (ix86_md_asm_adjust): When APX EGPR enabled without specifying the
>   target option, map reg/mem constraints to non-EGPR constraints.
>   * config/i386/i386.opt: Add option mapx-inline-asm-use-gpr32.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.target/i386/apx-inline-gpr-norex2.c: New test.
> ---
>  gcc/config/i386/i386.cc   |  44 +++
>  gcc/config/i386/i386.opt  |   5 +
>  .../gcc.target/i386/apx-inline-gpr-norex2.c   | 107 ++
>  3 files changed, 156 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-inline-gpr-norex2.c
> 
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index d26d9ab0d9d..9460ebbfda4 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public 
> License
>  along with GCC; see the file COPYING3.  If not see
>  .  */
>  
> +#define INCLUDE_STRING
>  #define IN_TARGET_CODE 1
>  
>  #include "config.h"
> @@ -23077,6 +23078,49 @@ ix86_md_asm_adjust (vec , vec & 
> /*inputs*/,
>bool saw_asm_flag = false;
>  
>start_sequence ();
> +  /* TODO: Here we just mapped the general r/m constraints to non-EGPR
> +   constraints, will eventually map all the usable constraints in the 
> future. */

I think there should be some constraint which explicitly has all the 32
GPRs, like there is one for just all 16 GPRs (h), so that regardless of
-mapx-inline-asm-use-gpr32 one can be explicit what the inline asm wants.

Also, what about the "g" constraint?  Shouldn't there be another for "g"
without r16..r31?  What about the various other memory
constraints ("<", "o", ...)?

> +  if (TARGET_APX_EGPR && !ix86_apx_inline_asm_use_gpr32)
> +{
> +  /* Map "r" constraint in inline asm to "h" that disallows r16-r31
> +  and replace only r, exclude Br and Yr.  */
> +  for (unsigned i = 0; i < constraints.length (); i++)
> + {
> +   std::string *s = new std::string (constraints[i]);

Doesn't this leak memory (all the time)?
I must say I don't really understand why you need to use std::string here,
but certainly it shouldn't leak.

> +   size_t pos = s->find ('r');
> +   while (pos != std::string::npos)
> + {
> +   if (pos > 0
> +   && (s->at (pos - 1) == 'Y' || s->at (pos - 1) == 'B'))
> + pos = s->find ('r', pos + 1);
> +   else
> + {
> +   s->replace (pos, 1, "h");
> +   constraints[i] = (const char*) s->c_str ();

Formatting (space before *).  The usual way for constraints is ggc_strdup on
some string in a buffer.  Also, one could have several copies or r (or m, 
memory (doesn't
that appear just in clobbers?  And that doesn't look like something that
should be replaced), Bm, e.g. in various alternatives.  So, you
need to change them all, not just the first hit.  "r,r,r,m" and the like.
Normally, one would simply walk the constraint string, parsing the special
letters (+, =, & etc.) and single letter constraints and 2 letter
constraints using CONSTRAINT_LEN macro (tons of examples in GCC sources).
Either do it in 2 passes, first one counts how long constraint string one
will need after the adjustments (and whether to adjust something at all),
then if needed XALLOCAVEC it and adjust in there, or say use a
auto_vec for
it.

> +   break;
> + }
> + }
> + }
> +  /* Also map "m/memory/Bm" constraint that may use GPR32, replace them 
> with
> +  "Bt/Bt/BT".  */
> +  for (unsigned i = 0; i < constraints.length (); i++)
> + {
> +   std::string *s = new std::string (constraints[i]);
> +   size_t pos = s->find ("m");
> +   size_t pos2 = s->find ("memory");
> +   if (pos != std::string::npos)
> + {
> +   if (pos > 0 && (s->at (pos - 1) == 'B'))
> +   s->replace (pos - 1, 2, "BT");
> +   else if (pos2 != std::string::npos)
> +   s->replace (pos, 6, "Bt");
> +   else
> +   s->replace (pos, 1, "Bt");

Formatting, the s->replace calls are indented too much.

Jakub



Re: [PATCH 1/2] c++: Initial support for P0847R7 (Deducing This) [PR102609]

2023-08-31 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 31, 2023 at 06:02:36AM +, waffl3x via Gcc-patches wrote:

> From e485a79ec5656e72ba46053618843c3d69331eab Mon Sep 17 00:00:00 2001
> From: Waffl3x 
> Date: Thu, 31 Aug 2023 01:05:25 -0400
> Subject: [PATCH] P0847R7 (deducing this) Initial support
> 
> Most things should be functional, lambdas need a little more work though.
> Limitations: Missing support for lambdas, and user defined conversion 
> functions when passing the implicit object argument does not work properly. 
> See explicit-object-param-valid4.C for an example of the current (errent) 
> behavior.
> 
> There is a slight mistake in call.cc, it should be benign.

Thanks for working on this.

Just some random mostly formatting comments, defering the actual patch
review to Jason.

The ChangeLog should refer to
PR c++/102609

and ideally mention somewhere that it implements
C++23 P0847R7 - Deducing this.
so that when one quickly searches when that was implemented it can be found
easily.
ChangeLog entries should start with capital letter after ): and
end with .  And they should fit into 80 columns, one can wrap lines (but use
tab indentation even on the subsequent lines).
More importantly, should describe what changed and not why, if the why needs
explanation, it should go into comments in the code.

> gcc/cp/ChangeLog:
> 
>   * call.cc (add_function_candidate): (Hopefully) benign mistake

So, this both misses . at the end and doesn't describe what changed.
* call.cc (add_function_candidate): Don't call build_this_conversion
for DECL_IS_XOBJ_MEMBER_FUNC.
?

>   (add_candidates): Treat explicit object member functions as member 
> functions when considering candidates

Too long line and missing . at the end

>   (build_over_call): Enable passing an implicit object argument when 
> calling an explicit object member function
>   * cp-tree.h (struct lang_decl_base): Added member xobj_flag for 
> differentiating explicit object member functions from static member functions

Just mention that xobj_flag member has been added, not what it is for.

>   (DECL_FUNC_XOBJ_FLAG): New, checked access for xobj_flag
>   (DECL_PARM_XOBJ_FLAG): New, access decl_flag_3
>   (DECL_IS_XOBJ_MEMBER_FUNC): New, safely check if a node is an explicit 
> object member function

These are macros, just say Define.
etc.

>   (enum cp_decl_spec): Support parsing 'this' as a decl spec, change is 
> mirrored in parser.cc:set_and_check_decl_spec_loc
>   * decl.cc (grokfndecl): Sets the xobj flag for the FUNCTION_DECL if the 
> first parameter is an explicit object parameter
>   (grokdeclarator): Sets the xobj flag for PARM_DECL if 'this' spec is 
> present in declspecs, bypasses conversion from FUNCTION_DECL to METHOD_DECL 
> if an xobj flag is set for the first parameter of the given function 
> declarator
>   * parser.cc (cp_parser_decl_specifier_seq): check for 'this' specifier
>   (set_and_check_decl_spec_loc): extended decl_spec_names to support 
> 'this', change is mirrored in cp-tree.h:cp_decl_spec
> 
> gcc/ChangeLog:
> 
>   * tree-core.h (struct tree_decl_common): Added comment describing new 
> use of decl_flag_3
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/cpp23/explicit-object-param-valid1.C: New test.
>   * g++.dg/cpp23/explicit-object-param-valid2.C: New test.
>   * g++.dg/cpp23/explicit-object-param-valid3.C: New test.
>   * g++.dg/cpp23/explicit-object-param-valid4.C: New test.

I think usually we don't differentiate in testcase names whether
the test is to be accepted or rejected.
So, one would just go with explicit-object-param{1,2,3,4,5,6}.C etc.
for everything related to the feature.
Isn't explicit-object-param too long though?
explicit-this or deducing-this might be shorter...

> +   /* FIXME: This doesn't seem to be neccesary, upon review I
> +  realized that it doesn't make sense (an xobj member func
> +  is not a nonstatic_member_function, so this check will
> +  never change anything) */

Comments should end with a dot and two spaces before */

> @@ -9995,7 +10001,8 @@ build_over_call (struct z_candidate *cand, int flags, 
> tsubst_flags_t complain)
>   }
>  }
>/* Bypass access control for 'this' parameter.  */
> -  else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
> +  else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
> +|| DECL_IS_XOBJ_MEMBER_FUNC (fn) )

No space between fn) and )

> +/* these need to moved to somewhere appropriate */

Comments should start with a capital letter and like above, end with
appropriate.  */

> +   && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (NODE))->u.base.xobj_flag == 1) \

No \ after the last line of the macro.

> +}
> \ No newline at end of file

Please avoid these (unless testing preprocessor etc. that
it can handle even sources which don't end with a newline).

> diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-object-param-valid2.C 
> 

[RFC PATCH] c++: Diagnose [basic.scope.block]/2 violations even for block externs [PR52953]

2023-08-31 Thread Jakub Jelinek via Gcc-patches
Hi!

C++17 had in [basic.block.scope]/2
"A parameter name shall not be redeclared in the outermost block of the function
definition nor in the outermost block of any handler associated with a
function-try-block."
and in [basic.block.scope]/4 similar rule for selection/iteration
statements.  My reading of that is that it applied even for block local
externs in all those spots, while they declare something at namespace scope,
the redeclaration happens in that outermost block etc. and introduces names
into that.
Those wordings seemed to have been moved somewhere else in C++20, but what's
worse, they were moved back and completely rewritten in
P1787R6: Declarations and where to find them
which has been applied as a DR (but admittedly, we don't claim yet to
implement that).
The current wording at https://eel.is/c++draft/basic.scope#block-2
and https://eel.is/c++draft/basic.scope#scope-2.10 seem to imply at least
to me that it doesn't apply to extern block local decls because their
target scope is the namespace scope and [basic.scope.block]/2 says
"and whose target scope is the block scope"...
Now, it is unclear if that is actually the intent or not.

There seems to be quite large implementation divergence on this as well.

Unpatched g++ e.g. on the redeclaration-5.C testcase diagnoses just
lines 55,58,67,70 (i.e. where the previous declaration is in for's
condition).

clang++ trunk diagnoses just lines 8 and 27, i.e. redeclaration in the
function body vs. parameter both in normal fn and lambda (but not e.g.
function-try-block and others, including ctors, but it diagnoses those
for non-extern decls).

ICC 19 diagnoses lines 8,32,38,41,45,52,55,58,61,64,67,70,76.

And MSCV trunk diagnoses 8,27,32,38,41,45,48,52,55,58,67,70,76,87,100,137
although the last 4 are just warnings.

g++ with the patch diagnoses
8,15,27,32,38,41,45,48,52,55,58,61,64,67,70,76,87,100,121,137
as the dg-error directives test.

So, I'm not really sure what to do.  Intuitively the patch seems right
because even block externs redeclare stuff and change meaning of the
identifiers and void foo () { int i; extern int i (int); } is rejected
by all compilers.

2023-08-31  Jakub Jelinek  

PR c++/52953
* name-lookup.cc (check_local_shadow): Defer punting on
DECL_EXTERNAL (decl) from the start of function to right before
the -Wshadow* checks.

* g++.dg/diagnostic/redeclaration-4.C: New test.
* g++.dg/diagnostic/redeclaration-5.C: New test.

--- gcc/cp/name-lookup.cc.jj2023-08-30 20:07:18.584830291 +0200
+++ gcc/cp/name-lookup.cc   2023-08-30 20:01:05.796967755 +0200
@@ -3096,10 +3096,6 @@ check_local_shadow (tree decl)
   if (TREE_CODE (decl) == PARM_DECL && !DECL_CONTEXT (decl))
 return;
 
-  /* External decls are something else.  */
-  if (DECL_EXTERNAL (decl))
-return;
-
   tree old = NULL_TREE;
   cp_binding_level *old_scope = NULL;
   if (cxx_binding *binding = outer_binding (DECL_NAME (decl), NULL, true))
@@ -3219,6 +3215,9 @@ check_local_shadow (tree decl)
  return;
}
 
+  if (DECL_EXTERNAL (decl))
+   return;
+
   /* If '-Wshadow=compatible-local' is specified without other
 -Wshadow= flags, we will warn only when the type of the
 shadowing variable (DECL) can be converted to that of the
@@ -3274,6 +3273,9 @@ check_local_shadow (tree decl)
   return;
 }
 
+  if (DECL_EXTERNAL (decl))
+return;
+
   if (!warn_shadow)
 return;
 
--- gcc/testsuite/g++.dg/diagnostic/redeclaration-4.C.jj2023-08-30 
20:01:37.013537549 +0200
+++ gcc/testsuite/g++.dg/diagnostic/redeclaration-4.C   2023-08-30 
20:12:03.763900190 +0200
@@ -0,0 +1,167 @@
+// PR c++/52953
+// { dg-do compile }
+// { dg-options "-pedantic-errors -Wno-switch-unreachable" }
+
+void
+foo (int x)// { dg-message "'int x' previously 
declared here" }
+{
+  extern int x;// { dg-error "declaration of 
'int x' shadows a parameter" }
+}
+
+void
+bar (int x)// { dg-message "'int x' previously 
declared here" }
+try
+{
+  extern int x;// { dg-error "declaration of 
'int x' shadows a parameter" }
+}
+catch (...)
+{
+}
+
+volatile int v;
+
+void
+baz ()
+{
+#if __cplusplus >= 201103L
+  auto f = [] (int x) { extern int x; };// { dg-error "declaration of 'int x' 
shadows a parameter" "" { target c++11 } }
+   // { dg-message "'int x' previously 
declared here" "" { target c++11 } .-1 }
+#endif
+  if (int x = 1)   // { dg-message "'int x' previously 
declared here" }
+{
+  extern int x;// { dg-error "redeclaration of 'int 
x'" }
+}
+  if (int x = 0)   // { dg-message "'int x' previously 
declared here" }
+;
+  else
+{
+  extern int x;// { dg-error "redeclaration of 'int 
x'" }
+}
+  if (int x = 1) 

[PATCH] c++: Diagnose [basic.scope.block]/2 violations even in compound-stmt of function-try-block [PR52953]

2023-08-31 Thread Jakub Jelinek via Gcc-patches
Hi!

As the following testcase shows, while check_local_shadow diagnoses most of
the [basic.scope.block]/2 violations, it doesn't diagnose when parameter's
name is redeclared inside of the compound-stmt of a function-try-block.

There is in that case an extra scope (sk_try with parent artificial
sk_block with for FUNCTION_NEEDS_BODY_BLOCK another sk_block and only then
sk_function_param).

The following patch fixes that.

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

2023-08-31  Jakub Jelinek  

PR c++/52953
* cp-tree.h (struct language_function): Add x_in_function_try_block
member.
* semantics.cc (begin_function_try_block): Set it.
(finish_function_try_block): Clear it.
* name-lookup.cc (check_local_shadow): If in_function_try_block
and current_binding_level->kind == sk_try, skip another level.

* g++.dg/diagnostic/redeclaration-3.C: New test.

--- gcc/cp/cp-tree.h.jj 2023-08-30 10:42:53.579169729 +0200
+++ gcc/cp/cp-tree.h2023-08-30 19:28:20.712246064 +0200
@@ -2110,6 +2110,7 @@ struct GTY(()) language_function {
   BOOL_BITFIELD returns_null : 1;
   BOOL_BITFIELD returns_abnormally : 1;
   BOOL_BITFIELD infinite_loop: 1;
+  BOOL_BITFIELD in_function_try_block : 1;
   BOOL_BITFIELD x_in_function_try_handler : 1;
   BOOL_BITFIELD x_in_base_initializer : 1;
 
--- gcc/cp/semantics.cc.jj  2023-08-28 10:33:11.064187885 +0200
+++ gcc/cp/semantics.cc 2023-08-30 19:28:44.295897427 +0200
@@ -1626,6 +1626,7 @@ begin_function_try_block (tree *compound
   *compound_stmt = begin_compound_stmt (0);
   r = begin_try_block ();
   FN_TRY_BLOCK_P (r) = 1;
+  cp_function_chain->in_function_try_block = 1;
   return r;
 }
 
@@ -1662,6 +1663,7 @@ finish_cleanup (tree cleanup, tree try_b
 void
 finish_function_try_block (tree try_block)
 {
+  cp_function_chain->in_function_try_block = 0;
   finish_try_block (try_block);
   /* FIXME : something queer about CTOR_INITIALIZER somehow following
  the try block, but moving it inside.  */
--- gcc/cp/name-lookup.cc.jj2023-08-24 15:36:59.272791101 +0200
+++ gcc/cp/name-lookup.cc   2023-08-30 19:40:09.396172794 +0200
@@ -3146,6 +3146,11 @@ check_local_shadow (tree decl)
 them there.  */
  cp_binding_level *b = current_binding_level->level_chain;
 
+ if (current_binding_level->kind == sk_try
+ && cp_function_chain->in_function_try_block)
+   /* Skip the function-try-block level.  */
+   b = b->level_chain;
+
  if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
/* Skip the ctor/dtor cleanup level.  */
b = b->level_chain;
--- gcc/testsuite/g++.dg/diagnostic/redeclaration-3.C.jj2023-08-30 
18:51:42.252179367 +0200
+++ gcc/testsuite/g++.dg/diagnostic/redeclaration-3.C   2023-08-30 
19:44:06.314933892 +0200
@@ -0,0 +1,204 @@
+// PR c++/52953
+// { dg-do compile }
+// { dg-options "-pedantic-errors -Wno-switch-unreachable" }
+
+void
+foo (int x)// { dg-message "'int x' previously 
declared here" }
+{
+  int x;   // { dg-error "declaration of 'int x' 
shadows a parameter" }
+}
+
+void
+bar (int x)// { dg-message "'int x' previously 
declared here" }
+try
+{
+  int x;   // { dg-error "declaration of 'int x' 
shadows a parameter" }
+}
+catch (...)
+{
+}
+
+volatile int v;
+
+void
+baz ()
+{
+#if __cplusplus >= 201103L
+  auto f = [] (int x) { int x; };  // { dg-error "declaration of 'int x' 
shadows a parameter" "" { target c++11 } }
+   // { dg-message "'int x' previously 
declared here" "" { target c++11 } .-1 }
+#endif
+  if (int x = 1)   // { dg-message "'int x' previously 
declared here" }
+{
+  int x;   // { dg-error "redeclaration of 'int 
x'" }
+}
+  if (int x = 0)   // { dg-message "'int x' previously 
declared here" }
+;
+  else
+{
+  int x;   // { dg-error "redeclaration of 'int 
x'" }
+}
+  if (int x = 1)   // { dg-message "'int x' previously 
declared here" }
+int x; // { dg-error "redeclaration of 'int 
x'" }
+  if (int x = 0)   // { dg-message "'int x' previously 
declared here" }
+;
+  else
+int x; // { dg-error "redeclaration of 'int 
x'" }
+  switch (int x = 1)   // { dg-message "'int x' previously 
declared here" }
+{
+  int x;   // { dg-error "redeclaration of 'int 
x'" }
+default:;
+}
+  switch (int x = 1)   // { dg-message "'int x' previously 
declared here" }
+int x; // { dg-error "redeclaration of 'int 
x'" }
+  while (int x = v)// { dg-message "'int x' previously 
declared 

Re: [PATCH] tree-optimization/111228 - combine two VEC_PERM_EXPRs

2023-08-30 Thread Jakub Jelinek via Gcc-patches
On Wed, Aug 30, 2023 at 01:54:46PM +0200, Richard Biener via Gcc-patches wrote:
>   * gcc.dg/tree-ssa/forwprop-42.c: New testcase.

> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-42.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-cddce1" } */
> +
> +typedef unsigned long v2di __attribute__((vector_size(16)));

Shouldn't this be unsigned long long ?  Otherwise it is actually V4SImode
rather than V2DImode.

> +
> +v2di g;
> +void test (v2di *v)
> +{
> +  v2di lo = v[0];
> +  v2di hi = v[1];
> +  v2di res;
> +  res[1] = hi[1];
> +  res[0] = lo[0];
> +  g = res;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR <\[^>\]*, { 0, 3 }>" 1 
> "cddce1" } } */
> -- 
> 2.35.3

Jakub



Re: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic

2023-08-30 Thread Jakub Jelinek via Gcc-patches
On Wed, Aug 30, 2023 at 12:47:42PM +0200, Tobias Burnus wrote:
> > For switches, there is the case of the switch jumping across declaration
> > of an automatic var which is not initialized/constructed (I think in that
> > case there is normally no warning/error and happens a lot in the wild
> > including GCC sources) but perhaps one could treat those cases with
> > #pragma omp allocate as if they are actually constructed (though, I'd still
> > raise it at OpenMP F2F),
> Can you open an OpenMP spec issue?

https://github.com/OpenMP/spec/issues/3676

Feel freeo to amend it.

Jakub



Re: RFC: Introduce -fhardened to enable security-related flags

2023-08-30 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 29, 2023 at 03:42:27PM -0400, Marek Polacek via Gcc-patches wrote:
> +   if (UNLIKELY (flag_hardened)
> +   && (opt->code == OPT_D || opt->code == OPT_U))
> + {
> +   if (!fortify_seen_p)
> + fortify_seen_p = !strncmp (opt->arg, "_FORTIFY_SOURCE", 15);

Perhaps this should check that the char after it is either '\0' or '=', we
shouldn't care if user defines or undefines _FORTIFY_SOURCE_WHATEVER macro.

> +   if (!cxx_assert_seen_p)
> + cxx_assert_seen_p = !strcmp (opt->arg, "_GLIBCXX_ASSERTIONS");

Like we don't care in this case about -D_GLIBCXX_ASSERTIONS42

> + }
> + }
> +
> +  if (flag_hardened)
> + {
> +   if (!fortify_seen_p && optimize > 0)
> + {
> +   if (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 35)
> + cpp_define (parse_in, "_FORTIFY_SOURCE=3");
> +   else
> + cpp_define (parse_in, "_FORTIFY_SOURCE=2");

I wonder if it wouldn't be better to enable _FORTIFY_SOURCE=2 by default for
-fhardened only for targets which actually have such a support in the C
library.  There is some poor man's _FORTIFY_SOURCE support in libssp,
but e.g. one has to link with -lssp in that case and compile with
-isystem `gcc -print-include-filename=include`/ssp .
For glibc that is >= 2.3.4, https://maskray.me/blog/2022-11-06-fortify-source
mentions NetBSD support since 2006, newlib since 2017, some Darwin libc,
bionic (but seems they have only some clang support and dropped GCC
support) and some third party reimplementation of libssp.
Or do we just enable it and hope that either it works well or isn't
supported at all quietly?  E.g. it would certainly break the ssp case
where -isystem finds ssp headers but -lssp isn't linked in.

> @@ -4976,6 +4993,22 @@ process_command (unsigned int decoded_options_count,
>  #endif
>  }
>  
> +  /* TODO: check if -static -pie works and maybe use it.  */
> +  if (flag_hardened && !any_link_options_p && !static_p)
> +{
> +  save_switch ("-pie", 0, NULL, /*validated=*/true, /*known=*/false);
> +  /* TODO: check if BIND_NOW/RELRO is supported.  */
> +  if (true)
> + {
> +   /* These are passed straight down to collect2 so we have to break
> +  it up like this.  */
> +   add_infile ("-z", "*");
> +   add_infile ("now", "*");
> +   add_infile ("-z", "*");
> +   add_infile ("relro", "*");

As the TODO comment says, to do that we need to check at configure time that
linker supports -z now and -z relro options.

> @@ -1117,9 +1121,12 @@ finish_options (struct gcc_options *opts, struct 
> gcc_options *opts_set,
>  }
>  
>/* We initialize opts->x_flag_stack_protect to -1 so that targets
> - can set a default value.  */
> + can set a default value.  With --enable-default-ssp or -fhardened
> + the default is -fstack-protector-strong.  */
>if (opts->x_flag_stack_protect == -1)
> -opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
> +opts->x_flag_stack_protect = (opts->x_flag_hardened
> +   ? SPCT_FLAG_STRONG
> +   : DEFAULT_FLAG_SSP);

This needs to be careful, -fstack-protector isn't supported on all targets
(e.g. ia64) and we don't want toplev.cc warning:
  /* Targets must be able to place spill slots at lower addresses.  If the
 target already uses a soft frame pointer, the transition is trivial.  */
  if (!FRAME_GROWS_DOWNWARD && flag_stack_protect)
{
  warning_at (UNKNOWN_LOCATION, 0,
  "%<-fstack-protector%> not supported for this target");
  flag_stack_protect = 0;
}
to be emitted whenever using -fhardened, it should not be enabled there
silently (for ia64 Fedora/RHEL gcc actually had a short patch to make it
work, turn the target into FRAME_GROWS_DOWNWARD one if -fstack-protect* was
enabled and otherwise keep it !FRAME_GROWS_DOWNWARD).

Jakub



[PATCH] tree-ssa-strlen: Fix up handling of conditionally zero memcpy [PR110914]

2023-08-30 Thread Jakub Jelinek via Gcc-patches
Hi!

The following testcase is miscompiled since r279392 aka 
r10-5451-gef29b12cfbb4979
The strlen pass has adjust_last_stmt function, which performs mainly strcat
or strcat-like optimizations (say strcpy (x, "abcd"); strcat (x, p);
or equivalent memcpy (x, "abcd", strlen ("abcd") + 1); char *q = strchr (x, 0);
memcpy (x, p, strlen (p)); etc. where the first stmt stores '\0' character
at the end but next immediately overwrites it and so the first memcpy can be
adjusted to store 1 fewer bytes.  handle_builtin_memcpy called this function
in two spots, the first one guarded like:
  if (olddsi != NULL
  && tree_fits_uhwi_p (len)
  && !integer_zerop (len))
adjust_last_stmt (olddsi, stmt, false);
i.e. only for constant non-zero length.  The other spot can call it even
for non-constant length but in that case we punt before that if that length
isn't length of some string + 1, so again non-zero.
The r279392 change I assume wanted to add some warning stuff and changed it
like
   if (olddsi != NULL
-  && tree_fits_uhwi_p (len)
   && !integer_zerop (len))
-adjust_last_stmt (olddsi, stmt, false);
+{
+  maybe_warn_overflow (stmt, len, rvals, olddsi, false, true);
+  adjust_last_stmt (olddsi, stmt, false);
+}
While maybe_warn_overflow possibly handles non-constant length fine,
adjust_last_stmt really relies on length to be non-zero, which
!integer_zerop (len) alone doesn't guarantee.  While we could for
len being SSA_NAME ask the ranger or tree_expr_nonzero_p, I think
adjust_last_stmt will not benefit from it much, so the following patch
just restores the above condition/previous behavior for the adjust_last_stmt
call only.

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

2023-08-30  Jakub Jelinek  

PR tree-optimization/110914
* tree-ssa-strlen.cc (strlen_pass::handle_builtin_memcpy): Don't call
adjust_last_stmt unless len is known constant.

* gcc.c-torture/execute/pr110914.c: New test.

--- gcc/tree-ssa-strlen.cc.jj   2023-04-27 10:17:46.406486796 +0200
+++ gcc/tree-ssa-strlen.cc  2023-08-29 18:13:38.189327203 +0200
@@ -3340,7 +3340,8 @@ strlen_pass::handle_builtin_memcpy (buil
   && !integer_zerop (len))
 {
   maybe_warn_overflow (stmt, false, len, olddsi, false, true);
-  adjust_last_stmt (olddsi, stmt, false);
+  if (tree_fits_uhwi_p (len))
+   adjust_last_stmt (olddsi, stmt, false);
 }
 
   int idx = get_stridx (src, stmt);
--- gcc/testsuite/gcc.c-torture/execute/pr110914.c.jj   2023-08-29 
18:38:33.305699206 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr110914.c  2023-08-29 
18:38:18.678901007 +0200
@@ -0,0 +1,22 @@
+/* PR tree-optimization/110914 */
+
+__attribute__ ((noipa)) int
+foo (const char *s, unsigned long l)
+{
+  unsigned char r = 0;
+  __builtin_memcpy (, s, l != 0);
+  return r;
+}
+
+int
+main ()
+{
+  const char *p = "123456";
+  int a = foo (p, __builtin_strlen (p) - 5);
+  int b = foo (p, __builtin_strlen (p) - 6);
+  if (a != '1')
+__builtin_abort ();
+  if (b != 0)
+__builtin_abort ();
+  return 0;
+}

Jakub



[PATCH] store-merging: Fix up >= 64 bit insertion [PR111015]

2023-08-30 Thread Jakub Jelinek via Gcc-patches
Hi!

The following testcase shows that we mishandle bit insertion for
info->bitsize >= 64.  The problem is in using unsigned HOST_WIDE_INT
shift + subtraction + build_int_cst to compute mask, the shift invokes
UB at compile time for info->bitsize 64 and larger and e.g. on the testcase
with info->bitsize happens to compute mask of 0x3f rather than
0x3f''.

The patch fixes that by using wide_int wi::mask + wide_int_to_tree, so it
handles masks in any precision (up to WIDE_INT_MAX_PRECISION ;) ).

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

2023-08-30  Jakub Jelinek  

PR tree-optimization/111015
* gimple-ssa-store-merging.cc
(imm_store_chain_info::output_merged_store): Use wi::mask and
wide_int_to_tree instead of unsigned HOST_WIDE_INT shift and
build_int_cst to build BIT_AND_EXPR mask.

* gcc.dg/pr111015.c: New test.

--- gcc/gimple-ssa-store-merging.cc.jj  2023-07-11 13:40:39.049448058 +0200
+++ gcc/gimple-ssa-store-merging.cc 2023-08-29 16:13:12.808434272 +0200
@@ -4687,12 +4687,13 @@ imm_store_chain_info::output_merged_stor
}
  else if ((BYTES_BIG_ENDIAN ? start_gap : end_gap) > 0)
{
- const unsigned HOST_WIDE_INT imask
-   = (HOST_WIDE_INT_1U << info->bitsize) - 1;
+ wide_int imask
+   = wi::mask (info->bitsize, false,
+   TYPE_PRECISION (TREE_TYPE (tem)));
  tem = gimple_build (, loc,
  BIT_AND_EXPR, TREE_TYPE (tem), tem,
- build_int_cst (TREE_TYPE (tem),
-imask));
+ wide_int_to_tree (TREE_TYPE (tem),
+   imask));
}
  const HOST_WIDE_INT shift
= (BYTES_BIG_ENDIAN ? end_gap : start_gap);
--- gcc/testsuite/gcc.dg/pr111015.c.jj  2023-08-29 16:06:38.526938204 +0200
+++ gcc/testsuite/gcc.dg/pr111015.c 2023-08-29 16:19:03.702536015 +0200
@@ -0,0 +1,28 @@
+/* PR tree-optimization/111015 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O2" } */
+
+struct S { unsigned a : 4, b : 4; unsigned __int128 c : 70; } d;
+
+__attribute__((noipa)) void
+foo (unsigned __int128 x, unsigned char y, unsigned char z)
+{
+  d.a = y;
+  d.b = z;
+  d.c = x;
+}
+
+int
+main ()
+{
+  foo (-1, 12, 5);
+  if (d.a != 12
+  || d.b != 5
+  || d.c != (-1ULL | (((unsigned __int128) 0x3f) << 64)))
+__builtin_abort ();
+  foo (0x123456789abcdef0ULL | (((unsigned __int128) 26) << 64), 7, 11);
+  if (d.a != 7
+  || d.b != 11
+  || d.c != (0x123456789abcdef0ULL | (((unsigned __int128) 26) << 64)))
+__builtin_abort ();
+}

Jakub



Re: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic

2023-08-29 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 29, 2023 at 06:56:40PM +0200, Tobias Burnus wrote:
> On 29.08.23 18:28, Jakub Jelinek wrote:
> > One thing is that for C++ one needs to be careful about vars optimized
> > by NRV by the FE.
> Thanks for the warning.
> > And, just from the gimplify_bind_expr function name,
> 
> (I forgot that one change in there which makes it look larger is that
> I moved the stack handling below the variable cleaning as it makes sense
> to GOMP_free before instead of after wiping the stack via 
> __builtin_stack_restore.)
> 
> > I'm guessing you are adding the allocations at the start of surrounding 
> > BIND_EXPR, is that where
> > we generally want to allocate them?
> 
> I actually started with this in a FE implementation, but that
> does not work in general. I need to put the GOMP_alloc right
> before the associated DECL_EXPR, otherwise, it will break for
> code like:
> 
>   omp_allocator_handle_t my_allocator = omp_low_lat_mem_alloc;
>   int n = 5;
>   pragma omp allocate(n) allocator(my_allocator)

What about
  int n = 5;
  omp_allocator_handle_t my_allocator = omp_low_lat_mem_alloc;
  #pragma omp allocate(n) allocator(my_allocator)
?  What we do in that case?  Is that invalid because my_allocator
isn't in scope when n is defined?

> For your example, I get (the full gimple dump is below):
> 
> foo.c:7:11: warning: statement will never be executed [-Wswitch-unreachable]
> 7 |   int j;
> 
> I wonder whether we should just error out as GCC does when using a VLA
> at that place:
> 
>   error: switch jumps into scope of identifier with variably modified type
> 
> (with a similar but modified msg wording.) In a sense, the 'allocate' is very
> similar to VLA such that we should be able to piggyback on the VLA diagnostic.

Well, in this case the warning is there just because the patch chose to put
it at the start of the BIND_EXPR rather than right before DECL_EXPR.

For switches, there is the case of the switch jumping across declaration
of an automatic var which is not initialized/constructed (I think in that
case there is normally no warning/error and happens a lot in the wild
including GCC sources) but perhaps one could treat those cases with
#pragma omp allocate as if they are actually constructed (though, I'd still
raise it at OpenMP F2F), and another case with switch which doesn't even do
that.
Consider
  switch (i)
{
case 42:
  bar ();
  break;
case 51:
  int j = 5;
  use ();
  break;
}
This is valid for both C and C++, one doesn't jump across any initialization
in there.  Yet if the j allocation is done at the start of the BIND_EXPR, it
will jump across that initialization.
So, to me this feels like we should treat for the crossing initialization
stuff vars mentioned in allocate directive as having a non-trivial
constructor.
If you add default: break; before } above, C++ will reject it with an error,
but C will accept it, it is up to the user to initialize the var again in C
or not use it.

And, as I said earlier, this isn't just about switch, but user gotos as
well.

Jakub



Re: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic

2023-08-29 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 29, 2023 at 06:12:58PM +0200, Tobias Burnus wrote:
> This adds support for
>   #pragma omp allocate(var-list) [allocator(..) align(..)]
> 
> While the spec permits stack and static variables, this patch only
> adds support for stack variables - keeping the 'sorry' for static
> variables.
> It is also only C as I wanted to get this out before updating C++
> parsing. However, if disable the 'sorry' + add the attribute, it
> will also work for C++.
> 
> For Fortran, there is no expression associated with the declaration
> such that it will not work with the gimplify.cc patch (it cannot
> find the place to add it); however, I have a mostly working version
> for FE generated support for stack _and_ static variables.
> 
> The main RFC question for this patch is whether to generate the
> GOMP_alloc/free calls also for !TREE_USED() or not. This patch avoids
> this to aid removal of such stack variables, but one could also argue
> otherwise.
> 
> Thoughts, comments, remarks?

Don't have time to look through it in detail right now, so just
2 quick comments.

One thing is that for C++ one needs to be careful about vars optimized
by NRV by the FE.  Dunno if we can simply disregard vars mentioned
in allocate directive from FE NRV, or whether we instead should ignore
the allocate directive, or sorry, etc.  Because NRV optimized vars
are turned into RESULT_DECL and live usually in the caller's stack frame
rather than current function, so they can't be heap allocated...

And, just from the gimplify_bind_expr function name, I'm guessing you are
adding the allocations at the start of surrounding BIND_EXPR, is that where
we generally want to allocate them?
Other option is on DECL_EXPR, e.g. for C++ right before they are
constructed, or for C initialized if they have initializer.  Though, that
can have a drawback, one can e.g. in C (and I think in C++ too as long as
the vars don't need any kind of construction) jump across that
initialization and one would then bypass this allocation.  Though, what
happens with say
void
foo (int i)
{
  switch (i)
{
  int j;
  #pragma omp allocate (j) ...
case 42:
  j = 5;
  use ();
  break;
default:
  j = 24;
  use ();
  break;
}
}
Where will j be allocated and where will j be deallocated with your patch?
If it is try/finally, then perhaps break; as jump out of the BIND_EXPR will
destruct it fine, but I have no idea how it would work when jumping into the
switch (or goto into middle of some compound statement etc.).

Jakub



Re: RFC: Top level configure: Require a minimum version 6.8 texinfo

2023-08-29 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 29, 2023 at 04:21:44PM +0100, Nick Clifton via Gcc-patches wrote:
>   Currently the top level configure.ac file sets the minimum required
>   version of texinfo to be 4.7.  I would like to propose changing this
>   to 6.8.
>   
>   The reason for the change is that the bfd documentation now needs at
>   least version 6.8 in order to build[1][2].  Given that 4.7 is now
>   almost 20 years old (it was released in April 2004), updating the
>   requirement to a newer version does seem reasonable.  On the other
>   hand 6.8 is quite new (it was released in March 2021), so a lot of
>   systems out there may not have it.
> 
>   Thoughts ?

I think that is too new.
We still allow building gcc e.g. with GCC 4.8 from ~ 10 years ago and
I think various boxes where people regularly build gcc will have similarly
old other tools.
So, bumping requirement from ~ 20 years old tools to ~ 10 years old tools
might be ok, but requiring ones at most 2 years old will be a nightmare,
especially if gcc itself doesn't have such a requirement.
Sure, we have requirements on newer gmp/mpfr/libmpc etc., but every extra
requirement means some extra work for lots of people.

So, either revert those bfd/*.texi changes, or make them somehow conditional
on the makeinfo version, or perhaps have this texinfo version requirement
only inside of bfd configure, or, if you really want to do it in toplevel
configure, make it dependent on whether bfd/ subdirectory is present (if
not, keep the old requirement, otherwise newer)?

> [1] https://sourceware.org/bugzilla/show_bug.cgi?id=30703
> [2] https://sourceware.org/pipermail/binutils/2023-February/125943.html
> 
> Suggested patch:
> 
> diff --git a/configure.ac b/configure.ac
> index 01cfd017273..10bfef1c6c5 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -3678,10 +3678,10 @@ case " $build_configdirs " in
>*" texinfo "*) MAKEINFO='$$r/$(BUILD_SUBDIR)/texinfo/makeinfo/makeinfo' ;;
>*)
>  changequote(,)
> -# For an installed makeinfo, we require it to be from texinfo 4.7 or
> +# For an installed makeinfo, we require it to be from texinfo 6.8 or
>  # higher, else we use the "missing" dummy.
>  if ${MAKEINFO} --version \
> -   | egrep 'texinfo[^0-9]*(4\.([7-9]|[1-9][0-9])|[5-9]|[1-9][0-9])' 
> >/dev/null 2>&1; then
> +   | egrep 'texinfo[^0-9]*(6\.([8-9]|[1-9][0-9])|[7-9]|[1-9][0-9])' 
> >/dev/null 2>&1; then
>:
>  else
>MAKEINFO="$MISSING makeinfo"

Jakub



Re: [RFC] > WIDE_INT_MAX_PREC support in wide-int

2023-08-29 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 29, 2023 at 11:42:48AM +0100, Richard Sandiford wrote:
> > I'll note tree-ssa-loop-niter.cc also uses GMP in some cases, widest_int
> > is really trying to be poor-mans GMP by limiting the maximum precision.
> 
> I'd characterise widest_int as "a wide_int that is big enough to hold
> all supported integer types, without losing sign information".  It's
> not big enough to do arbitrary arithmetic without losing precision
> (in the way that GMP is).
> 
> If the new limit on integer sizes is 65535 bits for all targets,
> then I think that means that widest_int needs to become a 65536-bit type.
> (But not with all bits represented all the time, of course.)

If the widest_int storage would be dependent on the len rather than
precision for how it is stored, then I think we'd need a new method which
would be called at the start of filling the limbs where we'd tell how many
limbs there would be (i.e. what will set_len be called with later on), and
do nothing for all storages but the new widest_int_storage.

> [ And at that point I think widest_int should ideally become a GMP wrapper.
>   The wide_int stuff isn't optimised for such large sizes, even accepting
>   that large sizes will be a worst case.  That might not be easy to do with
>   the current infrastructure though.  Especially not if widest_ints are
>   stored in GC-ed structures. ]

I strongly hope widest_ints aren't stored in GC-ed structures, we should
be using INTEGER_CSTs or RTXes in GC-ed structures, not wide_int/widest_int
IMNSHO.
nm cc1plus | grep gt_ggc.*widest_int
doesn't show anything,
nm cc1plus | grep gt_ggc.*wide_int
00b2c88d T _Z43gt_ggc_mx_hash_table_const_wide_int_hasher_Pv
00d00b3a T _Z44gt_ggc_mx_generic_wide_int_wide_int_storage_Pv
00d1c8bb W _Z9gt_ggc_mxI16wide_int_storageEvP16generic_wide_intIT_E
00b2eecb W 
_Z9gt_ggc_mxI21const_wide_int_hasherEvP10hash_tableIT_Lb0E11xcallocatorE
01596e00 T 
_Z9gt_ggc_mxP16generic_wide_intI22fixed_wide_int_storageILi576EEE
00d00b8e T _Z9gt_ggc_mxR16wide_int_storage
00b2c8e1 T _Z9gt_ggc_mxR21const_wide_int_hasher
>From those symbols, only the second has any undefined references to that
(in dwarf2out.o) plus gtype-desc.o defines them and has some references.

In dwarf2out it is dw_val_node's v.wide_int_ptr.  Already the (apparently
incomplete) wide_int patch would need to deal with that, either by making
those say fixed_wide_int_storage  or something
similar, so it would never store anything larger, or run the destructor
when actually freeing it (dunno if that is possible right now in GC).

> That seems like it would stand the biggest chance of preserving
> existing semantics.  But we might want to define new typedefs for
> narrower limits.  E.g. the current widest_int limit probably still
> makes sense for operations on scalar_int_modes.  (But then most
> RTL arithmetic should use wide_int rather than widest_int.)
> 
> Perhaps some widest_int uses are really restricted to address-like
> things and could instead use offset_int.  Until now there hasn't been
> much incentive to make the distinction.

Sure.

> And perhaps we could identify other similar cases where the limit is
> known (statically) to be the current limit, rather than 65536.
> 
> I think one of the worst things we could do is push the requirement
> up to users of the API to have one path for _BitInts and one for "normal"
> integers.  That's bound to lead to a whack-a-mole effect.

Yeah.
As for uses of GMP, I think actually most wide-int.{h,cc} operations aren't
that bad compared to GMP, it is most important to have a fast path for the
most common case and for something rare being say some small constant times
slower than GMP is acceptable (say because GMP will have some assembly
hand-written inner loop while wide-int doesn't).  Something different
is say multiplication/division, perhaps for those in the out of line
wide-int.cc helpers we could check for precision above certain boundary and
in that case convert to mpn, perform multiplication/division/modulo using
that and convert back, because the gmp algorithms for those are much better.

Jakub



Re: [RFC] > WIDE_INT_MAX_PREC support in wide-int

2023-08-29 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 29, 2023 at 09:49:59AM +, Richard Biener wrote:
> The simplest way would probably to keep widest_int at 
> WIDE_INT_MAX_PRECISION like we have now and assert that this is
> enough at ::to_widest time (we probably do already).  And then
> declare uses with more precision need to use GMP.
> 
> Not sure if that's not also a viable way for wide_int - we're
> only losing optimization here, no?

No.  In lots of places it is essential (constant evaluation), in other
places very much desirable optimization even or especially on _BitInt (e.g.
value range optimizations, ccp, ...) and then sure, spots where just punting
on larger _BitInt for optimization is something we can live with (and yet
other spots which only happen after the lowering and so will never see that
at all).

I think if we go with allowing _BitInt (N) for N >= WIDE_INT_MAX_PRECISION,
the most important thing is we want to slow down the compiler as little as
possible for the common case, no _BitInt at all or _BitInt smaller than that,
and furthermore from maintainance POV, we want most of the code to work as
is.  Adding assertion that precision is < WIDE_INT_MAX_PRECISION on
widest_int construction from wide_int/INTEGER_CST etc. wouldn't achieve
those goals.  Grepping outside of wide-int.{cc,h} for widest_int, I see
around 450 matches, sure, that doesn't mean 450 places where we'd need to
add some guard to punt for the larger _BitInt (if it is possible to punt at
all), but I'm sure it would be more than hundred of places.  And having
similarly say 50% of those 100-200 spots have a fallback using gmp would be
also a maintainance nightmare, because those spots for larger precisions
would be much less tested than normal code.  Sure, we can add some guards
in some places and the niter stuff could very well be one of them, or simply
also use there wide_int with carefully chosen precision, say
WIDE_INT_MAX_PRECISION if _BitInt isn't involved or at most 128 bits,
and otherwise something wider.  But I'm worried of the maintainance
nightmare etc. if we have to touch hundreds of places and figure out how to
punt or what else to do in each of those spots.

Compared to this, I see only 15 hits for widest2_int, in 2 places,
arith_overflowed_p and operator_mult::wi_fold, that is something that could
very well be done either always using appropriate wider precision wide_int,
or even do it twice, once for < WIDE_INT_MAX_PRECISION input precision and
another time wider.

Jakub



[PATCH] tree-ssa-math-opts: Improve uaddc/usubc pattern matching [PR111209]

2023-08-29 Thread Jakub Jelinek via Gcc-patches
Hi!

The uaddc/usubc usual matching is of the .{ADD,SUB}_OVERFLOW pair in the
middle, which adds/subtracts carry-in (from lower limbs) and computes
carry-out (to higher limbs).  Before optimizations (unless user writes
it intentionally that way already), all the steps look the same, but
optimizations simplify the handling of the least significant limb
(one which adds/subtracts 0 carry-in) to just a single
.{ADD,SUB}_OVERFLOW and the handling of the most significant limb
if the computed carry-out is ignored to normal addition/subtraction
of multiple operands.
Now, match_uaddc_usubc has code to turn that least significant
.{ADD,SUB}_OVERFLOW call into .U{ADD,SUB}C call with 0 carry-in if
a more significant limb above it is matched into .U{ADD,SUB}C; this
isn't necessary for functionality, as .ADD_OVERFLOW (x, y) is
functionally equal to .UADDC (x, y, 0) (provided the types of operands
are the same and result is complex type with that type element), and
it also has code to match the most significant limb with ignored carry-out
(in that case one pattern match turns both the penultimate limb pair of
.{ADD,SUB}_OVERFLOW into .U{ADD,SUB}C and the addition/subtraction
of the 4 values (2 carries) into another .U{ADD,SUB}C.

As the following patch shows, what we weren't handling is the case when
one uses either the __builtin_{add,sub}c builtins or hand written forms
thereof (either __builtin_*_overflow or even that written by hand) for
just 2 limbs, where the least significant has 0 carry-in and the most
significant ignores carry-out.  The following patch matches that, e.g.
  _16 = .ADD_OVERFLOW (_1, _2);
  _17 = REALPART_EXPR <_16>;
  _18 = IMAGPART_EXPR <_16>;
  _15 = _3 + _4;
  _12 = _15 + _18;
into
  _16 = .UADDC (_1, _2, 0);
  _17 = REALPART_EXPR <_16>;
  _18 = IMAGPART_EXPR <_16>;
  _19 = .UADDC (_3, _4, _18);
  _12 = IMAGPART_EXPR <_19>;
so that we can emit better code.

As the 2 later comments show, we must do that carefully, because the
pass walks the IL from first to last stmt in a bb and we must avoid
pattern matching this way something that should be matched on a later
instruction differently.

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

2023-08-29  Jakub Jelinek  

PR middle-end/79173
PR middle-end/111209
* tree-ssa-math-opts.cc (match_uaddc_usubc): Match also
just 2 limb uaddc/usubc with 0 carry-in on lower limb and ignored
carry-out on higher limb.  Don't match it though if it could be
matched later on 4 argument addition/subtraction.

* gcc.target/i386/pr79173-12.c: New test.

--- gcc/tree-ssa-math-opts.cc.jj2023-08-08 15:55:09.498122557 +0200
+++ gcc/tree-ssa-math-opts.cc   2023-08-28 20:51:31.893886862 +0200
@@ -4641,8 +4641,135 @@ match_uaddc_usubc (gimple_stmt_iterator
   __imag__ of something, verify it is .UADDC/.USUBC.  */
tree rhs1 = gimple_assign_rhs1 (im);
gimple *ovf = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs1, 0));
+   tree ovf_lhs = NULL_TREE;
+   tree ovf_arg1 = NULL_TREE, ovf_arg2 = NULL_TREE;
if (gimple_call_internal_p (ovf, code == PLUS_EXPR
-? IFN_UADDC : IFN_USUBC)
+? IFN_ADD_OVERFLOW
+: IFN_SUB_OVERFLOW))
+ {
+   /* Or verify it is .ADD_OVERFLOW/.SUB_OVERFLOW.
+  This is for the case of 2 chained .UADDC/.USUBC,
+  where the first one uses 0 carry-in and the second
+  one ignores the carry-out.
+  So, something like:
+  _16 = .ADD_OVERFLOW (_1, _2);
+  _17 = REALPART_EXPR <_16>;
+  _18 = IMAGPART_EXPR <_16>;
+  _15 = _3 + _4;
+  _12 = _15 + _18;
+  where the first 3 statements come from the lower
+  limb addition and the last 2 from the higher limb
+  which ignores carry-out.  */
+   ovf_lhs = gimple_call_lhs (ovf);
+   tree ovf_lhs_type = TREE_TYPE (TREE_TYPE (ovf_lhs));
+   ovf_arg1 = gimple_call_arg (ovf, 0);
+   ovf_arg2 = gimple_call_arg (ovf, 1);
+   /* In that case we need to punt if the types don't
+  mismatch.  */
+   if (!types_compatible_p (type, ovf_lhs_type)
+   || !types_compatible_p (type, TREE_TYPE (ovf_arg1))
+   || !types_compatible_p (type,
+   TREE_TYPE (ovf_arg2)))
+ ovf_lhs = NULL_TREE;
+   else
+

[RFC] > WIDE_INT_MAX_PREC support in wide-int

2023-08-28 Thread Jakub Jelinek via Gcc-patches
Hi!

While the _BitInt series isn't committed yet, I had a quick look at
lifting the current lowest limitation on maximum _BitInt precision,
that wide_int can only support wide_int until WIDE_INT_MAX_PRECISION - 1.

Note, other limits if that is lifted are INTEGER_CST currently using 3
unsigned char members and so being able to only hold up to 255 * 64 = 16320
bit numbers and then TYPE_PRECISION being 16-bit, so limiting us to 65535
bits.  The INTEGER_CST limit could be dealt with by dropping the
int_length.offset "cache" and making int_length.extended and
int_length.unextended members unsinged short rather than unsigned char.

The following so far just compile tested patch changes wide_int_storage
to be a union, for precisions up to WIDE_INT_MAX_PRECISION inclusive it
will work as before (just being no longer trivially copyable type and
having an inline destructor), while larger precision instead use a pointer
to heap allocated array.
For wide_int this is fairly easy (of course, I'd need to see what the
patch does to gcc code size and compile time performance, some
growth/slowdown is certain), but I'd like to brainstorm on
widest_int/widest2_int.

Currently it is a constant precision storage with WIDE_INT_MAX_PRECISION
precision (widest2_int twice that), so memory layout-wide on at least 64-bit
hosts identical to wide_int, just it doesn't have precision member and so
32 bits smaller on 32-bit hosts.  It is used in lots of places.

I think the most common is what is done e.g. in tree_int_cst* comparisons
and similarly, using wi::to_widest () to just compare INTEGER_CSTs.
That case actually doesn't even use wide_int but widest_extended_tree
as storage, unless stored into widest_int in between (that happens in
various spots as well).  For comparisons, it would be fine if
widest_int_storage/widest_extended_tree storages had a dynamic precision,
WIDE_INT_MAX_PRECISION for most of the cases (if only
precision < WIDE_INT_MAX_PRECISION is involved), otherwise the needed
precision (e.g. for binary ops) which would be what we say have in
INTEGER_CST or some type, rounded up to whole multiples of HOST_WIDE_INTs
and if unsigned with multiple of HOST_WIDE_INT precision, have another
HWI to make it always sign-extended.

Another common case is how e.g. tree-ssa-ccp.cc uses them, that is mostly
for bitwise ops and so I think the above would be just fine for that case.

Another case is how tree-ssa-loop-niter.cc uses it, I think for such a usage
it really wants something widest, perhaps we could just try to punt for
_BitInt(N) for N >= WIDE_INT_MAX_PRECISION in there, so that we never care
about bits beyond that limit?

Some passes only use widest_int after the bitint lowering spot, we don't
really need to care about those.

I think another possibility could be to make widest_int_storage etc. always
pretend it has 65536 bit precision or something similarly large and make the
decision on whether inline array or pointer is used in the storage be done
using len.  Unfortunately, set_len method is usually called after filling
the array, not before it (it even sign-extends some cases, so it has to be
done that late).

Or for e.g. binary ops compute widest_int precision based on the 2 (for
binary) or 1 (for unary) operand's .len involved?

Thoughts on this?

Note, the wide-int.cc change is just to show it does something, it would be
a waste to put that into self-test when _BitInt can support such sizes.

2023-08-28  Jakub Jelinek  

* wide-int.h (wide_int_storage): Replace val member with a union of
val and valp.  Declare destructor.
(wide_int_storage::wide_int_storage): Initialize precision to 0
in default ctor.  Allocate u.valp if needed in copy ctor.
(wide_int_storage::~wide_int_storage): New.
(wide_int_storage::operator =): Delete and/or allocate u.valp if
needed.
(wide_int_storage::get_val, wide_int_storage::write_val): Return
u.valp for precision > WIDE_INT_MAX_PRECISION, otherwise u.val.
(wide_int_storage::set_len): Use write_val instead of accessing
val directly.
(wide_int_storage::create): Allocate u.valp if needed.
* value-range.h (irange::maybe_resize): Use a loop instead of
memcpy.
* wide-int.cc (wide_int_cc_tests): Add a test for 4096 bit wide_int
addition.

--- gcc/wide-int.h.jj   2023-06-07 09:42:14.997126190 +0200
+++ gcc/wide-int.h  2023-08-28 15:09:06.498448770 +0200
@@ -1065,7 +1065,11 @@ namespace wi
 class GTY(()) wide_int_storage
 {
 private:
-  HOST_WIDE_INT val[WIDE_INT_MAX_ELTS];
+  union
+  {
+HOST_WIDE_INT val[WIDE_INT_MAX_ELTS];
+HOST_WIDE_INT *valp;
+  } GTY((skip)) u;
   unsigned int len;
   unsigned int precision;
 
@@ -1073,6 +1077,7 @@ public:
   wide_int_storage ();
   template 
   wide_int_storage (const T &);
+  ~wide_int_storage ();
 
   /* The standard generic_wide_int storage methods.  */
   unsigned int get_precision () const;
@@ -1104,7 +1109,7 @@ 

[PATCH] libcpp, v2: Small incremental patch for P1854R4 [PR110341]

2023-08-28 Thread Jakub Jelinek via Gcc-patches
Hi!

Sorry, testing revealed an unused uchar *outbuf; declaration breaking the
build, here is the same patch with that one line removed,
bootstrapped/regtested on x86_64-linux and i686-linux (on top of the earlier
POR110341 patch).

On Sat, Aug 26, 2023 at 01:11:06PM +0200, Jakub Jelinek via Gcc-patches wrote:
> The following incremental patch to the PR110341 posted patch uses
> a special conversion callback instead of conversion from host charset
> (UTF-8/UTF-EBCDIC) to UTF-32, and also ignores all diagnostics from the
> second cpp_interpret_string which should just count chars.  The UTF-EBCDIC
> is untested, but simple enough that it should just work.

2023-08-28  Jakub Jelinek  

PR c++/110341
* charset.cc (one_count_chars, convert_count_chars): New functions.
(narrow_str_to_charconst): Call cpp_interpret_string with type
rather than CPP_STRING32, temporarily override for that call
pfile->cb.diagnostic to noop_diagnostic_cb and
pfile->narrow_cset_desc.func to convert_count_chars and just compare
str.len against str2.len.

--- libcpp/charset.cc.jj2023-08-25 17:14:14.098733396 +0200
+++ libcpp/charset.cc   2023-08-28 12:57:44.858858994 +0200
@@ -446,6 +446,73 @@ one_utf16_to_utf8 (iconv_t bigend, const
   return 0;
 }
 
+
+/* Special routine which just counts number of characters in the
+   string, what exactly is stored into the output doesn't matter
+   as long as it is one uchar per character.  */
+
+static inline int
+one_count_chars (iconv_t, const uchar **inbufp, size_t *inbytesleftp,
+uchar **outbufp, size_t *outbytesleftp)
+{
+  cppchar_t s = 0;
+  int rval;
+
+  /* Check for space first, since we know exactly how much we need.  */
+  if (*outbytesleftp < 1)
+return E2BIG;
+
+#if HOST_CHARSET == HOST_CHARSET_ASCII
+  rval = one_utf8_to_cppchar (inbufp, inbytesleftp, );
+  if (rval)
+return rval;
+#else
+  if (*inbytesleftp < 1)
+return EINVAL;
+  static const uchar utf_ebcdic_map[256] = {
+/* See table 4 in http://unicode.org/reports/tr16/tr16-7.2.html  */
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1,
+1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1,
+1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1,
+9, 9, 9, 9, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 1, 3, 3,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 4,
+1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 5, 5, 5,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 6, 7, 7, 0
+  };
+  rval = utf_ebcdic_map[**inbufp];
+  if (rval == 9)
+return EILSEQ;
+  if (rval == 0)
+rval = 1;
+  if (rval >= 2)
+{
+  if (*inbytesleftp < rval)
+   return EINVAL;
+  for (int i = 1; i < rval; ++i)
+   if (utf_ebcdic_map[(*inbufp)[i]] != 9)
+ return EILSEQ;
+}
+  *inbytesleftp -= rval;
+  *inbufp += rval;
+#endif
+
+  **outbufp = ' ';
+
+  *outbufp += 1;
+  *outbytesleftp -= 1;
+  return 0;
+}
+
+
 /* Helper routine for the next few functions.  The 'const' on
one_conversion means that we promise not to modify what function is
pointed to, which lets the inliner see through it.  */
@@ -529,6 +596,15 @@ convert_utf32_utf8 (iconv_t cd, const uc
   return conversion_loop (one_utf32_to_utf8, cd, from, flen, to);
 }
 
+/* Magic conversion which just counts characters from input, so
+   only to->len is significant.  */
+static bool
+convert_count_chars (iconv_t cd, const uchar *from,
+size_t flen, struct _cpp_strbuf *to)
+{
+  return conversion_loop (one_count_chars, cd, from, flen, to);
+}
+
 /* Identity conversion, used when we have no alternative.  */
 static bool
 convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED,
@@ -2623,15 +2699,22 @@ narrow_str_to_charconst (cpp_reader *pfi
 ill-formed.  We need to count the number of c-chars and compare
 that to str.len.  */
   cpp_string str2 = { 0, 0 };
-  if (cpp_interpret_string (pfile, >val.str, 1, ,
-   CPP_STRING32))
+  bool (*saved_diagnostic_handler) (cpp_reader *, enum 
cpp_diagnostic_level,
+   enum cpp_warning_reason, rich_location 
*,
+   const char *, va_list *)
+   ATTRIBUTE_FPTR_PRINTF(5,0);
+  saved_diagnostic_handler = pfile->cb.diagnostic;
+  pfile->cb.diagnostic = noop_diagnostic_cb;
+  convert_f save_func = pfile->narrow_cset_desc.func;
+  pfile->narrow_cset_desc.func = convert_coun

[PATCH] c++, v2: Fix up mangling of function/block scope static structured bindings and emit abi tags [PR111069]

2023-08-28 Thread Jakub Jelinek via Gcc-patches
Hi!

On Thu, Aug 24, 2023 at 06:39:10PM +0200, Jakub Jelinek via Gcc-patches wrote:
> > Maybe do this in mangle_decomp, based on the actual mangling in process
> > instead of this pseudo-mangling?
> 
> Not sure that is possible, for 2 reasons:
> 1) determine_local_discriminator otherwise works on DECL_NAME, not mangled
>names, so if one uses (albeit implementation reserved)
>_ZZN1N3fooI1TB3bazEEivEDC1h1iEB6foobar and similar identifiers, they
>could clash with the counting of the structured bindings
> 2) seems the local discriminator counting shouldn't take into account
>details like abi tags, e.g. if I have:

The following updated patch handles everything except it leaves for the
above 2 reasons the determination of local discriminator where it was.
I had to add a new (defaulted) argument to cp_finish_decl and do
cp_maybe_mangle_decomp from there, so that it is after e.g. auto type
deduction and maybe_commonize_var (which had to be changed as well) and
spots in cp_finish_decl where we need or might need mangled names already.

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

There is one difference between g++ with this patch and clang++,
g++ uses
_ZZ3barI1TB3quxEivEDC1o1pEB3qux
while clang++ uses
_ZZ3barI1TB3quxEivEDC1o1pE
but from what I can see, such a difference is there also when just using
normal local decls:
struct [[gnu::abi_tag ("foobar")]] S { int i; };
struct [[gnu::abi_tag ("qux")]] T { int i; S j; int k; };

inline int
foo ()
{
  static S c;
  static T d;
  return ++c.i + ++d.i;
}

template 
inline int
bar ()
{
  static S c;
  static T d;
  return ++c.i + ++d.i;
}

int (*p) () = 
int (*q) () = ;
where both compilers mangle c in foo as:
_ZZ3foovE1cB6foobar
and d in there as
_ZZ3foovE1dB3qux
and similarly both compilers mangle c in bar as
_ZZ3barI1TB3quxEivE1cB6foobar
but g++ mangles d in bar as
_ZZ3barI1TB3quxEivE1dB3qux
while clang++ mangles it as just
_ZZ3barI1TB3quxEivE1d
No idea what is right or wrong according to Itanium mangling.

2023-08-28  Jakub Jelinek  

PR c++/111069
gcc/
* common.opt (fabi-version=): Document version 19.
* doc/invoke.texi (-fabi-version=): Likewise.
gcc/c-family/
* c-opts.cc (c_common_post_options): Change latest_abi_version to 19.
gcc/cp/
* cp-tree.h (determine_local_discriminator): Add NAME argument with
NULL_TREE default.
(struct cp_decomp): New type.
(cp_finish_decl): Add DECOMP argument defaulted to nullptr.
(cp_maybe_mangle_decomp): Remove declaration.
* decl.cc (determine_local_discriminator): Add NAME argument, use it
if non-NULL, otherwise compute it the old way.
(maybe_commonize_var): Don't return early for structured bindings.
(cp_finish_decl): Add DECOMP argument, if non-NULL, call
cp_maybe_mangle_decomp.
(cp_maybe_mangle_decomp): Make it static with a forward declaration.
Call determine_local_discriminator.
* mangle.cc (find_decomp_unqualified_name): Remove.
(write_unqualified_name): Don't call find_decomp_unqualified_name.
(mangle_decomp): Handle mangling of static function/block scope
structured bindings.  Don't call decl_mangling_context twice.  Call
check_abi_tags, call write_abi_tags for abi version >= 19 and emit
-Wabi warnings if needed.
(write_guarded_var_name): Handle structured bindings.
(mangle_ref_init_variable): Use write_guarded_var_name.
* parser.cc (cp_convert_range_for, cp_parser_decomposition_declaration,
cp_finish_omp_range_for): Don't call cp_maybe_mangle_decomp, adjust
cp_finish_decl callers.
* pt.cc (tsubst_expr): Likewise.
gcc/testsuite/
* g++.dg/cpp2a/decomp8.C: New test.
* g++.dg/cpp2a/decomp9.C: New test.
* g++.dg/abi/macro0.C: Expect __GXX_ABI_VERSION 1019 rather than
1018.

--- gcc/common.opt.jj   2023-08-28 10:32:41.519579280 +0200
+++ gcc/common.opt  2023-08-28 10:35:30.337342832 +0200
@@ -1010,6 +1010,9 @@ Driver Undocumented
 ; 18: Corrects errors in mangling of lambdas with additional context.
 ; Default in G++ 13.
 ;
+; 19: Emits ABI tags if needed in structured binding mangled names.
+; Default in G++ 14.
+;
 ; Additional positive integers will be assigned as new versions of
 ; the ABI become the default version of the ABI.
 fabi-version=
--- gcc/doc/invoke.texi.jj  2023-08-28 10:32:42.322568643 +0200
+++ gcc/doc/invoke.texi 2023-08-28 10:35:30.342342766 +0200
@@ -3016,6 +3016,9 @@ in C++14 and up.
 Version 18, which first appeard in G++ 13, fixes manglings of lambdas
 that have additional context.
 
+Version 19, which first appeard in G++ 14, fixes manglings of structured
+bindings to include ABI tags.
+
 See also @option{-Wabi}.
 
 @opindex fabi-compat-version
--- gcc/c-family/c-opts.cc.jj   2023-08-28 10:32:41.462580035 +0200
+++ gcc/c-family/c-opts.c

Patch ping^2 Re: [PATCH 0/12] GCC _BitInt support [PR102989]

2023-08-28 Thread Jakub Jelinek via Gcc-patches
Hi!

On Mon, Aug 21, 2023 at 05:24:02PM +0200, Jakub Jelinek via Gcc-patches wrote:
> Jakub Jelinek (12):
>   expr: Small optimization [PR102989]
>   lto-streamer-in: Adjust assert [PR102989]
>   phiopt: Fix phiopt ICE on vops [PR102989]
>   Middle-end _BitInt support [PR102989]
>   _BitInt lowering support [PR102989]
>   i386: Enable _BitInt on x86-64 [PR102989]
>   ubsan: _BitInt -fsanitize=undefined support [PR102989]

>   libgcc: Generated tables for _BitInt <-> _Decimal* conversions [PR102989]
>   libgcc _BitInt support [PR102989]
>   C _BitInt support [PR102989]

>   testsuite part 1 for _BitInt support [PR102989]
>   testsuite part 2 for _BitInt support [PR102989]

+   C _BitInt incremental fixes [PR102989]
+   libgcc _BitInt helper documentation [PR102989]

I'd like to ping the rest of this patch series.
First 3 patches are committed, next 4 are approved with commit waiting
for approval of the rest, the 2 testsuite patches are also approved if
you don't have further comments on them, the 3 libgcc patches and 2
C _BitInt patches need to be reviewed.

https://gcc.gnu.org/pipermail/gcc-patches/2023-August/626850.html
https://gcc.gnu.org/pipermail/gcc-patches/2023-August/626851.html
https://gcc.gnu.org/pipermail/gcc-patches/2023-August/626852.html
https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627033.html
https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628141.html

Thanks.

Jakub



Re: [PATCH] [frange] Relax floating point relational folding.

2023-08-28 Thread Jakub Jelinek via Gcc-patches
On Wed, Aug 23, 2023 at 05:22:00PM +0200, Aldy Hernandez via Gcc-patches wrote:
> BTW, we batted some ideas on how to get this work, and it seems this
> is the cleaner route with the special cases nestled in the operators
> themselves.  Another idea is to add unordered relations, but that
> would require bloating the various tables adding spots for VREL_UNEQ,
> VREL_UNLT, etc, plus adding relations for VREL_UNORDERED so the
> intersects work correctly.  I'm not wed to either one, and we can
> certainly revisit this if it becomes burdensome to maintain (or to get
> right).

My strong preference would be to have the full set of operations,
i.e. VREL_LTGT, VREL_{,UN}ORDERED, VREL_UN{LT,LE,GT,GE,EQ}, then everything
will fall out of this cleanly, not just some common special cases, but
also unions of them, intersections etc.
The only important question is if you want to differentiate VREL_*
for floating point comparisions with possible NANs vs. other comparisons
in the callers, then one needs effectively e.g. 2 sets of rr_* tables
in value-relation.cc and what exactly say VREL_EQ inverts to etc. is then
dependent on the context (this is what we do at the tree level normally,
e.g. fold-const.cc (invert_tree_comparison) has honor_nans argument),
or whether it would be a completely new set of value relations, so
even for EQ/NE etc. one would use VRELF_ or something similar.

Jakub



[PATCH] libcpp: Small incremental patch for P1854R4 [PR110341]

2023-08-26 Thread Jakub Jelinek via Gcc-patches
Hi!

The following incremental patch to the PR110341 posted patch uses
a special conversion callback instead of conversion from host charset
(UTF-8/UTF-EBCDIC) to UTF-32, and also ignores all diagnostics from the
second cpp_interpret_string which should just count chars.  The UTF-EBCDIC
is untested, but simple enough that it should just work.

2023-08-26  Jakub Jelinek  

PR c++/110341
* charset.cc (one_count_chars, convert_count_chars): New functions.
(narrow_str_to_charconst): Call cpp_interpret_string with type
rather than CPP_STRING32, temporarily override for that call
pfile->cb.diagnostic to noop_diagnostic_cb and
pfile->narrow_cset_desc.func to convert_count_chars and just compare
str.len against str2.len.

--- libcpp/charset.cc.jj2023-08-25 17:14:14.098733396 +0200
+++ libcpp/charset.cc   2023-08-26 12:57:44.858858994 +0200
@@ -446,6 +446,74 @@ one_utf16_to_utf8 (iconv_t bigend, const
   return 0;
 }
 
+
+/* Special routine which just counts number of characters in the
+   string, what exactly is stored into the output doesn't matter
+   as long as it is one uchar per character.  */
+
+static inline int
+one_count_chars (iconv_t, const uchar **inbufp, size_t *inbytesleftp,
+uchar **outbufp, size_t *outbytesleftp)
+{
+  uchar *outbuf;
+  cppchar_t s = 0;
+  int rval;
+
+  /* Check for space first, since we know exactly how much we need.  */
+  if (*outbytesleftp < 1)
+return E2BIG;
+
+#if HOST_CHARSET == HOST_CHARSET_ASCII
+  rval = one_utf8_to_cppchar (inbufp, inbytesleftp, );
+  if (rval)
+return rval;
+#else
+  if (*inbytesleftp < 1)
+return EINVAL;
+  static const uchar utf_ebcdic_map[256] = {
+/* See table 4 in http://unicode.org/reports/tr16/tr16-7.2.html  */
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1,
+1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1,
+1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1,
+9, 9, 9, 9, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2,
+2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 1, 3, 3,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 4,
+1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 5, 5, 5,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 6, 7, 7, 0
+  };
+  rval = utf_ebcdic_map[**inbufp];
+  if (rval == 9)
+return EILSEQ;
+  if (rval == 0)
+rval = 1;
+  if (rval >= 2)
+{
+  if (*inbytesleftp < rval)
+   return EINVAL;
+  for (int i = 1; i < rval; ++i)
+   if (utf_ebcdic_map[(*inbufp)[i]] != 9)
+ return EILSEQ;
+}
+  *inbytesleftp -= rval;
+  *inbufp += rval;
+#endif
+
+  **outbufp = ' ';
+
+  *outbufp += 1;
+  *outbytesleftp -= 1;
+  return 0;
+}
+
+
 /* Helper routine for the next few functions.  The 'const' on
one_conversion means that we promise not to modify what function is
pointed to, which lets the inliner see through it.  */
@@ -529,6 +597,15 @@ convert_utf32_utf8 (iconv_t cd, const uc
   return conversion_loop (one_utf32_to_utf8, cd, from, flen, to);
 }
 
+/* Magic conversion which just counts characters from input, so
+   only to->len is significant.  */
+static bool
+convert_count_chars (iconv_t cd, const uchar *from,
+size_t flen, struct _cpp_strbuf *to)
+{
+  return conversion_loop (one_count_chars, cd, from, flen, to);
+}
+
 /* Identity conversion, used when we have no alternative.  */
 static bool
 convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED,
@@ -2613,15 +2690,22 @@ narrow_str_to_charconst (cpp_reader *pfi
 ill-formed.  We need to count the number of c-chars and compare
 that to str.len.  */
   cpp_string str2 = { 0, 0 };
-  if (cpp_interpret_string (pfile, >val.str, 1, ,
-   CPP_STRING32))
+  bool (*saved_diagnostic_handler) (cpp_reader *, enum 
cpp_diagnostic_level,
+   enum cpp_warning_reason, rich_location 
*,
+   const char *, va_list *)
+   ATTRIBUTE_FPTR_PRINTF(5,0);
+  saved_diagnostic_handler = pfile->cb.diagnostic;
+  pfile->cb.diagnostic = noop_diagnostic_cb;
+  convert_f save_func = pfile->narrow_cset_desc.func;
+  pfile->narrow_cset_desc.func = convert_count_chars;
+  bool ret = cpp_interpret_string (pfile, >val.str, 1, , type);
+  pfile->narrow_cset_desc.func = save_func;
+  pfile->cb.diagnostic = saved_diagnostic_handler;
+  if (ret)
{
- size_t width32 = converter_for_type (pfile, CPP_STRING32).width;
- size_t nbwc = width32 / width;
- size_t len = str2.len / 

[PATCH] c++: Implement C++26 P1854R4 - Making non-encodable string literals ill-formed [PR110341]

2023-08-25 Thread Jakub Jelinek via Gcc-patches
Hi!

This paper voted in as DR makes some multi-character literals ill-formed.
'abcd' stays valid, but e.g. 'á' is newly invalid in UTF-8 exec charset
while valid e.g. in ISO-8859-1, because it is a single character which needs
2 bytes to be encoded.

The following patch does that by checking (only pedantically, especially
because it is a DR) if we'd emit a -Wmultichar warning because character
constant has more than one byte in it whether the number of bytes in the
narrow string matches number of bytes in CPP_STRING32 divided by char32_t
size in bytes.  If it is, it is normal multi-character literal constant
and is diagnosed normally with -Wmultichar, if the number of bytes is
larger, at least one of the c-chars in the sequence was encoded as 2+
bytes.

Now, doing this way has 2 drawbacks, some of the diagnostics which doesn't
result in cpp_interpret_string_1 failures can be printed twice, once
when calling cpp_interpret_string_1 for CPP_CHAR, once for CPP_STRING32.
And, functionally I think it must work 100% correctly if host source
character set is UTF-8 (because all valid UTF-8 chars are encodable in
UTF-32), but might not work for some control codes in UTF-EBCDIC if
that is the source character set (though I don't know if we really actually
support it, e.g. Linux iconv certainly doesn't).
All we actually need is count the number of c-chars in the literal,
alternative would be to write custom character counter which would quietly
interpret/skip over + count escape sequences and decode UTF-8 characters
in between those escape sequences.  But we'd need to have something similar
also for UTF-EBCDIC if it works at all, and from what I've looked, we don't
have anyything like that implemented in libcpp nor anywhere else in GCC.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Or ok with some tweaks to avoid the second round of diagnostics from
cpp_interpret_string_1/convert_escape?  Or reimplement that second time and
count manually?

2023-08-25  Jakub Jelinek  

PR c++/110341
libcpp/
* charset.cc: Implement C++ 26 P1854R4 - Making non-encodable string
literals ill-formed.
(narrow_str_to_charconst): Change last type from cpp_ttype to
const cpp_token *.  For C++ if pedantic and i > 1 in CPP_CHAR
interpret token also as CPP_STRING32 and if number of characters
in the CPP_STRING32 is larger than number of bytes in CPP_CHAR,
pedwarn on it.
(cpp_interpret_charconst): Adjust narrow_str_to_charconst caller.
gcc/testsuite/
* g++.dg/cpp26/literals1.C: New test.
* g++.dg/cpp26/literals2.C: New test.
* g++.dg/cpp23/wchar-multi1.C (c, d): Expect an error rather than
warning.

--- libcpp/charset.cc.jj2023-08-24 15:36:59.0 +0200
+++ libcpp/charset.cc   2023-08-25 17:14:14.098733396 +0200
@@ -2567,18 +2567,20 @@ cpp_interpret_string_notranslate (cpp_re
 /* Subroutine of cpp_interpret_charconst which performs the conversion
to a number, for narrow strings.  STR is the string structure returned
by cpp_interpret_string.  PCHARS_SEEN and UNSIGNEDP are as for
-   cpp_interpret_charconst.  TYPE is the token type.  */
+   cpp_interpret_charconst.  TOKEN is the token.  */
 static cppchar_t
 narrow_str_to_charconst (cpp_reader *pfile, cpp_string str,
 unsigned int *pchars_seen, int *unsignedp,
-enum cpp_ttype type)
+const cpp_token *token)
 {
+  enum cpp_ttype type = token->type;
   size_t width = CPP_OPTION (pfile, char_precision);
   size_t max_chars = CPP_OPTION (pfile, int_precision) / width;
   size_t mask = width_to_mask (width);
   size_t i;
   cppchar_t result, c;
   bool unsigned_p;
+  bool diagnosed = false;
 
   /* The value of a multi-character character constant, or a
  single-character character constant whose representation in the
@@ -2602,7 +2604,37 @@ narrow_str_to_charconst (cpp_reader *pfi
 
   if (type == CPP_UTF8CHAR)
 max_chars = 1;
-  if (i > max_chars)
+  else if (i > 1 && CPP_OPTION (pfile, cplusplus) && CPP_PEDANTIC (pfile))
+{
+  /* C++ as a DR since
+P1854R4 - Making non-encodable string literals ill-formed
+makes multi-character narrow character literals if any of the
+characters in the literal isn't encodable in char/unsigned char
+ill-formed.  We need to count the number of c-chars and compare
+that to str.len.  */
+  cpp_string str2 = { 0, 0 };
+  if (cpp_interpret_string (pfile, >val.str, 1, ,
+   CPP_STRING32))
+   {
+ size_t width32 = converter_for_type (pfile, CPP_STRING32).width;
+ size_t nbwc = width32 / width;
+ size_t len = str2.len / nbwc;
+ if (str2.text != token->val.str.text)
+   free ((void *)str2.text);
+ if (str.len > len)
+   {
+ diagnosed
+   = cpp_error (pfile, CPP_DL_PEDWARN,
+   

[PATCH] c++: Implement C++ DR 2406 - [[fallthrough]] attribute and iteration statements

2023-08-25 Thread Jakub Jelinek via Gcc-patches
Hi!

The following patch implements
CWG 2406 - [[fallthrough]] attribute and iteration statements
The genericization of some loops leaves nothing at all or just a label
after a body of a loop, so if the loop is later followed by
case or default label in a switch, the fallthrough statement isn't
diagnosed.

The following patch implements it by marking the IFN_FALLTHROUGH call
in such a case, such that during gimplification it can be pedantically
diagnosed even if it is followed by case or default label or some normal
labels followed by case/default labels.

While looking into this, I've discovered other problems.
expand_FALLTHROUGH_r is removing the IFN_FALLTHROUGH calls from the IL,
but wasn't telling that to walk_gimple_stmt/walk_gimple_seq_mod, so
the callers would then skip the next statement after it, and it would
return non-NULL if the removed stmt was last in the sequence.  This could
lead to wi->callback_result being set even if it didn't appear at the very
end of switch sequence.
The patch makes use of wi->removed_stmt such that the callers properly
know what happened, and use different way to handle the end of switch
sequence case.

That change discovered a bug in the gimple-walk handling of
wi->removed_stmt.  If that flag is set, the callback is telling the callers
that the current statement has been removed and so the innermost
walk_gimple_seq_mod shouldn't gsi_next.  The problem is that
wi->removed_stmt is only reset at the start of a walk_gimple_stmt, but that
can be too late for some cases.  If we have two nested gimple sequences,
say GIMPLE_BIND as the last stmt of some gimple seq, we remove the last
statement inside of that GIMPLE_BIND, set wi->removed_stmt there, don't
do gsi_next correctly because already gsi_remove moved us to the next stmt,
there is no next stmt, so we return back to the caller, but wi->removed_stmt
is still set and so we don't do gsi_next even in the outer sequence, despite
the GIMPLE_BIND (etc.) not being removed.  That means we walk the
GIMPLE_BIND with its whole sequence again.
The patch fixes that by resetting wi->removed_stmt after we've used that
flag in walk_gimple_seq_mod.  Nothing really uses that flag after the
outermost walk_gimple_seq_mod, it is just a private notification that
the stmt callback has removed a stmt.

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

2023-08-25  Jakub Jelinek  

gcc/
* gimplify.cc (expand_FALLTHROUGH_r): Use wi->removed_stmt after
gsi_remove, change the way of passing fallthrough stmt at the end
of sequence to expand_FALLTHROUGH.  Diagnose IFN_FALLTHROUGH
with GF_CALL_NOTHROW flag.
(expand_FALLTHROUGH): Change loc into array of 2 location_t elts,
don't test wi.callback_result, instead check whether first
elt is not UNKNOWN_LOCATION and in that case pedwarn with the
second location.
* gimple-walk.cc (walk_gimple_seq_mod): Clear wi->removed_stmt
after the flag has been used.
gcc/c-family/
* c-gimplify.cc (genericize_c_loop): For C++ mark IFN_FALLTHROUGH
call at the end of loop body as TREE_NOTHROW.
gcc/testsuite/
* g++.dg/DRs/dr2406.C: New test.

--- gcc/gimplify.cc.jj  2023-08-23 11:22:28.115592483 +0200
+++ gcc/gimplify.cc 2023-08-25 13:43:58.711847414 +0200
@@ -2588,17 +2588,33 @@ expand_FALLTHROUGH_r (gimple_stmt_iterat
   *handled_ops_p = false;
   break;
 case GIMPLE_CALL:
+  static_cast(wi->info)[0] = UNKNOWN_LOCATION;
   if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
{
+ location_t loc = gimple_location (stmt);
  gsi_remove (gsi_p, true);
+ wi->removed_stmt = true;
+
+ /* nothrow flag is added by genericize_c_loop to mark fallthrough
+statement at the end of some loop's body.  Those should be
+always diagnosed, either because they indeed don't precede
+a case label or default label, or because the next statement
+is not within the same iteration statement.  */
+ if ((stmt->subcode & GF_CALL_NOTHROW) != 0)
+   {
+ pedwarn (loc, 0, "attribute % not preceding "
+  "a case label or default label");
+ break;
+   }
+
  if (gsi_end_p (*gsi_p))
{
- *static_cast(wi->info) = gimple_location (stmt);
- return integer_zero_node;
+ static_cast(wi->info)[0] = BUILTINS_LOCATION;
+ static_cast(wi->info)[1] = loc;
+ break;
}
 
  bool found = false;
- location_t loc = gimple_location (stmt);
 
  gimple_stmt_iterator gsi2 = *gsi_p;
  stmt = gsi_stmt (gsi2);
@@ -2648,6 +2664,7 @@ expand_FALLTHROUGH_r (gimple_stmt_iterat
}
   break;
 default:
+  static_cast(wi->info)[0] = UNKNOWN_LOCATION;
   break;
 }
   return NULL_TREE;
@@ -2659,14 +2676,16 @@ static void
 expand_FALLTHROUGH 

Re: [PATCH] c++: Fix up mangling of function/block scope static structured bindings [PR111069]

2023-08-24 Thread Jakub Jelinek via Gcc-patches
On Wed, Aug 23, 2023 at 04:23:00PM -0400, Jason Merrill wrote:
> I'd be surprised if this would affect any real code, but I suppose so. In
> any case I'd like to fix this at the same time as the local statics, to
> avoid changing their mangled name twice.

Ok.
Running now into a problem with abi tags, because cp_maybe_mangle_decomp
is called before the type of the structured binding is finalized (sequence
is cp_maybe_mangle_decomp; cp_finish_decl; cp_finish_decomp), I vaguely
remember the reason was to have the name already mangled by cp_finish_decl
time, so that it can add it into varpool etc..
Will see if I can e.g. pass the initializer expression to
cp_maybe_mangle_decomp and figure out the tags from that.

> > @@ -9049,6 +9050,25 @@ cp_maybe_mangle_decomp (tree decl, tree
> > tree d = first;
> > for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d))
> > v[count - i - 1] = d;
> > +  if (DECL_FUNCTION_SCOPE_P (decl))
> > +   {
> > + size_t sz = 3;
> > + for (unsigned int i = 0; i < count; ++i)
> > +   sz += IDENTIFIER_LENGTH (DECL_NAME (v[i])) + 1;
> > + char *name = XALLOCAVEC (char, sz);
> > + name[0] = 'D';
> > + name[1] = 'C';
> > + char *p = name + 2;
> > + for (unsigned int i = 0; i < count; ++i)
> > +   {
> > + size_t len = IDENTIFIER_LENGTH (DECL_NAME (v[i]));
> > + *p++ = ' ';
> > + memcpy (p, IDENTIFIER_POINTER (DECL_NAME (v[i])), len);
> > + p += len;
> > +   }
> > + *p = '\0';
> > + determine_local_discriminator (decl, get_identifier (name));
> > +   }
> 
> Maybe do this in mangle_decomp, based on the actual mangling in process
> instead of this pseudo-mangling?

Not sure that is possible, for 2 reasons:
1) determine_local_discriminator otherwise works on DECL_NAME, not mangled
   names, so if one uses (albeit implementation reserved)
   _ZZN1N3fooI1TB3bazEEivEDC1h1iEB6foobar and similar identifiers, they
   could clash with the counting of the structured bindings
2) seems the local discriminator counting shouldn't take into account
   details like abi tags, e.g. if I have:
struct [[gnu::abi_tag ("foobar")]] S { int a; };
namespace N {
  template 
  inline int
  foo ()
  {
static int h = 42; int r = ++h;
{ static S h = { 42 }; r += ++h.a; }
{ static int h = 42; r += ++h; }
{ static S h = { 42 }; r += ++h.a; }
return r;
  }
}
int (*p) () = N::foo;
  then both GCC and Clang mangle these as
  _ZZN1N3fooIiEEivE1h
  _ZZN1N3fooIiEEivE1hB6foobar_0
  _ZZN1N3fooIiEEivE1h_1
  _ZZN1N3fooIiEEivE1hB6foobar_2
  so whether abi tags appear in the mangled name or not shouldn't result
  in separate buckets for counting.

> 
> > @@ -4564,6 +4519,13 @@ write_guarded_var_name (const tree varia
> >   /* The name of a guard variable for a reference temporary should refer
> >  to the reference, not the temporary.  */
> >   write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
> > +  else if (DECL_DECOMPOSITION_P (variable)
> > +  && DECL_NAME (variable) == NULL_TREE
> > +  && startswith (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (variable)),
> > + "_Z"))
> 
> Maybe add a startswith overload that takes an identifier?

Ok.

> > @@ -4630,7 +4592,10 @@ mangle_ref_init_variable (const tree var
> > start_mangling (variable);
> > write_string ("_ZGR");
> > check_abi_tags (variable);
> > -  write_name (variable, /*ignore_local_scope=*/0);
> > +  if (DECL_DECOMPOSITION_P (variable))
> > +write_guarded_var_name (variable);
> > +  else
> > +write_name (variable, /*ignore_local_scope=*/0);
> 
> Why not use write_guarded_name unconditionally?

Ok.

Jakub



Re: [RFC] gimple ssa: SCCP - A new PHI optimization pass

2023-08-24 Thread Jakub Jelinek via Gcc-patches
On Thu, Aug 24, 2023 at 05:47:09PM +0200, Richard Biener via Gcc-patches wrote:
> > Do you think that the pass is worthy of inclusion into upstream GCC? What 
> > are
> > some things that I should change? Should I try to put the pass in different
> > places in passes.def?
> 
> The most obvious places would be right after SSA construction and before RTL 
> expansion.
> Can you provide measurements for those positions?
> Can the pass somehow be used as part of propagations like during value 
> numbering?

Could the new file be called gimple-ssa-sccp.cc or something similar?
Removing some PHIs is nice, but it would be also interesting to know what
are the effects on generated code size and/or performance.
And also if it has any effects on debug information coverage.

Jakub



[PATCH] c++: Implement C++26 P2741R3 - user-generated static_assert messages [PR110348]

2023-08-24 Thread Jakub Jelinek via Gcc-patches
Hi!

The following patch on top of PR110349 patch (weak dependency,
only for -Wc++26-extensions, I could split that part into an independent
patch) and PR110342 patch (again weak dependency, this time mainly
because it touches the same code in cp_parser_static_assert and
nearby spot in udlit-error1.C testcase) implements the user generated
static_assert messages next to string literals.

As I wrote already in the PR, in addition to looking through the paper
I looked at the clang++ testcase for this feature implemented there from
paper's author and on godbolt played with various parts of the testcase
coverage below, and there are 4 differences between what the patch
implements and what clang++ implements.

The first is that clang++ diagnoses if M.size () or M.data () methods
are present, but aren't constexpr; while the paper introduction talks about
that, the standard wording changes don't seem to require that, all they say
is that those methods need to exist (assuming accessible and the like)
and be implicitly convertible to std::size_t or const char *, but rest is
only if the static assertion fails.  If there is intent to change that
wording, the question is how far to go, e.g. while M.size () could be
constexpr, they could e.g. return some class object which wouldn't have
constexpr conversion operator to size_t/const char * and tons of other
reasons why the constant evaluation could fail.  Without actually evaluating
it I don't see how we could guarantee anything for non-failed static_assert.

The second and most important is that clang++ has a couple of tests (and the
testcase below as well) where M.data () is not a core constant expression
but M.data ()[0] ... M.data ()[M.size () - 1] is integer constant
expression.  From my reading of http://eel.is/c++draft/dcl.pre#11.2.2
that means those should be rejected (examples of these are e.g.
static_assert (false, T{});
in the testcase, where T{}.data () returns pointer returned from new
expression, but T{}'s destructor then deletes it, making it point to
no longer live object.  Or
static_assert (false, a);
where a.data () returns  but because a is constexpr automatic variable,
that isn't valid core constant expression, while a.data ()[0] is.
There are a couple of others.  Now, it seems allowing that is quite useful
in real-world, but the question is with what standard changes to achieve
that.  One possibility would be s/a core constant/an/; from implementation
POV that would mean that if M.size () is 0, then M.data () doesn't have
to be constexpr at all.  Otherwise, implementation could try to evaluate
silently M.data () as constant expression, if it would be one, it could
just use c_getstr in the GCC case as the patch does + optionally the 2
M.data ()[0] and M.data ()[M.size () - 1] tests to verify boundary cases
more carefully.  And if it wouldn't be one, it would need to evaluate
M.data ()[i] for i in [0, M.size () - 1] to get all the characters one by
one.  Another possibility would be to require that say ((void) (M.data ()), 0)
is a constant expression, that doesn't help much with the optimized way
to get at the message characters, but would require that data () is
constexpr even for the 0 case etc.

The third difference is that 
static_assert (false, "foo"_myd);
in the testcase is normal failed static assertion and
static_assert (true, "foo"_myd);
would be accepted, while clang++ rejects it.  IMHO
"foo"_myd doesn't match the syntactic requirements of unevaluated-string
as mentioned in http://eel.is/c++draft/dcl.pre#10 , and because
a constexpr udlit operator can return something which is valid, it shouldn't
be rejected just in case.

Last is clang++ ICEs on non-static data members size/data.

The patch implements what I see in the paper, because it is unclear what
further changes will be voted in (and the changes can be done at that
point).
The patch uses tf_none in 6 spots so that just the static_assert specific
errors are emitted and not others, but it would certainly be possible to
use complain instead of tf_none there, get more errors in some cases, but
perhaps help users figure out what exactly is wrong in detail.

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

2023-08-24  Jakub Jelinek  

PR c++/110348
gcc/c-family/
* c-cppbuiltin.cc (c_cpp_builtins): For C++26 predefine
__cpp_static_assert to 202306L rather than 201411L.
gcc/cp/
* parser.cc: Implement C++26 P2741R3 - user-generated static_assert
messages.
(cp_parser_static_assert): Parse message argument as
conditional-expression if it is not a pure string literal or
several of them concatenated followed by closing paren.
* semantics.cc (finish_static_assert): Handle message which is not
STRING_CST.
* pt.cc (tsubst_expr) : Also tsubst_expr
message and make sure that if it wasn't originally STRING_CST, it
isn't after tsubst_expr either.
gcc/testsuite/
* 

[PATCH] c++: Implement C++26 P2361R6 - Unevaluated strings [PR110342]

2023-08-24 Thread Jakub Jelinek via Gcc-patches
Hi!

The following patch implements C++26 unevaluated-string.
As it seems to me just extra pedanticity, it is implemented only for
-std=c++26 or -std=gnu++26 and later and only if -pedantic/-pedantic-errors.
Nothing is done for inline asm, while the spec changes those, it changes it
to a balanced token sequence with implementation defined rules on what is
and isn't allowed (so pedantically accepting asm ("" : "+m" (x));
was accepts-invalid before C++26, but we didn't diagnose anything).
For the other spots mentioned in the paper, static_assert message,
linkage specification, deprecated/nodiscard attributes it enforces the
requirements (no prefixes, udlit suffixes, no octal/hexadecimal escapes
(conditional escape sequences were rejected with pedantic already before).
For the deprecated operator "" identifier case I've kept things as is,
because everything seems to have been diagnosed already (a lot being implied
from the string having to be empty).

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

2023-08-24  Jakub Jelinek  

PR c++/110342
gcc/cp/
* parser.cc: Implement C++26 P2361R6 - Unevaluated strings.
(uneval_string_attr): New enumerator.
(cp_parser_string_literal_common): Add UNEVAL argument.  If true,
pass CPP_UNEVAL_STRING rather than CPP_STRING to
cpp_interpret_string_notranslate.
(cp_parser_string_literal, cp_parser_userdef_string_literal): Adjust
callers of cp_parser_string_literal_common.
(cp_parser_unevaluated_string_literal): New function.
(cp_parser_parenthesized_expression_list): Handle uneval_string_attr.
(cp_parser_linkage_specification): Use
cp_parser_unevaluated_string_literal for C++26.
(cp_parser_static_assert): Likewise.
(cp_parser_std_attribute): Use uneval_string_attr for standard
deprecated and nodiscard attributes.
gcc/testsuite/
* g++.dg/cpp26/unevalstr1.C: New test.
* g++.dg/cpp26/unevalstr2.C: New test.
* g++.dg/cpp0x/udlit-error1.C (lol): Expect an error for C++26
about user-defined literal in deprecated attribute.
libcpp/
* include/cpplib.h (TTYPE_TABLE): Add CPP_UNEVAL_STRING literal
entry.  Use C++11 instead of C++-0x in comments.
* charset.cc (convert_escape): Add UNEVAL argument, if true,
pedantically diagnose numeric escape sequences.
(cpp_interpret_string_1): Formatting fix.  Adjust convert_escape
caller.
(cpp_interpret_string): Formatting string.
(cpp_interpret_string_notranslate): Pass type through to
cpp_interpret_string if it is CPP_UNEVAL_STRING.

--- gcc/cp/parser.cc.jj 2023-08-23 11:22:28.006593913 +0200
+++ gcc/cp/parser.cc2023-08-23 12:21:31.384232520 +0200
@@ -2267,7 +2267,8 @@ static vec *cp_parser_paren
   (cp_parser *, int, bool, bool, bool *, location_t * = NULL,
bool = false);
 /* Values for the second parameter of cp_parser_parenthesized_expression_list. 
 */
-enum { non_attr = 0, normal_attr = 1, id_attr = 2, assume_attr = 3 };
+enum { non_attr = 0, normal_attr = 1, id_attr = 2, assume_attr = 3,
+   uneval_string_attr = 4 };
 static void cp_parser_pseudo_destructor_name
   (cp_parser *, tree, tree *, tree *);
 static cp_expr cp_parser_unary_expression
@@ -4409,7 +4410,8 @@ cp_parser_identifier (cp_parser* parser)
 return error_mark_node;
 }
 
-/* Worker for cp_parser_string_literal and cp_parser_userdef_string_literal.
+/* Worker for cp_parser_string_literal, cp_parser_userdef_string_literal
+   and cp_parser_unevaluated_string_literal.
Do not call this directly; use either of the above.
 
Parse a sequence of adjacent string constants.  Return a
@@ -4417,7 +4419,8 @@ cp_parser_identifier (cp_parser* parser)
constant.  If TRANSLATE is true, translate the string to the
execution character set.  If WIDE_OK is true, a wide string is
valid here.  If UDL_OK is true, a string literal with user-defined
-   suffix can be used in this context.
+   suffix can be used in this context.  If UNEVAL is true, diagnose
+   numeric and conditional escape sequences in it if pedantic.
 
C++98 [lex.string] says that if a narrow string literal token is
adjacent to a wide string literal token, the behavior is undefined.
@@ -4431,7 +4434,7 @@ cp_parser_identifier (cp_parser* parser)
 static cp_expr
 cp_parser_string_literal_common (cp_parser *parser, bool translate,
 bool wide_ok, bool udl_ok,
-bool lookup_udlit)
+bool lookup_udlit, bool uneval)
 {
   tree value;
   size_t count;
@@ -4584,6 +4587,8 @@ cp_parser_string_literal_common (cp_pars
   cp_parser_error (parser, "a wide string is invalid in this context");
   type = CPP_STRING;
 }
+  if (uneval)
+type = CPP_UNEVAL_STRING;
 
   if ((translate ? cpp_interpret_string : cpp_interpret_string_notranslate)
   (parse_in, strs, 

Re: [PATCH V2 2/5] OpenMP: C front end support for imperfectly-nested loops

2023-08-24 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 22, 2023 at 12:53:19PM -0600, Sandra Loosemore wrote:
> > All these c-c++-common testsuite changes will now FAIL after the C patch but
> > before the C++.  It is nice to have the new c-c++-common tests in a separate
> > patch, but these tweaks which can't be just avoided need the temporary
> > { target c } vs. { target c++} hacks undone later in the C++ patch.
> 
> In spite of being in the c-c++-common subdirectory, this particular testcase
> is presently run only for C:
> 
> /* { dg-skip-if "not yet" { c++ } } */

Oh, sorry, I didn't think of such an possibility, it is just weird.
Please ignore my comments on this topic then.

Jakub



Patch ping Re: [PATCH 6/12] i386: Enable _BitInt on x86-64 [PR102989]

2023-08-23 Thread Jakub Jelinek via Gcc-patches
Hi!

Now that Richi has acked all the middle-end _BitInt patches (but am
deferring committing those until also the C FE and libgcc patches are
approved), I'd like to ping this patch.

Thanks!

On Wed, Aug 09, 2023 at 08:19:41PM +0200, Jakub Jelinek via Gcc-patches wrote:
> The following patch enables _BitInt support on x86-64, the only
> target which has _BitInt specified in psABI.
> 
> 2023-08-09  Jakub Jelinek  
> 
>   PR c/102989
>   * config/i386/i386.cc (classify_argument): Handle BITINT_TYPE.
>   (ix86_bitint_type_info): New function.
>   (TARGET_C_BITINT_TYPE_INFO): Redefine.

Jakub



Re: Intel AVX10.1 Compiler Design and Support

2023-08-23 Thread Jakub Jelinek via Gcc-patches
On Wed, Aug 23, 2023 at 08:03:58AM +, Jiang, Haochen wrote:
> We could first work on -mevex512 then further discuss -mavx10.1-256/512 since
> these -mavx10.1-256/512 is quite controversial.
> 
> Just to clarify, -mno-evex512 -mavx512f should not enable 512 bit vector 
> right?

I think it should enable them because -mavx512f is after it.  But it seems the
option handling is more complex than I thought, e.g. -mavx512bw -mno-avx512bw
just cancels each other, rather than
enabling AVX512BW, AVX512F, AVX2 and all its dependencies (like -mavx512bw
alone does) and then just disabling AVX512BW (like -mno-avx512bw does).
But, if one uses separate target pragmas, it behaves like that:
#pragma GCC target ("avx512bw")
#ifdef __AVX512F__
int a;
#endif
#ifdef __AVX512BW__
int b;
#endif
#pragma GCC target ("no-avx512bw")
#ifdef __AVX512F__
int c;
#endif
#ifdef __AVX512BW__
int d;
#endif
The above defines a, b and c vars even without any special -march= or other
command line option.

So, first important decision would be whether to make EVEX512
OPTION_MASK_ISA_EVEX512 or OPTION_MASK_ISA2_EVEX512, the former would need
to move some other ISA flag from the first to second set.
That OPTION_MASK_ISA*_EVEX512 then should be added to
OPTION_MASK_ISA_AVX512F_SET or OPTION_MASK_ISA2_AVX512F_SET (but, if it is
the latter, we also need to do that for tons of other AVX512*_SET),
and then just arrange for -mavx10.1-256 to enable
OPTION_MASK_ISA*_AVX512*_SET of everything it needs except the EVEX512 set
(but, only disable it from the newly added set, not actually act as
-mavx512{f,bw,...} -mno-evex512).
OPTION_MASK_ISA*_EVEX512_SET dunno, should it enable OPTION_MASK_ISA_AVX512F
or just EVEX512?
And then the UNSET cases...

Jakub



Re: Intel AVX10.1 Compiler Design and Support

2023-08-23 Thread Jakub Jelinek via Gcc-patches
On Wed, Aug 23, 2023 at 01:57:59AM +, Jiang, Haochen wrote:
> > > Let's assume there's no detla now, AVX10.1-512 is equal to
> > > AVX512{F,VL,BW,DQ,CD,BF16,FP16,VBMI,VBMI2,VNNI,IFMA,BITALG,VPOPCNTDQ}
> > > > other stuff.
> > > > The current common/config/i386/i386-common.cc OPTION_MASK_ISA*SET* 
> > > > would be
> > > > like now, except that the current AVX512* sets imply also 
> > > > EVEX512/whatever
> > > > it will be called, that option itself enables nothing (or 
> > > > TARGET_AVX512F),
> > > > and unsetting it doesn't disable all the TARGET_AVX512*.
> > > > -mavx10.1 would enable the AVX512* sets without EVEX512/whatever.
> > > So for -mavx512bw -mavx10.1-256, -mavx512bw will set EVEX512, but
> > > -mavx10.1-256 doesn't clear EVEX512 but just enable all AVX512* sets?.
> > > then the combination basically is equal to AVX10.1-512(AVX512* sets +
> > > EVEX512)
> > > If this is your assumption, yes, there's no need for TARGET_AVX10_1.
> 
> I think we still need that since the current w/o AVX512VL, we will not only
> enable 512 bit vector instructions but also enable scalar instructions, which
> means when it comes to -mavx512bw -mno-evex512, we should enable
> the scalar function.
> 
> And scalar functions will also be enabled in AVX10.1-256, we need something
> to distinguish them out from the ISA set w/o AVX512VL.

Ah, forgot about scalar instructions, even better, then we don't have to do
that special case.  So, I think TARGET_AVX512F && !TARGET_EVEX512 && 
!TARGET_AVX512VL
in general should disable 512-bit modes in ix86_hard_regno_mode_ok.  That
should prevent the need to replace TARGET_AVX512F to TARGET_EVEX512 on all
the patterns which refer to 512-bit modes.  Also wonder if it
wouldn't be easiest to make "v" constraint in that case be equivalent to
just "x" so that all those hacks to make xmm16+ registers working in various
instructions through g modifiers wouldn't trigger.  Sure, that would
penalize also scalar instructions, but the above case wouldn't be something
any CPU actually supports, it would be only the common subset of say XeonPhi
and AVX10.1-256.

Jakub



Re: [PATCH] libgomp, testsuite: Do not call nonstandard functions on darwin

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 22, 2023 at 10:25:51AM +0200, FX Coudert wrote:
> > Revised patch. I does the job on darwin, can you check that it still tests 
> > the functions on Linux?
> > And if so, OK to commit?
> 
> With the correct file, sorry.

Seems to work for me, I see
... -DNONSTDFUNC=1 ...
on the test's command line on linux and the test passes.
So ok.

Jakub



Re: Intel AVX10.1 Compiler Design and Support

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 22, 2023 at 10:35:55PM +0800, Hongtao Liu wrote:
> Let's assume there's no detla now, AVX10.1-512 is equal to
> AVX512{F,VL,BW,DQ,CD,BF16,FP16,VBMI,VBMI2,VNNI,IFMA,BITALG, VPOPCNTDQ}
> > other stuff.
> > The current common/config/i386/i386-common.cc OPTION_MASK_ISA*SET* would be
> > like now, except that the current AVX512* sets imply also EVEX512/whatever
> > it will be called, that option itself enables nothing (or TARGET_AVX512F),
> > and unsetting it doesn't disable all the TARGET_AVX512*.
> > -mavx10.1 would enable the AVX512* sets without EVEX512/whatever.
> So for -mavx512bw -mavx10.1-256, -mavx512bw will set EVEX512, but
> -mavx10.1-256 doesn't clear EVEX512 but just enable all AVX512* sets?.
> then the combination basically is equal to AVX10.1-512(AVX512* sets +
> EVEX512)
> If this is your assumption, yes, there's no need for TARGET_AVX10_1.

I think that would be my expectation.  -mavx512bw currently implies
512-bit vector support of avx512f and avx512bw, and with -mavx512{bw,vl}
also 128-bit/256-bit vector support.  All pre-AVX10 chips which do support
AVX512BW support 512-bit vectors.  Now, -mavx10.1 will bring in also
vl,dq,cd,bf16,fp16,vbmi,vbmi2,vnni,ifma,bitalg,vpopcntdq as you wrote
which weren't enabled before, but unless there is some existing or planned
CPU which would support 512-bit vectors in avx512f and avx512bw ISAs and
only support 128/256-bit vectors in those
dq,cd,bf16,fp16,vbmi,vbmi2,vnni,ifma,bitalg,vpopcntdq isas, I think there
is no need to differentiate further; the only CPUs which will support both
what -mavx512bw and -mavx10.1 requires will be (if there is no delta)
either CPUs with 128/256/512-bit vector support of those
f,vl,bw,dq,cd,...vpopcntdq ISAs, or AVX10.1-512 ISAs.
-mavx512vl -mavx512bw -mno-evex512 -mavx10.1-256 would on the other side
disable all 512-bit vector instructions and in the end just mean the
same as -mavx10.1-256.
For just
-mavx512bw -mno-evex512 -mavx10.1-256
the question is if that -mno-evex512 turns off also avx512bw/avx512f because
avx512vl isn't enabled at that point during processing, or if we do that
only at the end as a special case.  Of course, in this exact case there is
no difference, because -mavx10.1-256 turns that back on.
But it would make a difference on
-mavx512bw -mno-evex512 -mavx512vl
(when processed right away would disable AVX512BW (because VL isn't on)
and in the end enable VL,F including EVEX512, or be equivalent to just
-mavx512bw -mavx512vl if processed at the end, because -mavx512vl implied
-mevex512 again.

Jakub



Re: Intel AVX10.1 Compiler Design and Support

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 22, 2023 at 09:35:44PM +0800, Hongtao Liu wrote:
> Ok, then we can't avoid TARGET_AVX10_1 in those existing 256/128-bit
> evex instruction patterns.

Why?
Internally for md etc. purposes, we should have the current
TARGET_AVX512* etc. ISA flags, plus one new one, whatever we call it
(TARGET_EVEX512 even if it is not completely descriptive because of kandq
etc., or some other name) which says if 512-bit vector modes can be used,
if g modifier can be used, if the 64-bit mask operations can be used etc.
Plus, if AVX10.1 contains any instructions not covered in the preexisting
TARGET_AVX512* sets, TARGET_AVX10_1 which covers that delta, otherwise
keep -mavx10.1 just as an command line option which enables/disables
other stuff.
The current common/config/i386/i386-common.cc OPTION_MASK_ISA*SET* would be
like now, except that the current AVX512* sets imply also EVEX512/whatever
it will be called, that option itself enables nothing (or TARGET_AVX512F),
and unsetting it doesn't disable all the TARGET_AVX512*.
-mavx10.1 would enable the AVX512* sets without EVEX512/whatever.
At the end of the option processing, if EVEX512/whatever is set but
TARGET_AVX512VL is not, disable TARGET_AVX512F with all its dependencies,
because VL is a precondition of 128/256-bit EVEX and if 512-bit EVEX is not
enabled, there is nothing left.

Jakub



Re: [PATCH V2 5/5] OpenMP: Fortran support for imperfectly-nested loops

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Sun, Jul 23, 2023 at 04:15:21PM -0600, Sandra Loosemore wrote:
> OpenMP 5.0 removed the restriction that multiple collapsed loops must
> be perfectly nested, allowing "intervening code" (including nested
> BLOCKs) before or after each nested loop.  In GCC this code is moved
> into the inner loop body by the respective front ends.
> 
> In the Fortran front end, most of the semantic processing happens during
> the translation phase, so the parse phase just collects the intervening
> statements, checks them for errors, and splices them around the loop body.
> 
> gcc/fortran/ChangeLog
>   * gfortran.h (struct gfc_namespace): Add omp_structured_block bit.
>   * openmp.cc: Include omp-api.h.
>   (resolve_omp_clauses): Consolidate inscan reduction clause conflict
>   checking here.
>   (find_nested_loop_in_chain): New.
>   (find_nested_loop_in_block): New.
>   (gfc_resolve_omp_do_blocks): Set omp_current_do_collapse properly.
>   Handle imperfectly-nested loops when looking for nested omp scan.
>   Refactor to move inscan reduction clause conflict checking to
>   resolve_omp_clauses.
>   (gfc_resolve_do_iterator): Handle imperfectly-nested loops.
>   (struct icode_error_state): New.
>   (icode_code_error_callback): New.
>   (icode_expr_error_callback): New.
>   (diagnose_intervening_code_errors_1): New.
>   (diagnose_intervening_code_errors): New.
>   (make_structured_block): New.
>   (restructure_intervening_code): New.
>   (is_outer_iteration_variable): Do not assume loops are perfectly
>   nested.
>   (check_nested_loop_in_chain): New.
>   (check_nested_loop_in_block_state): New.
>   (check_nested_loop_in_block_symbol): New.
>   (check_nested_loop_in_block): New.
>   (expr_uses_intervening_var): New.
>   (is_intervening_var): New.
>   (expr_is_invariant): Do not assume loops are perfectly nested.
>   (resolve_omp_do): Handle imperfectly-nested loops.
>   * trans-stmt.cc (gfc_trans_block_construct): Generate
>   OMP_STRUCTURED_BLOCK if magic bit is set on block namespace.
> 
> gcc/testsuite/ChangeLog
>   * gfortran.dg/gomp/collapse1.f90: Adjust expected errors.
>   * gfortran.dg/gomp/collapse2.f90: Likewise.
>   * gfortran.dg/gomp/imperfect-gotos.f90: New.
>   * gfortran.dg/gomp/imperfect-invalid-scope.f90: New.
>   * gfortran.dg/gomp/imperfect1.f90: New.
>   * gfortran.dg/gomp/imperfect2.f90: New.
>   * gfortran.dg/gomp/imperfect3.f90: New.
>   * gfortran.dg/gomp/imperfect4.f90: New.
>   * gfortran.dg/gomp/imperfect5.f90: New.
> 
> libgomp/ChangeLog
>   * testsuite/libgomp.fortran/imperfect-destructor.f90: New.
>   * testsuite/libgomp.fortran/imperfect1.f90: New.
>   * testsuite/libgomp.fortran/imperfect2.f90: New.
>   * testsuite/libgomp.fortran/imperfect3.f90: New.
>   * testsuite/libgomp.fortran/imperfect4.f90: New.
>   * testsuite/libgomp.fortran/target-imperfect1.f90: New.
>   * testsuite/libgomp.fortran/target-imperfect2.f90: New.
>   * testsuite/libgomp.fortran/target-imperfect3.f90: New.
>   * testsuite/libgomp.fortran/target-imperfect4.f90: New.

LGTM, but please let Tobias have a second look unless he has done so
already.

Jakub



Re: [PATCH V2 4/5] OpenMP: New C/C++ testcases for imperfectly nested loops.

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Sun, Jul 23, 2023 at 04:15:20PM -0600, Sandra Loosemore wrote:
> gcc/testsuite/ChangeLog
>   * c-c++-common/gomp/imperfect-attributes.c: New.
>   * c-c++-common/gomp/imperfect-badloops.c: New.
>   * c-c++-common/gomp/imperfect-blocks.c: New.
>   * c-c++-common/gomp/imperfect-extension.c: New.
>   * c-c++-common/gomp/imperfect-gotos.c: New.
>   * c-c++-common/gomp/imperfect-invalid-scope.c: New.
>   * c-c++-common/gomp/imperfect-labels.c: New.
>   * c-c++-common/gomp/imperfect-legacy-syntax.c: New.
>   * c-c++-common/gomp/imperfect-pragmas.c: New.
>   * c-c++-common/gomp/imperfect1.c: New.
>   * c-c++-common/gomp/imperfect2.c: New.
>   * c-c++-common/gomp/imperfect3.c: New.
>   * c-c++-common/gomp/imperfect4.c: New.
>   * c-c++-common/gomp/imperfect5.c: New.
> 
> libgomp/ChangeLog
>   * testsuite/libgomp.c-c++-common/imperfect1.c: New.
>   * testsuite/libgomp.c-c++-common/imperfect2.c: New.
>   * testsuite/libgomp.c-c++-common/imperfect3.c: New.
>   * testsuite/libgomp.c-c++-common/imperfect4.c: New.
>   * testsuite/libgomp.c-c++-common/imperfect5.c: New.
>   * testsuite/libgomp.c-c++-common/imperfect6.c: New.
>   * testsuite/libgomp.c-c++-common/target-imperfect1.c: New.
>   * testsuite/libgomp.c-c++-common/target-imperfect2.c: New.
>   * testsuite/libgomp.c-c++-common/target-imperfect3.c: New.
>   * testsuite/libgomp.c-c++-common/target-imperfect4.c: New.

As I wrote in reply to the cover letter, I'd prefer the
ordered(2)/ordered(3) nests to have #pragma omp ordered doacross(source:)
and #pragma omp ordered doacross(sink: ...) directives and
use the libgomp scan-1.c as basis for the scan tests.
Otherwise LGTM.

Jakub



Re: [PATCH V2 3/5] OpenMP: C++ support for imperfectly-nested loops

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Sun, Jul 23, 2023 at 04:15:19PM -0600, Sandra Loosemore wrote:
> OpenMP 5.0 removed the restriction that multiple collapsed loops must
> be perfectly nested, allowing "intervening code" (including nested
> BLOCKs) before or after each nested loop.  In GCC this code is moved
> into the inner loop body by the respective front ends.
> 
> This patch changes the C++ front end to use recursive descent parsing
> on nested loops within an "omp for" construct, rather than an
> iterative approach, in order to preserve proper nesting of compound
> statements.  Preserving cleanups (destructors) for class objects
> declared in intervening code and loop initializers complicates moving
> the former into the body of the loop; this is handled by parsing the
> entire construct before reassembling any of it.
> 
> gcc/cp/ChangeLog
>   * cp-tree.h (cp_convert_omp_range_for): Adjust declaration.
>   * parser.cc (struct omp_for_parse_data): New.
>   (cp_parser_postfix_expression): Diagnose calls to OpenMP runtime
>   in intervening code.
>   (check_omp_intervening_code): New.
>   (cp_parser_statement_seq_opt): Special-case nested loops, blocks,
>   and other constructs for OpenMP loops.
>   (cp_parser_iteration_statement): Reject loops in intervening code.
>   (cp_parser_omp_for_loop_init): Expand comments and tweak the
>   interface slightly to better distinguish input/output parameters.
>   (cp_convert_omp_range_for): Likewise.
>   (cp_parser_omp_loop_nest): New, split from cp_parser_omp_for_loop
>   and largely rewritten.  Add more comments.
>   (insert_structured_blocks): New.
>   (find_structured_blocks): New.
>   (struct sit_data, substitute_in_tree_walker, substitute_in_tree):
>   New.
>   (fixup_blocks_walker): New.
>   (cp_parser_omp_for_loop): Rewrite to use recursive descent instead
>   of a loop.  Add logic to reshuffle the bits of code collected
>   during parsing so intervening code gets moved to the loop body.
>   (cp_parser_omp_loop): Remove call to finish_omp_for_block, which
>   is now redundant.
>   (cp_parser_omp_simd): Likewise.
>   (cp_parser_omp_for): Likewise.
>   (cp_parser_omp_distribute): Likewise.
>   (cp_parser_oacc_loop): Likewise.
>   (cp_parser_omp_taskloop): Likewise.
>   (cp_parser_pragma): Reject OpenMP pragmas in intervening code.
>   * parser.h (struct cp_parser): Add omp_for_parse_state field.
>   * pt.cc (tsubst_omp_for_iterator): Adjust call to
>   cp_convert_omp_range_for.
>   * semantics.cc (finish_omp_for): Try harder to preserve location
>   of loop variable init expression for use in diagnostics.
>   (struct fofb_data, finish_omp_for_block_walker): New.
>   (finish_omp_for_block): Allow variables to be bound in a BIND_EXPR
>   nested inside BIND instead of directly in BIND itself.
> 
> gcc/testsuite/ChangeLog
>   * c-c++-common/goacc/tile-2.c: Adjust expected error patterns.
>   * g++.dg/gomp/attrs-imperfect1.C: New test.
>   * g++.dg/gomp/attrs-imperfect2.C: New test.
>   * g++.dg/gomp/attrs-imperfect3.C: New test.
>   * g++.dg/gomp/attrs-imperfect4.C: New test.
>   * g++.dg/gomp/attrs-imperfect5.C: New test.
>   * g++.dg/gomp/pr41967.C: Adjust expected error patterns.
>   * g++.dg/gomp/tpl-imperfect-gotos.C: New test.
>   * g++.dg/gomp/tpl-imperfect-invalid-scope.C: New test.
> 
> libgomp/ChangeLog
>   * testsuite/libgomp.c++/attrs-imperfect1.C: New test.
>   * testsuite/libgomp.c++/attrs-imperfect2.C: New test.
>   * testsuite/libgomp.c++/attrs-imperfect3.C: New test.
>   * testsuite/libgomp.c++/attrs-imperfect4.C: New test.
>   * testsuite/libgomp.c++/attrs-imperfect5.C: New test.
>   * testsuite/libgomp.c++/attrs-imperfect6.C: New test.
>   * testsuite/libgomp.c++/imperfect-class-1.C: New test.
>   * testsuite/libgomp.c++/imperfect-class-2.C: New test.
>   * testsuite/libgomp.c++/imperfect-class-3.C: New test.
>   * testsuite/libgomp.c++/imperfect-destructor.C: New test.
>   * testsuite/libgomp.c++/imperfect-template-1.C: New test.
>   * testsuite/libgomp.c++/imperfect-template-2.C: New test.
>   * testsuite/libgomp.c++/imperfect-template-3.C: New test.

Ok (though, if the c-c++-common tests are tweaked in the C patch,
this patch needs to undo that).

Jakub



Re: [PATCH V2 2/5] OpenMP: C front end support for imperfectly-nested loops

2023-08-22 Thread Jakub Jelinek via Gcc-patches
> New common C/C++ testcases are in a separate patch.
> 
> gcc/c-family/ChangeLog
>   * c-common.h (c_omp_check_loop_binding_exprs): Declare.
>   * c-omp.cc: Include tree-iterator.h.
>   (find_binding_in_body): New.
>   (check_loop_binding_expr_r): New.
>   (LOCATION_OR): New.
>   (check_looop_binding_expr): New.
>   (c_omp_check_loop_binding_exprs): New.
> 
> gcc/c/ChangeLog
>   * c-parser.cc (struct c_parser): Add omp_for_parse_state field.
>   (struct omp_for_parse_data): New.
>   (check_omp_intervening_code): New.
>   (add_structured_block_stmt): New.
>   (c_parser_compound_statement_nostart): Recognize intervening code,
>   nested loops, and other things that need special handling in
>   OpenMP loop constructs.
>   (c_parser_while_statement): Error on loop in intervening code.
>   (c_parser_do_statement): Likewise.
>   (c_parser_for_statement): Likewise.
>   (c_parser_postfix_expression_after_primary): Error on calls to
>   the OpenMP runtime in intervening code.
>   (c_parser_pragma): Error on OpenMP pragmas in intervening code.
>   (c_parser_omp_loop_nest): New.
>   (c_parser_omp_for_loop): Rewrite to use recursive descent, calling
>   c_parser_omp_loop_nest to do the heavy lifting.
> 
> gcc/ChangeLog
>   * omp-api.h: New.
>   * omp-general.cc (omp_runtime_api_procname): New.
>   (omp_runtime_api_call): Moved here from omp-low.cc, and make
>   non-static.
>   * omp-general.h: Include omp-api.h.
>   * omp-low.cc (omp_runtime_api_call): Delete this copy.
> 
> gcc/testsuite/ChangeLog
>   * c-c++-common/goacc/collapse-1.c: Update for new C error behavior.
>   * c-c++-common/goacc/tile-2.c: Likewise.
>   * gcc.dg/gomp/collapse-1.c: Likewise.

> diff --git a/gcc/testsuite/c-c++-common/goacc/collapse-1.c 
> b/gcc/testsuite/c-c++-common/goacc/collapse-1.c
> index 11b14383983..0feac8f8ddb 100644
> --- a/gcc/testsuite/c-c++-common/goacc/collapse-1.c
> +++ b/gcc/testsuite/c-c++-common/goacc/collapse-1.c
> @@ -8,8 +8,8 @@ f1 (void)
>  {
>#pragma acc parallel
>#pragma acc loop collapse (2)
> -  for (i = 0; i < 5; i++)
> -;/* { dg-error "not enough 
> perfectly nested" } */
> +  for (i = 0; i < 5; i++)/* { dg-error "not enough nested loops" } */
> +;
>{
>  for (j = 0; j < 5; j++)
>;

All these c-c++-common testsuite changes will now FAIL after the C patch but
before the C++.  It is nice to have the new c-c++-common tests in a separate
patch, but these tweaks which can't be just avoided need the temporary
{ target c } vs. { target c++} hacks undone later in the C++ patch.

> --- a/gcc/testsuite/c-c++-common/goacc/tile-2.c
> +++ b/gcc/testsuite/c-c++-common/goacc/tile-2.c
> @@ -3,8 +3,8 @@ int main ()
>  #pragma acc parallel
>{
>  #pragma acc loop tile (*,*)
> -for (int ix = 0; ix < 30; ix++)
> -  ; /* { dg-error "not enough" } */
> +for (int ix = 0; ix < 30; ix++) /* { dg-error "not enough" "" { target c 
> } } */
> +  ; /* { dg-error "not enough" "" { target c++ } } */

E.g. like you do here.

Otherwise LGTM.

Jakub



Re: Intel AVX10.1 Compiler Design and Support

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 22, 2023 at 09:02:29PM +0800, Hongtao Liu wrote:
> > Agreed.  And I still think -mevex512 vs. -mno-evex512 is the best option
> > name to represent whether the effective ISA set allows 512-bit vectors or
> > not.  I think -mavx10.1 -mno-avx512cd should be fine.  And, -mavx10.1-256
> > option IMHO should be in the same spirit to all the others a positive 
> > enablement,
> > not both positive (enable avx512{f,cd,bw,dq,...} and negative (disallow
> > 512-bit vectors).  So, if one uses -mavx512f -mavx10.1-256, because the
> > former would allow 512-bit vectors, the latter shouldn't disable those again
> > because it isn't a -mno-* option.  Sure, instructions which are specific to
> But there's implicit negative (disallow 512-bit vector), I think

That is wrong.

> -mav512f -mavx10.1-256 or -mavx10.1-256 -mavx512f shouldn't enable
> 512-bit vector.

Because then the -mavx10.1-256 option behaves completely differently from
all the other isa options.

We have the -march= options which are processed separately, but the normal
ISA options either only enable something (when -mwhatever), or only disable 
something
(when -mno-whatever). -mavx512f -mavx10.1-256 should be a union of those
ISAs, like say -mavx2 -mbmi is, not an intersection or something even
harder to understand.

> Further, we should disallow a mix of exex512 and non-evex512 (e.g.
> -mavx10.1-512 -mavx10.2-256),they should be a unified separate switch
> that either disallows both or allows both. Instead of some isa
> allowing it and some isa disallowing it.

No, it will be really terrible user experience if the new options behave
completely differently from everything else.  Because then we'll need to
document it in detail how it behaves and users will have hard time to figure
it out, and specify what it does not just on the command line, but also when
mixing with target attribute or pragmas.  -mavx10.1-512 -mavx10.2-256 should
be a union of those two ISAs.  Either internally there is an ISA flag whether
the instructions in the avx10.2 ISA but not avx10.1 ISA can operate on
512-bit vectors or not, in that case -mavx10.1-512 -mavx10.2-256 should
enable the AVX10.1 set including 512-bit vectors + just the < 512-bit
instructions from the 10.1 to 10.2 delta, or if there is no such separation
internally, it will just enable full AVX10.2-512.  User has asked for it.

Jakub



Re: [PATCH V2 1/5] OpenMP: Add OMP_STRUCTURED_BLOCK and GIMPLE_OMP_STRUCTURED_BLOCK.

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Sun, Jul 23, 2023 at 04:15:17PM -0600, Sandra Loosemore wrote:
> In order to detect invalid jumps in and out of intervening code in
> imperfectly-nested loops, the front ends need to insert some sort of
> marker to identify the structured block sequences that they push into
> the inner body of the loop.  The error checking happens in the
> diagnose_omp_blocks pass, between gimplification and OMP lowering, so
> we need both GENERIC and GIMPLE representations of these markers.
> They are removed in OMP lowering so no subsequent passes need to know
> about them.
> 
> This patch doesn't include any front-end changes to generate the new
> data structures.
> 
> gcc/cp/ChangeLog
>   * constexpr.cc (cxx_eval_constant_expression): Handle
>   OMP_STRUCTURED_BLOCK.
>   * pt.cc (tsubst_expr): Likewise.
> 
> gcc/ChangeLog
>   * doc/generic.texi (OpenMP): Document OMP_STRUCTURED_BLOCK.
>   * doc/gimple.texi (GIMPLE instruction set): Add
>   GIMPLE_OMP_STRUCTURED_BLOCK.
>   (GIMPLE_OMP_STRUCTURED_BLOCK): New subsection.
>   * gimple-low.cc (lower_stmt): Error on GIMPLE_OMP_STRUCTURED_BLOCK.
>   * gimple-pretty-print.cc (dump_gimple_omp_block): Handle
>   GIMPLE_OMP_STRUCTURED_BLOCK.
>   (pp_gimple_stmt_1): Likewise.
>   * gimple-walk.cc (walk_gimple_stmt): Likewise.
>   * gimple.cc (gimple_build_omp_structured_block): New.
>   * gimple.def (GIMPLE_OMP_STRUCTURED_BLOCK): New.
>   * gimple.h (gimple_build_omp_structured_block): Declare.
>   (gimple_has_substatements): Handle GIMPLE_OMP_STRUCTURED_BLOCK.
>   (CASE_GIMPLE_OMP): Likewise.
>   * gimplify.cc (is_gimple_stmt): Handle OMP_STRUCTURED_BLOCK.
>   (gimplify_expr): Likewise.
>   * omp-expand.cc (GIMPLE_OMP_STRUCTURED_BLOCK): Error on
>   GIMPLE_OMP_STRUCTURED_BLOCK.
>   * omp-low.cc (scan_omp_1_stmt): Handle GIMPLE_OMP_STRUCTURED_BLOCK.
>   (lower_omp_1): Likewise.
>   (diagnose_sb_1): Likewise.
>   (diagnose_sb_2): Likewise.
>   * tree-inline.cc (remap_gimple_stmt): Handle
>   GIMPLE_OMP_STRUCTURED_BLOCK.
>   (estimate_num_insns): Likewise.
>   * tree-nested.cc (convert_nonlocal_reference_stmt): Likewise.
>   (convert_local_reference_stmt): Likewise.
>   (convert_gimple_call): Likewise.
>   * tree-pretty-print.cc (dump_generic_node): Handle
>   OMP_STRUCTURED_BLOCK.
>   * tree.def (OMP_STRUCTURED_BLOCK): New.
>   * tree.h (OMP_STRUCTURED_BLOCK_BODY): New.
> --- a/gcc/gimple-low.cc
> +++ b/gcc/gimple-low.cc
> @@ -717,6 +717,11 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data 
> *data)
>   gsi_next (gsi);
>return;
>  
> +case GIMPLE_OMP_STRUCTURED_BLOCK:
> +  /* These are supposed to be removed already in OMP lowering.  */
> +  gcc_unreachable ();
> +  break;

Please don't add break; after gcc_unreachable ();

> --- a/gcc/omp-expand.cc
> +++ b/gcc/omp-expand.cc
> @@ -10592,6 +10592,11 @@ expand_omp (struct omp_region *region)
>parent GIMPLE_OMP_SECTIONS region.  */
> break;
>  
> + case GIMPLE_OMP_STRUCTURED_BLOCK:
> +   /* We should have gotten rid of these in gimple lowering.  */
> +   gcc_unreachable ();
> +   break;

And here neither.

Otherwise LGTM.

Jakub



Re: [PATCH V2 0/5] OpenMP: support for imperfectly-nested loops

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Sun, Jul 23, 2023 at 04:15:16PM -0600, Sandra Loosemore wrote:
> Here is the latest version of my imperfectly-nested loops patches.
> Compared to the initial version I'd posted in April
> 
> https://gcc.gnu.org/pipermail/gcc-patches/2023-April/617103.html
> 
> this version includes many minor cosmetic fixes suggested by Jakub in
> his initial review (also present in the version I committed to the
> OG13 branch last month), many new test cases to cover various corner
> cases, and code fixes so that C and C++ at least behave consistently
> even if the spec is unclear.  The most intrusive of those fixes is
> that I couldn't figure out how to make jumping between different
> structured blocks of intervening code in the same OMP loop construct
> produce errors without introducing new GENERIC and GIMPLE data
> structures to represent a structured block without any other
> associated OpenMP semantics; that's now part 1 of the patch series.
> 
> There are a few things from the review comments I haven't done anything
> about:
> 
> * I left omp-api.h alone because the Fortran front end needs those
>   declarations without everything else in omp-general.h.

Ok.

> * I didn't think I ought to be speculatively implementing extensions
>   like allowing "do { ... } while (0);" in intervening code.  If it's
>   really important for supporting macros, I suppose it will make it
>   into a future version of the OpenMP spec.

Ack.

> * I didn't understand the comment about needing to add "#pragma omp
>   ordered doacross(source) and sink" to the testcase for errors with
>   the "ordered" clause.  Isn't that only for cross-iteration
>   data dependencies?  There aren't any in that loop.  Also note that some
>   of my new corner-case tests use the "ordered" clause to trigger an
>   error to check that things are being correctly parsed as intervening
>   code, so if there is something really bogus there that must be fixed,
>   it now affects other test cases as well.

ordered(N) clause is meant to be used with doacross loops, where one uses
#pragma omp ordered depend/doacross in the body.
So, when one is testing the rejection of imperfectly nested loops with it,
it is better to actually test it on something properly formed except for the
extra code making the loop imperfectly nested, rather than test it on
something which doesn't have the ordered directives in the body at all.

> * Likewise I didn't know what to do with coming up with a better
>   testcase for "scan".  I could not find an existing testcase with nested
>   loops that I could just add intervening code to, and when I made

What about libgomp.c-c++-common/scan-1.c ?
Obviously, you can cut the initialization and checking, because that is a
runtime testcase and all you need is a compile time test; perhaps put each
of the 2 loop nests into a separate function and just add some code in
between the loops + dg-error.

Jakub



[PATCH 14/12] libgcc _BitInt helper documentation [PR102989]

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Mon, Aug 21, 2023 at 05:32:04PM +, Joseph Myers wrote:
> I think the libgcc functions (i.e. those exported by libgcc, to which 
> references are generated by the compiler) need documenting in libgcc.texi.  
> Internal functions or macros in the libgcc patch need appropriate comments 
> specifying their semantics; especially FP_TO_BITINT and FP_FROM_BITINT 
> which have a lot of arguments and no comments saying what the semantics of 
> the macros and their arguments are supposed to me.

Here is an incremental patch which does that.

2023-08-22  Jakub Jelinek  

PR c/102989
gcc/
* doc/libgcc.texi (Bit-precise integer arithmetic functions):
Document general rules for _BitInt support library functions
and document __mulbitint3 and __divmodbitint4.
(Conversion functions): Document __fix{s,d,x,t}fbitint,
__floatbitint{s,d,x,t,h,b}f, __bid_fix{s,d,t}dbitint and
__bid_floatbitint{s,d,t}d.
libgcc/
* libgcc2.c (bitint_negate): Add function comment.
* soft-fp/bitint.h (bitint_negate): Add function comment.
(FP_TO_BITINT, FP_FROM_BITINT): Add comment explaining the macros.

--- gcc/doc/libgcc.texi.jj  2023-01-16 11:52:16.115733593 +0100
+++ gcc/doc/libgcc.texi 2023-08-22 12:35:08.561348126 +0200
@@ -218,6 +218,51 @@ These functions return the number of bit
 These functions return the @var{a} byteswapped.
 @end deftypefn
 
+@subsection Bit-precise integer arithmetic functions
+
+@code{_BitInt(@var{N})} library functions operate on arrays of limbs, where
+each limb has @code{__LIBGCC_BITINT_LIMB_WIDTH__} bits and the limbs are
+ordered according to @code{__LIBGCC_BITINT_ORDER__} ordering.  The most
+significant limb if @var{N} is not divisible by
+@code{__LIBGCC_BITINT_LIMB_WIDTH__} contains padding bits which should be
+ignored on read (sign or zero extended), but extended on write.  For the
+library functions, all bit-precise integers regardless of @var{N} are
+represented like that, even when the target ABI says that for some small
+@var{N} they should be represented differently in memory.  A pointer
+to the array of limbs argument is always accompanied with a bit size
+argument.  If that argument is positive, it is number of bits and the
+number is assumed to be zero-extended to infinite precision, if that
+argument is negative, it is negated number of bits above which all bits
+are assumed to be sign-extended to infinite precision.  These number of bits
+arguments don't need to match actual @var{N} for the operation used in the
+source, they could be lowered because of sign or zero extensions on the
+input or because value-range optimization figures value will need certain
+lower number of bits.  For big-endian ordering of limbs, when lowering
+the bit size argument the pointer argument needs to be adjusted as well.
+Negative bit size argument should be always smaller or equal to @code{-2},
+because @code{signed _BitInt(1)} is not valid.
+For output arguments, either the corresponding bit size argument should
+be always positive (for multiplication and division), or is negative when
+the output of conversion from floating-point value is signed and positive
+when unsigned.  The arrays of limbs output arguments point to should not
+overlap any inputs, while input arrays of limbs can overlap.
+@code{UBILtype} below stands for unsigned integer type with
+@code{__LIBGCC_BITINT_LIMB_WIDTH__} bit precision.
+
+@deftypefn {Runtime Function} void __mulbitint3 (@code{UBILtype} *@var{ret}, 
int32_t @var{retprec}, const @code{UBILtype} *u, int32_t @var{uprec}, const 
@code{UBILtype} *v, int32_t @var{vprec})
+This function multiplies bit-precise integer operands @var{u} and @var{v} and 
stores
+result into @var{retprec} precision bit-precise integer result @var{ret}.
+@end deftypefn
+
+@deftypefn {Runtime Function} void __divmodbitint4 (@code{UBILtype} *@var{q}, 
int32_t @var{qprec}, @code{UBILtype} *@var{r}, int32_t @var{rprec},  const 
@code{UBILtype} *u, int32_t @var{uprec}, const @code{UBILtype} *v, int32_t 
@var{vprec})
+This function divides bit-precise integer operands @var{u} and @var{v} and 
stores
+quotient into @var{qprec} precision bit-precise integer result @var{q}
+(unless @var{q} is @code{NULL} and @var{qprec} is 0, in that case quotient
+is not stored anywhere) and remainder into @var{rprec} precision bit-precise
+integer result @var{r} (similarly, unless @var{r} is @code{NULL} and 
@var{rprec}
+is 0).
+@end deftypefn
+
 @node Soft float library routines
 @section Routines for floating point emulation
 @cindex soft float library
@@ -384,6 +429,27 @@ These functions convert @var{i}, an unsi
 These functions convert @var{i}, an unsigned long long, to floating point.
 @end deftypefn
 
+@deftypefn {Runtime Function} void __fixsfbitint (@code{UBILtype} *@var{r}, 
int32_t @var{rprec}, float @var{a})
+@deftypefnx {Runtime Function} void __fixdfbitint (@code{UBILtype} *@var{r}, 
int32_t @var{rprec}, double @var{a})
+@deftypefnx 

Re: [OpenMP/offloading][RFC] How to handle target/device-specifics with C pre-processor (in general, inside 'omp declare variant')

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 22, 2023 at 10:43:54AM +0200, Tobias Burnus wrote:
> On 22.08.23 09:25, Richard Biener wrote:
> > On Mon, Aug 21, 2023 at 6:23 PM Tobias Burnus  
> > wrote:
> > > ...
> > Err, so the OMP standard doesn't put any constraints on what to allow 
> > inside the
> > variants?  Is declare variant always at the toplevel?
> 
> Actually, the OpenMP specification only states the following – which is less 
> than I claimed:
> 
> "If the context selector of a begin declare variant directive contains traits 
> in the device
> or implementation set that are known never to be compatible with an OpenMP 
> context during
> the current compilation, the preprocessed code that follows the begin declare 
> variant
> directive up to its paired end directive is elided."

The reason for the way how GCC implements the offloading is make sure the
layout of types/variables/functions is the same so that the host and
offloading side can actually interoperate.  I think it is much cleaner
design.
The unfortunate thing is that LLVM decided to do it differently, by separate
parsing/compilation for host cases and device cases.
That allows the various preprocessor games and the like, but on the other
side allows the user to make host vs. offloading inoperable - say #ifdefing
out some members of a struct, using different attributes which cause
different alignment and the like.  If source comes from a pipe, what do you
do so that you can preprocess multiple times?  The offloading compilation
still needs to be some weird hybrid of the offloading target and host target,
because e.g. the structure/variable layout/alignment etc. decisions need to
be done according to host target.
The worst thing is that the bad way LLVM decided to implement this later
leaks into the standard, where some people who propose new features just
don't think that it could be implemented differently and that results in
cases like the begin declare variant eliding what is in between.  It takes
time to adjust the wording so that it is acceptable even for the GCC way
of doing offloading and sometimes we aren't successful at it.
So, the long term question is if we should't give up and do it with separate
parsing as well.  But that would be a lot of work...

Jakub



Re: Intel AVX10.1 Compiler Design and Support

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 22, 2023 at 09:36:15AM +0200, Richard Biener via Gcc-patches wrote:
> I think internally we should have conditional 512bit support work across
> AVX512 and AVX10.
> 
> I also think it makes sense to _internally_ have AVX10.1 (10.1!) just
> enable the respective AVX512 features.  AVX10.2 would then internally
> cover the ISA extensions added in 10.2 only.  Both would reduce the
> redundancy and possibly make providing inter-operation between
> AVX10.1 (10.1!) and AVX512 to the user easier.  I see AVX 10.1 (10.1!)
> just as "re-branding" latest AVX512, so we should treat it that way
> (making it an alias to the AVX512 features).
> 
> Whether we want allow -mavx10.1 -mno-avx512cd or whether
> we only allow the "positive" -mavx512f -mavx512... (omitting avx512cd)
> is an entirely separate
> question.  But I think to not wreck the core idea (more interoperability,
> here between small/big cores) we absolutely have to
> provide a subset of avx10.1 but with disabled 512bit vectors which
> effectively means AVX512 with disabled 512bit support.

Agreed.  And I still think -mevex512 vs. -mno-evex512 is the best option
name to represent whether the effective ISA set allows 512-bit vectors or
not.  I think -mavx10.1 -mno-avx512cd should be fine.  And, -mavx10.1-256
option IMHO should be in the same spirit to all the others a positive 
enablement,
not both positive (enable avx512{f,cd,bw,dq,...} and negative (disallow
512-bit vectors).  So, if one uses -mavx512f -mavx10.1-256, because the
former would allow 512-bit vectors, the latter shouldn't disable those again
because it isn't a -mno-* option.  Sure, instructions which are specific to
AVX10.1 (aren't present in any currently existing AVX512* ISA set) might be
enabled only in 128/256 bit variants if we differentiate that level.
But, if one uses -mavx2 -mavx10.1-256, because no AVX512* has been enabled
it can enable all the AVX10.1 implied AVX512* parts without EVEX.512.

Jakub



Re: [PATCH] libgomp, testsuite: Do not call nonstandard functions on darwin

2023-08-22 Thread Jakub Jelinek via Gcc-patches
On Tue, Aug 22, 2023 at 10:16:37AM +0200, FX Coudert wrote:
> Revised patch. I does the job on darwin, can you check that it still tests 
> the functions on Linux?

Seems the attached patch doesn't match what was discussed in this thread.
And for that DWARF patch, I'd like to see what different output
you get on Darwin...

> And if so, OK to commit?

Jakub



[PATCH] doc: Remove obsolete sentence about _Float* not being supported in C++ [PR106652]

2023-08-22 Thread Jakub Jelinek via Gcc-patches
Hi!

As mentioned in the PR, these types are supported in C++ since GCC 13,
so we shouldn't confuse users.

Ok for trunk?

2023-08-22  Jakub Jelinek  

PR c++/106652
* doc/extend.texi (_Float): Drop obsolete sentence that the
types aren't supported in C++.

--- gcc/doc/extend.texi.jj  2023-08-18 09:33:45.738666727 +0200
+++ gcc/doc/extend.texi 2023-08-21 21:36:01.376269073 +0200
@@ -1084,7 +1084,7 @@ infinities, NaNs and negative zeros are
 ISO/IEC TS 18661-3:2015 defines C support for additional floating
 types @code{_Float@var{n}} and @code{_Float@var{n}x}, and GCC supports
 these type names; the set of types supported depends on the target
-architecture.  These types are not supported when compiling C++.
+architecture.
 Constants with these types use suffixes @code{f@var{n}} or
 @code{F@var{n}} and @code{f@var{n}x} or @code{F@var{n}x}.  These type
 names can be used together with @code{_Complex} to declare complex

Jakub



[PATCH] c++: Fix up mangling of function/block scope static structured bindings [PR111069]

2023-08-22 Thread Jakub Jelinek via Gcc-patches
Hi!

As can be seen on the testcase, we weren't correctly mangling
static/thread_local structured bindings (C++20 feature) at function/block
scope.  The following patch fixes that by using what write_local_name
does for those cases (note, structured binding mandling doesn't use the
standard path because it needs to pass a list of all the identifiers in
the structured binding to the mangling).  In addition to that it fixes
mangling of various helpers which use write_guarded_name (_ZGV*, _ZTH*,
_ZTW*) and kills find_decomp_unqualified_name which for the local names
would be too hard to implement and uses write_guarded_name for structured
binding related _ZGR* names as well.
All the mangled names on the testcase match now clang++ and my expectations.
Because the old mangled names were plain wrong (they mangled the same as
structured binding at global scope and resulted in assembly errors if there
was more than one static structured binding with the same identifiers in
the same (or another) function, I think we don't need to play with another
mangling ABI level which turns on/off the old broken way, unsure whether
we should backport the patch to 13 branch though.

BTW, I think we should also handle ABI tags in mangle_decomp which we
currently don't do, but guess that should be subject to another mangling ABI
version.
On
struct __attribute__((abi_tag ("foobar"))) S { int i; };
extern S a[2];
struct __attribute__((abi_tag ("qux"))) T { int i; S j; int k; };
extern T b[2];
namespace N { auto [i, j] = a; auto [k, l] = b; S c; T d; }
inline void foo () { static auto [m, n] = a; static auto [o, p] = b;
{ static auto [m, n] = a; ++n.i; } ++m.i; ++o.i; }
void (*p) () = 
clang++ uses
_ZN1NDC1i1jEB6foobarE
_ZN1NDC1k1lEB3quxE
_ZZ3foovEDC1m1nEB6foobar
_ZGVZ3foovEDC1m1nEB6foobar
_ZZ3foovEDC1o1pEB3qux
_ZGVZ3foovEDC1o1pEB3qux
_ZZ3foovEDC1m1nEB6foobar_0
_ZGVZ3foovEDC1m1nEB6foobar_0
mangling while g++ (with the patch):
_ZN1NDC1i1jEE
_ZN1NDC1k1lEE
_ZZ3foovEDC1m1nE
_ZGVZ3foovEDC1m1nE
_ZZ3foovEDC1o1pE
_ZGVZ3foovEDC1o1pE
_ZZ3foovEDC1m1nE_0
_ZGVZ3foovEDC1m1nE_0

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

2023-08-22  Jakub Jelinek  

PR c++/111069
* cp-tree.h (determine_local_discriminator): Add NAME argument with
NULL_TREE default.
* decl.cc (determine_local_discriminator): Add NAME argument, use it
if non-NULL, otherwise compute it the old way.
(cp_maybe_mangle_decomp): Call determine_local_discriminator.
* mangle.cc (find_decomp_unqualified_name): Remove.
(write_unqualified_name): Don't call find_decomp_unqualified_name.
(mangle_decomp): Handle mangling of static function/block scope
structured bindings.  Don't call decl_mangling_context twice.
(write_guarded_var_name): Handle structured bindings.
(mangle_ref_init_variable): Use write_guarded_var_name for structured
bindings.

* g++.dg/cpp2a/decomp8.C: New test.

--- gcc/cp/cp-tree.h.jj 2023-08-18 20:11:11.013692860 +0200
+++ gcc/cp/cp-tree.h2023-08-19 10:45:00.320543681 +0200
@@ -6858,7 +6858,7 @@ extern void pop_switch(void);
 extern void note_break_stmt(void);
 extern bool note_iteration_stmt_body_start (void);
 extern void note_iteration_stmt_body_end   (bool);
-extern void determine_local_discriminator  (tree);
+extern void determine_local_discriminator  (tree, tree = NULL_TREE);
 extern bool fns_correspond (tree, tree);
 extern int decls_match (tree, tree, bool = true);
 extern bool maybe_version_functions(tree, tree, bool);
--- gcc/cp/decl.cc.jj   2023-08-18 09:49:38.899871662 +0200
+++ gcc/cp/decl.cc  2023-08-19 10:52:11.74997 +0200
@@ -913,15 +913,16 @@ static GTY((deletable)) vec
generally very few of these in any particular function.  */
 
 void
-determine_local_discriminator (tree decl)
+determine_local_discriminator (tree decl, tree name)
 {
   auto_cond_timevar tv (TV_NAME_LOOKUP);
   retrofit_lang_decl (decl);
   tree ctx = DECL_CONTEXT (decl);
-  tree name = (TREE_CODE (decl) == TYPE_DECL
-  && TYPE_UNNAMED_P (TREE_TYPE (decl))
-  ? NULL_TREE : DECL_NAME (decl));
   size_t nelts = vec_safe_length (local_entities);
+  if (name == NULL_TREE)
+name = (TREE_CODE (decl) == TYPE_DECL
+   && TYPE_UNNAMED_P (TREE_TYPE (decl))
+   ? NULL_TREE : DECL_NAME (decl));
   for (size_t i = 0; i < nelts; i += 2)
 {
   tree *pair = &(*local_entities)[i];
@@ -9049,6 +9050,25 @@ cp_maybe_mangle_decomp (tree decl, tree
   tree d = first;
   for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d))
v[count - i - 1] = d;
+  if (DECL_FUNCTION_SCOPE_P (decl))
+   {
+ size_t sz = 3;
+ for (unsigned int i = 0; i < count; ++i)
+   sz += IDENTIFIER_LENGTH (DECL_NAME (v[i])) + 1;
+ char *name = XALLOCAVEC (char, 

  1   2   3   4   5   6   7   8   9   10   >