[PATCH] Add statistics counting to PHI-OPT

2021-06-10 Thread apinski--- via Gcc-patches
From: Andrew Pinski 

This should have been done before I started to work on connecting
PHI-OPT to match-and-simplify to see quickly if we miss anything
but it is better late than never.
Anyways there was no statistics counting in PHI-OPT before so adding
it is the right thing to do.

OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.

gcc/ChangeLog:

* tree-ssa-phiopt.c (replace_phi_edge_with_variable):
Add counting of how many times it is done.
(factor_out_conditional_conversion): Likewise.
(match_simplify_replacement): Likewise.
(value_replacement): Likewise.
(spaceship_replacement): Likewise.
(cond_store_replacement): Likewise.
(cond_if_else_store_replacement_1): Likewise.
(hoist_adjacent_loads): Likewise.
---
 gcc/tree-ssa-phiopt.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 76f4e7ec843..02e26f974a5 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -419,6 +419,8 @@ replace_phi_edge_with_variable (basic_block cond_block,
   gsi = gsi_last_bb (cond_block);
   gsi_remove (, true);
 
+  statistics_counter_event (cfun, "Replace PHI with variable", 1);
+
   if (dump_file && (dump_flags & TDF_DETAILS))
 fprintf (dump_file,
  "COND_EXPR in block %d and PHI in block %d converted to 
straightline code.\n",
@@ -618,6 +620,9 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi 
*phi,
   /* Remove the original PHI stmt.  */
   gsi = gsi_for_stmt (phi);
   gsi_remove (, true);
+
+  statistics_counter_event (cfun, "factored out cast", 1);
+
   return newphi;
 }
 
@@ -893,6 +898,11 @@ match_simplify_replacement (basic_block cond_bb, 
basic_block middle_bb,
 
   replace_phi_edge_with_variable (cond_bb, e1, phi, result);
 
+  /* Add Statistic here even though replace_phi_edge_with_variable already
+ does it as we want to be able to count when match-simplify happens vs
+ the others.  */
+  statistics_counter_event (cfun, "match-simplify PHI replacement", 1);
+
   /* Note that we optimized this PHI.  */
   return true;
 }
@@ -1196,6 +1206,8 @@ value_replacement (basic_block cond_bb, basic_block 
middle_bb,
}
   else
{
+ statistics_counter_event (cfun, "Replace PHI with 
variable/value_replacement", 1);
+
  /* Replace the PHI arguments with arg. */
  SET_PHI_ARG_DEF (phi, e0->dest_idx, arg);
  SET_PHI_ARG_DEF (phi, e1->dest_idx, arg);
@@ -2320,6 +2332,7 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
 
   gimple_stmt_iterator psi = gsi_for_stmt (phi);
   remove_phi_node (, true);
+  statistics_counter_event (cfun, "spaceship replacement", 1);
 
   return true;
 }
@@ -2982,6 +2995,7 @@ cond_store_replacement (basic_block middle_bb, 
basic_block join_bb,
   fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n");
   print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS);
 }
+  statistics_counter_event (cfun, "conditional store replacement", 1);
 
   return true;
 }
@@ -3056,6 +3070,8 @@ cond_if_else_store_replacement_1 (basic_block then_bb, 
basic_block else_bb,
   else
 gsi_insert_before (, new_stmt, GSI_NEW_STMT);
 
+  statistics_counter_event (cfun, "if-then-else store replacement", 1);
+
   return true;
 }
 
@@ -3469,6 +3485,7 @@ hoist_adjacent_loads (basic_block bb0, basic_block bb1,
   gsi_move_to_bb_end (, bb0);
   gsi2 = gsi_for_stmt (def2);
   gsi_move_to_bb_end (, bb0);
+  statistics_counter_event (cfun, "hoisted loads", 1);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
{
-- 
2.27.0



Re: [PATCH] c++: Failure to delay noexcept parsing with ptr-operator [PR100752]

2021-06-10 Thread Jason Merrill via Gcc-patches

On 6/10/21 5:19 PM, Marek Polacek wrote:

On Thu, Jun 10, 2021 at 03:09:29PM -0400, Jason Merrill wrote:

On 6/8/21 8:25 PM, Marek Polacek wrote:

We weren't passing 'flags' to the recursive call to cp_parser_declarator
in the ptr-operator case and as an effect, delayed parsing of noexcept
didn't work as advertised.  The following change passes more than just
CP_PARSER_FLAGS_DELAY_NOEXCEPT but that doesn't seem to break anything.

I'm not passing member_p because I don't need it and because it breaks
a few tests.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/branches?

PR c++/100752

gcc/cp/ChangeLog:

* parser.c (cp_parser_declarator): Pass flags down to
cp_parser_declarator.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/noexcept69.C: New test.
---
   gcc/cp/parser.c |  3 +--
   gcc/testsuite/g++.dg/cpp0x/noexcept69.C | 12 
   2 files changed, 13 insertions(+), 2 deletions(-)
   create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept69.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d59a829d0b9..5930990ec1c 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -22066,8 +22066,7 @@ cp_parser_declarator (cp_parser* parser,
cp_parser_parse_tentatively (parser);
 /* Parse the dependent declarator.  */
-  declarator = cp_parser_declarator (parser, dcl_kind,
-CP_PARSER_FLAGS_NONE,
+  declarator = cp_parser_declarator (parser, dcl_kind, flags,
 /*ctor_dtor_or_conv_p=*/NULL,
 /*parenthesized_p=*/NULL,
 /*member_p=*/false,


Should the other parameters also be passed down?  I'd think definitely
member_p and static_p, not sure about ctor_dtor_or_conv_p and
parenthesized_p.


Hmm, as I mentioned in the patch description, I tried, but passing member_p
broke a few tests and since it's not needed for this fix I gave up
investigating why.  I could look into it if you're curious :).


Please.

Jason



Re: [PATCH v2] c++: Extend std::is_constant_evaluated in if warning [PR100995]

2021-06-10 Thread Jason Merrill via Gcc-patches

On 6/10/21 7:04 PM, Marek Polacek wrote:

On Thu, Jun 10, 2021 at 10:27:44AM -0400, Jason Merrill wrote:

On 6/9/21 9:46 PM, Marek Polacek wrote:

Jakub pointed me at

which shows that our existing warning could be extended to handle more
cases.  This patch implements that.

A minor annoyance was handling macros, in libstdc++ we have

reference operator[](size_type __pos) {
__glibcxx_assert(__pos <= size());
...
}

wherein __glibcxx_assert expands to

if (__builtin_is_constant_evaluated() && !bool(__pos <= size())
  ...

but I'm of a mind to not warn on that.

Possible tweaks: merge the "always true" warnings and say something
about a manifestly evaluated context, and perhaps add an early exit
for TREE_CONSTANT trees because for constexpr if we are going to call
maybe_warn_for_constant_evaluated twice.

Once consteval if makes it in, we should tweak this warning one more
time.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

PR c++/100995

gcc/cp/ChangeLog:

* semantics.c (find_std_constant_evaluated_r): New.
(maybe_warn_for_constant_evaluated): New.
(finish_if_stmt_cond): Call it.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/is-constant-evaluated9.C: Add dg-warning.
* g++.dg/cpp2a/is-constant-evaluated12.C: New test.
---
   gcc/cp/semantics.c| 85 ---
   .../g++.dg/cpp2a/is-constant-evaluated12.C| 79 +
   .../g++.dg/cpp2a/is-constant-evaluated9.C |  4 +-
   3 files changed, 152 insertions(+), 16 deletions(-)
   create mode 100644 gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated12.C

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index f506a239864..07459a357e2 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -927,6 +927,75 @@ is_std_constant_evaluated_p (tree fn)
 return name && id_equal (name, "is_constant_evaluated");
   }
+/* Callback function for maybe_warn_for_constant_evaluated that looks
+   for calls to std::is_constant_evaluated in TP.  */
+
+static tree
+find_std_constant_evaluated_r (tree *tp, int *walk_subtrees, void *)
+{
+  tree t = *tp;
+
+  if (TYPE_P (t) || TREE_CONSTANT (t))
+{
+  *walk_subtrees = false;
+  return NULL_TREE;
+}
+
+  switch (TREE_CODE (t))
+{
+case CALL_EXPR:
+  if (is_std_constant_evaluated_p (t))
+   return t;
+  break;
+case EXPR_STMT:
+  /* Don't warn in statement expressions.  */
+  *walk_subtrees = false;
+  return NULL_TREE;
+default:
+  break;
+}
+
+  return NULL_TREE;
+}
+
+/* In certain contexts, std::is_constant_evaluated() is always true (for
+   instance, in a consteval function or in a constexpr if), or always false
+   (e.g., in a non-constexpr non-consteval function) so give the user a clue.  
*/
+
+static void
+maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if)
+{
+  if (!warn_tautological_compare)
+return;
+
+  /* Suppress warning for std::is_constant_evaluated if the conditional
+ comes from a macro.  */
+  if (from_macro_expansion_at (EXPR_LOCATION (cond)))
+return;
+
+  cond = cp_walk_tree_without_duplicates (, find_std_constant_evaluated_r,
+ NULL);
+  if (cond)
+{
+  if (constexpr_if)
+   warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
+   "% always evaluates to "
+   "true in %");
+  else if (!DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+  /* C++17 lambda op() is implicitly constexpr but finish_function
+ may not have marked it as such.  */
+  && !(cxx_dialect >= cxx17
+   && LAMBDA_TYPE_P (CP_DECL_CONTEXT (current_function_decl


Let's factor a new maybe_constexpr_fn out of var_in_maybe_constexpr_fn.


I've introduced maybe_constexpr_fn but I don't really see a way to
use it in var_in_maybe_constexpr_fn that would simplify things and
didn't change its semantics.
  

+   warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
+   "% always evaluates to "
+   "false in a non-% function");
+  else if (DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
+   warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
+   "% always evaluates to "
+   "true in a % function");
+}
+}
+
   /* Process the COND of an if-statement, which may be given by
  IF_STMT.  */
@@ -942,23 +1011,11 @@ finish_if_stmt_cond (tree cond, tree if_stmt)
 converted to bool.  */
 && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
   {
-  /* if constexpr (std::is_constant_evaluated()) is always true,
-so give the user a clue.  */
-  if (warn_tautological_compare)
-   {
- tree t = cond;
- if (TREE_CODE (t) == 

Re: GCC documentation: porting to Sphinx

2021-06-10 Thread Martin Sebor via Gcc-patches

On 6/10/21 7:18 AM, Martin Liška wrote:

On 6/10/21 11:07 AM, Martin Liška wrote:
Doing that, one has 2 unique links, that would be needed for get_option_url function. 

Plus, both :option:`-Wfoo` and :option:`-Wno-foo` references are going to work. 



And I've actually did the transformation and one can see it e.g. here:
https://splichal.eu/scripts/sphinx/gcc/_build/html/gcc-command-options/options-to-request-or-suppress-warnings.html#cmdoption-Wprio-ctor-dtor 


I find the style you have below right now clearer than keeping both
options in the same heading and adding a Note explaining the default
etc.  I.e., this

  _
  -Wchar-subscripts

Warn if an array subscript has type char. This is a common cause
of error, as programmers often forget that this type is signed on
some machines. This warning is enabled by -Wall.

  
  -Wno-char-subscripts

   Default option value for -Wchar-subscripts.

on this page right now:
https://splichal.eu/scripts/sphinx/gcc/_build/html/gcc-command-options/options-to-request-or-suppress-warnings.html#cmdoption-Wchar-subscripts 



seems better than this:

  _
  -Wno-shift-overflow, -Wshift-overflow=n, -Wshift-overflow

+--+
| (!) Note |
+---
| Default value is -Wno-shift-overflow, -Wshift-overflow is|
| enabled by -Wall.|
+--+

These options control warnings about left shift overflows.

and also better than the alternative with (non-default) after the option
in the heading.

https://splichal.eu/scripts/sphinx/demo/_build/html/#cmdoption-Wno-shift-overflow3

Martin




Martin




[PATCH 4/4] remove %G and %K support from pretty printer and -Wformat (PR 98512)

2021-06-10 Thread Martin Sebor via Gcc-patches

This final diff removes the handlers for %G and %K from the pretty
printer and the support for the directives from c-format.c so that
using them will be diagnosed.
gcc/c-family/ChangeLog:

	* c-format.c (gcc_tdiag_char_table): Remove support for %G and %K.
	 (gcc_cdiag_char_table): Same.
	 (gcc_cxxdiag_char_table): Same.

gcc/c/ChangeLog:

	* c-objc-common.c (c_tree_printer): Remove support for %G and %K.

gcc/cp/ChangeLog:

	* error.c (cp_printer):  Remove support for %G and %K.

gcc/ChangeLog:

	* gimple-pretty-print.c (percent_G_format): Remove.
	* tree-diagnostic.c (default_tree_printer): Remove calls.
	* tree-pretty-print.c (percent_K_format): Remove.
	* tree-pretty-print.h (percent_K_format): Remove.

gcc/testsuite/ChangeLog:

	* gcc.dg/format/gcc_diag-10.c: Update expected warnings.

diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index bda3b18fcd0..6fd0bb33d21 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -781,10 +781,6 @@ static const format_char_info gcc_tdiag_char_table[] =
   /* These will require a "tree" at runtime.  */
   { "DFTV", 1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "'",   NULL },
   { "E", 1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
-  { "K", 1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"",   NULL },
-
-  /* G requires a "gimple*" argument at runtime.  */
-  { "G", 1, STD_C89, { T89_G,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"",   NULL },
 
   { NULL,  0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
 };
@@ -799,10 +795,6 @@ static const format_char_info gcc_cdiag_char_table[] =
   /* These will require a "tree" at runtime.  */
   { "DFTV", 1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "'",   NULL },
   { "E",   1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
-  { "K",   1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"",   NULL },
-
-  /* G requires a "gimple*" argument at runtime.  */
-  { "G",   1, STD_C89, { T89_G,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"",   NULL },
 
   { "v",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q#",  "",   NULL },
 
@@ -819,10 +811,6 @@ static const format_char_info gcc_cxxdiag_char_table[] =
   /* These will require a "tree" at runtime.  */
   { "ADFHISTVX",1,STD_C89,{ T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+#",   "'",   NULL },
   { "E", 1,STD_C89,{ T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+#",   "",   NULL },
-  { "K", 1, STD_C89,{ T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   "\"",   NULL },
-
-  /* G requires a "gimple*" argument at runtime.  */
-  { "G", 1, STD_C89,{ T89_G,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   "\"",   NULL },
 
   /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.)  */
   { "CLOPQ",0,STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
diff --git a/gcc/c/c-objc-common.c b/gcc/c/c-objc-common.c
index b945de15ab8..cdb2242758e 100644
--- a/gcc/c/c-objc-common.c
+++ b/gcc/c/c-objc-common.c
@@ -247,8 +247,6 @@ print_type (c_pretty_printer *cpp, tree t, bool *quoted)
%D: a general decl,
%E: an identifier or expression,
%F: a function declaration,
-   %G: a Gimple statement,
-   %K: a CALL_EXPR,
%T: a type.
%V: a list of type qualifiers from a tree.
%v: an explicit list of type qualifiers
@@ -269,19 +267,6 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
   if (precision != 0 || wide)
 return false;
 
-  if (*spec == 'G')
-{
-  percent_G_format (text);
-  return true;
-}
-
-  if (*spec == 'K')
-{
-  t = va_arg (*text->args_ptr, tree);
-  percent_K_format (text, EXPR_LOCATION (t), TREE_BLOCK (t));
-  return true;
-}
-
   if (*spec != 'v')
 {
   t = va_arg (*text->args_ptr, tree);
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 4a89b348829..012a4ecddf4 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -4338,10 +4338,8 @@ defer_phase_2_of_type_diff (deferred_printed_type *deferred,
%D   declaration.
%E   expression.
%F   function declaration.
-   %G   gcall 

[PATCH 3/4] remove %K from error() calls in the aarch64/arm back ends (PR 98512)

2021-06-10 Thread Martin Sebor via Gcc-patches

This patch removes the uses of %K from error() calls in the aarch64
and arm back ends.  I tested this change only by building a cross-
compiler but I can't easily run the tests so I'd appreciate some help
validating it.  The fallout from the change should be limited to changes
to error messages so in the worst case it could be addressed after
committing the patch.
gcc/ChangeLog:

	* config/aarch64/aarch64-builtins.c (aarch64_simd_expand_builtin):
	Remove %K and use error_at.
	(aarch64_expand_fcmla_builtin): Same.
	(aarch64_expand_builtin_tme): Same.
	(aarch64_expand_builtin_memtag): Same.
	* config/arm/arm-builtins.c (arm_expand_acle_builtin): Same.
	(arm_expand_builtin): Same.
	* config/arm/arm.c (bounds_check): Same.

diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 3cab3ec992c..9ed4b72d005 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -1598,8 +1598,9 @@ constant_arg:
 	  if (!(*insn_data[icode].operand[opc].predicate)
 		  (op[opc], mode))
 	  {
-		error ("%Kargument %d must be a constant immediate",
-		   exp, opc + 1 - have_retval);
+		error_at (EXPR_LOCATION (exp),
+			  "argument %d must be a constant immediate",
+			  opc + 1 - have_retval);
 		return const0_rtx;
 	  }
 	  break;
@@ -1669,10 +1670,13 @@ aarch64_simd_expand_builtin (int fcode, tree exp, rtx target)
    / UINTVAL (elementsize),
   exp);
   else
-	error ("%Klane index must be a constant immediate", exp);
+	error_at (EXPR_LOCATION (exp),
+		  "lane index must be a constant immediate");
 	}
   else
-	error ("%Ktotal size and element size must be a non-zero constant immediate", exp);
+	error_at (EXPR_LOCATION (exp),
+		  "total size and element size must be a non-zero "
+		  "constant immediate");
   /* Don't generate any RTL.  */
   return const0_rtx;
 }
@@ -1828,7 +1832,8 @@ aarch64_expand_fcmla_builtin (tree exp, rtx target, int fcode)
   /* Validate that the lane index is a constant.  */
   if (!CONST_INT_P (lane_idx))
 {
-  error ("%Kargument %d must be a constant immediate", exp, 4);
+  error_at (EXPR_LOCATION (exp),
+		"argument %d must be a constant immediate", 4);
   return const0_rtx;
 }
 
@@ -1917,7 +1922,8 @@ aarch64_expand_builtin_tme (int fcode, tree exp, rtx target)
 	  emit_insn (GEN_FCN (CODE_FOR_tcancel) (op0));
 	else
 	  {
-	error ("%Kargument must be a 16-bit constant immediate", exp);
+	error_at (EXPR_LOCATION (exp),
+		  "argument must be a 16-bit constant immediate");
 	return const0_rtx;
 	  }
   }
@@ -2006,8 +2012,9 @@ aarch64_expand_builtin_memtag (int fcode, tree exp, rtx target)
 		  pat = GEN_FCN (icode) (target, op0, const0_rtx, op1);
 		  break;
 		}
-	  error ("%Kargument %d must be a constant immediate "
-		 "in range [0,15]", exp, 2);
+	  error_at (EXPR_LOCATION (exp),
+			"argument %d must be a constant immediate "
+			"in range [0,15]", 2);
 	  return const0_rtx;
 	}
 	  else
diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index fa0fb0b16ab..3a9ff8f26b8 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -3092,26 +3092,30 @@ constant_arg:
 			  unsigned int cp_bit = (CONST_INT_P (op[argc])
 		 ? UINTVAL (op[argc]) : -1);
 			  if (IN_RANGE (cp_bit, 0, ARM_CDE_CONST_COPROC))
-			error ("%Kcoprocessor %d is not enabled "
-   "with +cdecp%d", exp, cp_bit, cp_bit);
+			error_at (EXPR_LOCATION (exp),
+  "coprocessor %d is not enabled "
+  "with +cdecp%d", cp_bit, cp_bit);
 			  else
-			error ("%Kcoproc must be a constant immediate in "
-   "range [0-%d] enabled with +cdecp", exp,
-   ARM_CDE_CONST_COPROC);
+			error_at (EXPR_LOCATION (exp),
+  "coproc must be a constant immediate in "
+  "range [0-%d] enabled with +cdecp",
+  ARM_CDE_CONST_COPROC);
 			}
 		  else
 			/* Here we mention the builtin name to follow the same
 			   format that the C/C++ frontends use for referencing
 			   a given argument index.  */
-			error ("%Kargument %d to %qE must be a constant immediate "
-			   "in range [0-%d]", exp, argc + 1,
+			error_at (EXPR_LOCATION (exp),
+  "argument %d to %qE must be a constant "
+  "immediate in range [0-%d]", argc + 1,
 			   arm_builtin_decls[fcode],
 			   cde_builtin_data[fcode -
 			   ARM_BUILTIN_CDE_PATTERN_START].imm_max);
 		}
 		  else
-		error ("%Kargument %d must be a constant immediate",
-			   exp, argc + 1);
+		error_at (EXPR_LOCATION (exp),
+			  "argument %d must be a constant immediate",
+			  argc + 1);
 		  /* We have failed to expand the pattern, and are safely
 		 in to invalid code.  But the mid-end will still try to
 		 build an assignment for this node while it expands,
@@ -3328,11 +3332,13 @@ arm_expand_acle_builtin (int fcode, tree exp, rtx target)

[PATCH 2/4] remove %G and %K from calls in front end and middle end (PR 98512)

2021-06-10 Thread Martin Sebor via Gcc-patches

This diff removes the uses of %G and %K from all warning_at() calls
throughout GCC front end and middle end.  The inlining context is
included in diagnostic output whenever it's present.
Improve warning suppression for inlined functions.

Resolves:
PR middle-end/98871 - Cannot silence -Wmaybe-uninitialized at declaration site
PR middle-end/98512 - #pragma GCC diagnostic ignored ineffective in conjunction with alias attribute

gcc/ChangeLog:

	* builtins.c (warn_string_no_nul): Remove %G.
	(maybe_warn_for_bound): Same.
	(warn_for_access): Same.
	(check_access): Same.
	(check_strncat_sizes): Same.
	(expand_builtin_strncat): Same.
	(expand_builtin_strncmp): Same.
	(expand_builtin): Same.
	(expand_builtin_object_size): Same.
	(warn_dealloc_offset): Same.
	(maybe_emit_free_warning): Same.
	* calls.c (maybe_warn_alloc_args_overflow): Same.
	(maybe_warn_nonstring_arg): Same.
	(maybe_warn_rdwr_sizes): Same.
	* expr.c (expand_expr_real_1): Remove %K.
	* gimple-fold.c (gimple_fold_builtin_strncpy): Remove %G.
	(gimple_fold_builtin_strncat): Same.
	* gimple-ssa-sprintf.c (format_directive): Same.
	(handle_printf_call): Same.
	* gimple-ssa-warn-alloca.c (pass_walloca::execute): Same.
	* gimple-ssa-warn-restrict.c (maybe_diag_overlap): Same.
	(maybe_diag_access_bounds): Same.  Call gimple_location.
	(check_bounds_or_overlap): Same.
	* trans-mem.c (ipa_tm_scan_irr_block): Remove %K.  Simplify.
	* tree-ssa-ccp.c (pass_post_ipa_warn::execute): Remove %G.
	* tree-ssa-strlen.c (maybe_warn_overflow): Same.
	(maybe_diag_stxncpy_trunc): Same.
	(handle_builtin_stxncpy_strncat): Same.
	(maybe_warn_pointless_strcmp): Same.
	* tree-ssa-uninit.c (maybe_warn_operand): Same.

gcc/testsuite/ChangeLog:

	* gcc.dg/Wfree-nonheap-object-4.c: Tighten up.
	* gcc.dg/Wobjsize-1.c: Prune expected output.
	* gcc.dg/Warray-bounds-71.c: New test.
	* gcc.dg/Warray-bounds-71.h: New test.
	* gcc.dg/Warray-bounds-72.c: New test.
	* gcc.dg/Warray-bounds-73.c: New test.
	* gcc.dg/Warray-bounds-74.c: New test.
	* gcc.dg/Warray-bounds-75.c: New test.
	* gcc.dg/Wfree-nonheap-object-5.c: New test.
	* gcc.dg/pragma-diag-10.c: New test.
	* gcc.dg/pragma-diag-9.c: New test.
	* gcc.dg/uninit-suppress_3.c: New test.

diff --git a/gcc/builtins.c b/gcc/builtins.c
index af1fe49bb48..96997b7edc8 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1124,30 +1124,30 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname,
 	{
 	  if (wi::ltu_p (maxsiz, bndrng[0]))
 	warned = warning_at (loc, OPT_Wstringop_overread,
- "%K%qD specified bound %s exceeds "
+ "%qD specified bound %s exceeds "
  "maximum object size %E",
- expr, func, bndstr, maxobjsize);
+ func, bndstr, maxobjsize);
 	  else
 	{
 	  bool maybe = wi::to_wide (size) == bndrng[0];
 	  warned = warning_at (loc, OPT_Wstringop_overread,
    exact
-   ? G_("%K%qD specified bound %s exceeds "
+   ? G_("%qD specified bound %s exceeds "
 	"the size %E of unterminated array")
    : (maybe
-  ? G_("%K%qD specified bound %s may "
+  ? G_("%qD specified bound %s may "
 	   "exceed the size of at most %E "
 	   "of unterminated array")
-  : G_("%K%qD specified bound %s exceeds "
+  : G_("%qD specified bound %s exceeds "
 	   "the size of at most %E "
 	   "of unterminated array")),
-   expr, func, bndstr, size);
+   func, bndstr, size);
 	}
 	}
   else
 	warned = warning_at (loc, OPT_Wstringop_overread,
-			 "%K%qD argument missing terminating nul",
-			 expr, func);
+			 "%qD argument missing terminating nul",
+			 func);
 }
   else
 {
@@ -3967,35 +3967,34 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func,
 	warned = (func
 		  ? warning_at (loc, opt,
 (maybe
- ? G_("%K%qD specified bound %E may "
+ ? G_("%qD specified bound %E may "
 	  "exceed maximum object size %E")
- : G_("%K%qD specified bound %E "
+ : G_("%qD specified bound %E "
 	  "exceeds maximum object size %E")),
-exp, func, bndrng[0], maxobjsize)
+func, bndrng[0], maxobjsize)
 		  : warning_at (loc, opt,
 (maybe
- ? G_("%Kspecified bound %E may "
+ ? G_("specified bound %E may "
 	  "exceed maximum object size %E")
- : G_("%Kspecified bound %E "
+ : G_("specified bound %E "
 	  "exceeds maximum object size %E")),
-exp, bndrng[0], maxobjsize));
+bndrng[0], maxobjsize));
 	  else
 	warned = (func
 		  ? warning_at (loc, opt,
 (maybe
- ? G_("%K%qD specified bound [%E, %E] may "
+ ? G_("%qD specified bound [%E, %E] may "
 	  "exceed maximum object size %E")
- : G_("%K%qD specified bound [%E, %E] "
+ : G_("%qD specified bound [%E, %E] "
 	  "exceeds maximum object size %E")),
-exp, func,
-bndrng[0], bndrng[1], maxobjsize)
+func, bndrng[0], bndrng[1], maxobjsize)
 		 

[PATCH 1/4] introduce diagnostic infrastructure changes (PR 98512)

2021-06-10 Thread Martin Sebor via Gcc-patches

This diff introduces the diagnostic infrastructure changes to support
controlling warnings at any call site in the inlining stack and printing
the inlining context without the %K and %G directives.
Improve warning suppression for inlined functions.

Resolves:
PR middle-end/98871 - Cannot silence -Wmaybe-uninitialized at declaration site
PR middle-end/98512 - #pragma GCC diagnostic ignored ineffective in conjunction with alias attribute

gcc/ChangeLog:

	* diagnostic.c (update_inlining_context): New.
	(update_effective_level_from_pragmas): Handle inlining context.
	(diagnostic_report_diagnostic): Same.
	* diagnostic.h (struct diagnostic_info): Add ctor.
	(struct diagnostic_context): Add members.
	* tree-diagnostic.c (get_inlining_locations): New.
	(set_inlining_location): New.
	(tree_diagnostics_defaults): Set new callback pointers.

diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index d58586f2526..d1c8c655f7a 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -991,51 +991,92 @@ print_parseable_fixits (pretty_printer *pp, rich_location *richloc,
   pp_set_prefix (pp, saved_prefix);
 }
 
-/* Update the diag_class of DIAGNOSTIC based on its location
-   relative to any
+/* Update the inlininig context in CONTEXT for a DIAGNOSTIC.  */
+
+static void
+update_inlining_context (diagnostic_context *context,
+			 diagnostic_info *diagnostic)
+{
+  context->ictx.reset ();
+
+  auto  = context->ictx.ilocs;
+
+  if (context->get_locations_cb)
+/* Retrieve the locations into which the expression about to be
+   diagnosed has been inlined, including those of all the callers
+   all the way down the inlining stack.  */
+context->get_locations_cb (context, diagnostic);
+  else
+{
+  /* When there's no metadata use just the one location provided
+	 by the caller of the diagnostic function.  */
+  location_t loc = diagnostic_location (diagnostic);
+  ilocs.safe_push (loc);
+  context->ictx.allsyslocs = in_system_header_at (loc);
+}
+}
+
+/* Update the kind of DIAGNOSTIC based on its location(s), including
+   any of those in its inlining context, relative to any
  #pragma GCC diagnostic
directives recorded within CONTEXT.
 
-   Return the new diag_class of DIAGNOSTIC if it was updated, or
-   DK_UNSPECIFIED otherwise.  */
+   Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED
+   otherwise.  */
 
 static diagnostic_t
 update_effective_level_from_pragmas (diagnostic_context *context,
  diagnostic_info *diagnostic)
 {
-  diagnostic_t diag_class = DK_UNSPECIFIED;
-
-  if (context->n_classification_history > 0)
+  if (context->ictx.allsyslocs && !context->dc_warn_system_headers)
 {
-  location_t location = diagnostic_location (diagnostic);
+  /* Ignore the diagnostic if all the inlined locations are
+	 in system headers and -Wno-system-headers is in effect.  */
+  diagnostic->kind = DK_IGNORED;
+  return DK_IGNORED;
+}
+
+  if (context->n_classification_history <= 0)
+return DK_UNSPECIFIED;
+
+  auto  = context->ictx.ilocs;
 
+  /* Iterate over the locations, checking the diagnostic disposition
+ for the diagnostic at each.  If it's explicitly set as opposed
+ to unspecified, update the disposition for this instance of
+ the diagnostic and return it.  */
+  for (unsigned idx = 0; idx < ilocs.length (); ++idx)
+{
   /* FIXME: Stupid search.  Optimize later. */
   for (int i = context->n_classification_history - 1; i >= 0; i --)
 	{
-	  if (linemap_location_before_p
-	  (line_table,
-	   context->classification_history[i].location,
-	   location))
+	  const diagnostic_classification_change_t 
+	= context->classification_history[i];
+
+	  location_t pragloc = hist.location;
+	  if (!linemap_location_before_p (line_table, pragloc, ilocs[idx]))
+	continue;
+
+	  if (hist.kind == (int) DK_POP)
 	{
-	  if (context->classification_history[i].kind == (int) DK_POP)
-		{
-		  i = context->classification_history[i].option;
-		  continue;
-		}
-	  int option = context->classification_history[i].option;
-	  /* The option 0 is for all the diagnostics.  */
-	  if (option == 0 || option == diagnostic->option_index)
-		{
-		  diag_class = context->classification_history[i].kind;
-		  if (diag_class != DK_UNSPECIFIED)
-		diagnostic->kind = diag_class;
-		  break;
-		}
+	  /* Move on to the next region.  */
+	  i = hist.option;
+	  continue;
+	}
+
+	  int option = hist.option;
+	  /* The option 0 is for all the diagnostics.  */
+	  if (option == 0 || option == diagnostic->option_index)
+	{
+	  diagnostic_t kind = hist.kind;
+	  if (kind != DK_UNSPECIFIED)
+		diagnostic->kind = kind;
+	  return kind;
 	}
 	}
 }
 
-  return diag_class;
+  return DK_UNSPECIFIED;
 }
 
 /* Generate a URL string describing CWE.  The caller is responsible for
@@ -1129,6 +1170,9 @@ static bool
 diagnostic_enabled (diagnostic_context *context,
 		

[PATCH 0/4] improve warning suppression for inlined functions (PR 98512)

2021-06-10 Thread Martin Sebor via Gcc-patches

David, this is a revised patch set based on your feedback below
and our discussion.  It works with the existing warning_at()
interface without introducing any new overloads (for now).  It
resolves PR middle-end/98871 and 98512.  PR 98465 was handled
in GCC 11 differently so this has no impact on that problem
anymore.

The first diff in the series introduces the diagnostic
infrastructure changes.

The second one removes the uses of %G and %K from all warning_at()
calls throughout GCC front end and middle end.  The inlining context
is included in diagnostic output whenever it's present.

The third removes the uses of %K from error() calls in the arm and
aarch64 back end.

The fourth and final diff then removes the handlers from the pretty
printer and the support for the directives from c-format.c.

On 5/19/21 7:41 AM, David Malcolm wrote:

On Thu, 2021-01-21 at 16:46 -0700, Martin Sebor via Gcc-patches wrote:

Martin and I had a chat about this patch, but it's best to discuss code
on the mailing list rather than in a silo, so here goes...



The initial patch I posted is missing initialization for a couple
of locals.  I'd noticed it in testing but forgot to add the fix to
the patch before posting it.  I have corrected that in the updated
revision and also added the test case from pr98512, and retested
the whole thing on x86_64-linux.

On 1/19/21 11:58 AM, Martin Sebor wrote:

std::string tends to trigger a class of false positive out of bounds
access warnings for code GCC cannot prove is unreachable because of
missing aliasing constrains, and that ends up expanded inline into
user code.  Simply inserting the contents of a constant char array
does that.  In GCC 10 these false positives are suppressed due to
-Wno-system-headers, but in GCC 11, to help detect calls rendered
invalid by user code passing in either incorrect or insufficiently
constrained arguments, -Wno-system-header no longer has this effect
on invalid access warnings.

To solve the problem without at least partially reverting the change
and going back to the GCC 10 way of things for the affected subset
of calls (just memcpy and memmove), the attached patch enhances
the #pragma GCC diagnostic machinery to consider not just a single
location for inlined code but all locations at which an expression
and its callers are inlined all the way up the stack.  This gives
each author of a function involved in inlining the ability to
control a warning issued for the code, not just the user into whose
code all the calls end up inlined.  To resolve PR 98465, it lets us
suppress the false positives selectively in std::string rather
than across the board in GCC.


I like the idea of checking the whole of the inlining stack for
pragmas, but I don't like the way the patch implements it.

The patch provides a hook for getting a vec of locations for a
diagnostic for use when checking for pragmas, and uses it the hook on a
few specific diagnostics.

Why wouldn’t we always do this?  It seems to me like something we
should always do when there's inlining information associated with a
location, rather than being a per-diagnostic thing - but maybe there's
something I'm missing here.  The patch adds diag_inlining_context
instances on the stack in various places, and doing that feels to me
like a special-case hack, when it should be fixed more generally in
diagnostics.c

I don't like attaching the "override the location" hook to the
diagnostic_metadata; I intended the latter to be about diagnostic
taxonomies (CWE, coding standards, etc), rather than a place to stash
location overrides.

One issue is that the core of the diagnostics subsystem doesn't have
knowledge of "tree", but the inlining information requires tree-ish
knowledge.

It's still possible to get at the inlining information from the
diagnostics.c, but only as a void *:

input.h's has:

#define LOCATION_BLOCK(LOC) \
   ((tree) ((IS_ADHOC_LOC (LOC)) ? get_data_from_adhoc_loc (line_table,
(LOC)) \
: NULL))

Without knowing about "tree", diagnostic.c could still query a
location_t to get at the data as a void *:

   if (IS_ADHOC_LOC (loc)
 return get_data_from_adhoc_loc (line_table, loc);
   else
 return NULL;


If we make the "get all the pertinent locations" hook a part of the
diagnostic_context, we could have diagnostic_report_diagnostic check to
see if there's ad-hoc data associated with the location and a non-NULL
hook on the context, and if so, call it.  This avoids adding an
indirect call for the common case where there isn't any inlining
information, and lets us stash the implementation of the hook in the
tree-diagnostic.c, keeping the separation of trees from diagnostic.c

One design question here is: what if there are multiple pragmas on the
inlining stack, e.g. explicitly enabling a warning at one place, and
explicitly ignoring that warning in another?  I don't think it would
happen in the cases you're interested in, but it seems worth
considering.  Perhaps the closest place to the user's 

Re: [PATCH v2] c++: Extend std::is_constant_evaluated in if warning [PR100995]

2021-06-10 Thread Marek Polacek via Gcc-patches
On Thu, Jun 10, 2021 at 10:27:44AM -0400, Jason Merrill wrote:
> On 6/9/21 9:46 PM, Marek Polacek wrote:
> > Jakub pointed me at
> > 
> > which shows that our existing warning could be extended to handle more
> > cases.  This patch implements that.
> > 
> > A minor annoyance was handling macros, in libstdc++ we have
> > 
> >reference operator[](size_type __pos) {
> >__glibcxx_assert(__pos <= size());
> >...
> >}
> > 
> > wherein __glibcxx_assert expands to
> > 
> >if (__builtin_is_constant_evaluated() && !bool(__pos <= size())
> >  ...
> > 
> > but I'm of a mind to not warn on that.
> > 
> > Possible tweaks: merge the "always true" warnings and say something
> > about a manifestly evaluated context, and perhaps add an early exit
> > for TREE_CONSTANT trees because for constexpr if we are going to call
> > maybe_warn_for_constant_evaluated twice.
> > 
> > Once consteval if makes it in, we should tweak this warning one more
> > time.
> > 
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > 
> > PR c++/100995
> > 
> > gcc/cp/ChangeLog:
> > 
> > * semantics.c (find_std_constant_evaluated_r): New.
> > (maybe_warn_for_constant_evaluated): New.
> > (finish_if_stmt_cond): Call it.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/cpp2a/is-constant-evaluated9.C: Add dg-warning.
> > * g++.dg/cpp2a/is-constant-evaluated12.C: New test.
> > ---
> >   gcc/cp/semantics.c| 85 ---
> >   .../g++.dg/cpp2a/is-constant-evaluated12.C| 79 +
> >   .../g++.dg/cpp2a/is-constant-evaluated9.C |  4 +-
> >   3 files changed, 152 insertions(+), 16 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated12.C
> > 
> > diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
> > index f506a239864..07459a357e2 100644
> > --- a/gcc/cp/semantics.c
> > +++ b/gcc/cp/semantics.c
> > @@ -927,6 +927,75 @@ is_std_constant_evaluated_p (tree fn)
> > return name && id_equal (name, "is_constant_evaluated");
> >   }
> > +/* Callback function for maybe_warn_for_constant_evaluated that looks
> > +   for calls to std::is_constant_evaluated in TP.  */
> > +
> > +static tree
> > +find_std_constant_evaluated_r (tree *tp, int *walk_subtrees, void *)
> > +{
> > +  tree t = *tp;
> > +
> > +  if (TYPE_P (t) || TREE_CONSTANT (t))
> > +{
> > +  *walk_subtrees = false;
> > +  return NULL_TREE;
> > +}
> > +
> > +  switch (TREE_CODE (t))
> > +{
> > +case CALL_EXPR:
> > +  if (is_std_constant_evaluated_p (t))
> > +   return t;
> > +  break;
> > +case EXPR_STMT:
> > +  /* Don't warn in statement expressions.  */
> > +  *walk_subtrees = false;
> > +  return NULL_TREE;
> > +default:
> > +  break;
> > +}
> > +
> > +  return NULL_TREE;
> > +}
> > +
> > +/* In certain contexts, std::is_constant_evaluated() is always true (for
> > +   instance, in a consteval function or in a constexpr if), or always false
> > +   (e.g., in a non-constexpr non-consteval function) so give the user a 
> > clue.  */
> > +
> > +static void
> > +maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if)
> > +{
> > +  if (!warn_tautological_compare)
> > +return;
> > +
> > +  /* Suppress warning for std::is_constant_evaluated if the conditional
> > + comes from a macro.  */
> > +  if (from_macro_expansion_at (EXPR_LOCATION (cond)))
> > +return;
> > +
> > +  cond = cp_walk_tree_without_duplicates (, 
> > find_std_constant_evaluated_r,
> > + NULL);
> > +  if (cond)
> > +{
> > +  if (constexpr_if)
> > +   warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
> > +   "% always evaluates to "
> > +   "true in %");
> > +  else if (!DECL_DECLARED_CONSTEXPR_P (current_function_decl)
> > +  /* C++17 lambda op() is implicitly constexpr but finish_function
> > + may not have marked it as such.  */
> > +  && !(cxx_dialect >= cxx17
> > +   && LAMBDA_TYPE_P (CP_DECL_CONTEXT (current_function_decl
> 
> Let's factor a new maybe_constexpr_fn out of var_in_maybe_constexpr_fn.

I've introduced maybe_constexpr_fn but I don't really see a way to
use it in var_in_maybe_constexpr_fn that would simplify things and
didn't change its semantics.
 
> > +   warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
> > +   "% always evaluates to "
> > +   "false in a non-% function");
> > +  else if (DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
> > +   warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
> > +   "% always evaluates to "
> > +   "true in a % function");
> > +}
> > +}
> > +
> >   /* Process the COND of an if-statement, which may be given by
> >  IF_STMT.  */
> > @@ -942,23 +1011,11 @@ 

Re: Aligning stack offsets for spills

2021-06-10 Thread Jeff Law via Gcc-patches




On 6/8/2021 8:55 AM, Jakub Jelinek wrote:

On Tue, Jun 08, 2021 at 08:47:26AM -0600, Jeff Law wrote:

Why is the machinery involving STACK_SLOT_ALIGNMENT and
spill_slot_alignment() (for spilling) or get_stack_local_alignment() (for
backing stack slots) not working for you?  If everything is setup
correctly the input alignment to try_fit_stack_local ought to be correct
already.

We don't need the MEM as a whole aligned, just the offset in the address
calculation due to how we encode those instructions.  If I've read that code
correctly, it would arrange for a dynamic realignment of the stack  so that
it could then align the slot. None of that is necessary for us and we'd like
to avoid forcing the dynamic stack realignment.  Or did I misread the code?

I think dynamic stack realignment is done only on x86, no other backend has
that support, on all the other arches larger alignments are done
in expand_stack_vars by effectively performing __builtin_alloca_with_align
for the block containing all such variables.
So I'd the the functions Michael mentioned shouldn't be doing dynamic stack
realignment, though perhaps by pretending the vars have higher alignment
might be recorded in MEM_ALIGN and perhaps might result in wrong-code if
something will try to e.g. test if least significant bits of certain MEM
address are 0.
Hmm, I thought we'd do a dynamic realignment, if that's not the case 
then we've got another approach to consider.


Thanks everyone...

jeff


Re: [PATCH] libgccjit: add some reflection functions in the jit C api

2021-06-10 Thread David Malcolm via Gcc-patches
On Thu, 2021-05-27 at 21:51 -0400, Antoni Boucher wrote:
> I chose option A, so everything is a size_t, now.
> I also renamed the dyncast functions.
> Here's the new patch.

Thanks, sorry again about the delays in reviewing your work.

You didn't specify how you tested the patch; are you running the full
jit regression test suite?

This is looking close to done; a few nits inline below:

[...snip...]

> diff --git a/gcc/jit/docs/topics/functions.rst 
> b/gcc/jit/docs/topics/functions.rst
> index b2d9239aa0a..1d20e3045a0 100644
> --- a/gcc/jit/docs/topics/functions.rst
> +++ b/gcc/jit/docs/topics/functions.rst

[...snip...]

> +   The API entrypoints relating to getting info about parameters and return
> +   types:
> +
> +  * :c:func:`gcc_jit_function_get_return_type`
> +
> +  * :c:func:`gcc_jit_function_get_param_count`
> +
> +   were added in :ref:`LIBGCCJIT_ABI_15`; you can test for their presence
> +   using

16, rather than 15.

> +   The API entrypoints related to the reflection API:
> +
> +  * :c:func:`gcc_jit_function_type_get_return_type`
> +

[...snip...]

> +
> +  * :c:func:`gcc_jit_struct_get_field_count`
> +
> +   were added in :ref:`LIBGCCJIT_ABI_15`; you can test for their presence
> +   using

16, rather than 15 again.

> +
> +   .. code-block:: c
> +
> +  #ifdef LIBGCCJIT_HAVE_REFLECTION
> +
> +   .. type:: gcc_jit_case

[...snip...]

> +gcc_jit_type *
> +gcc_jit_function_type_get_param_type (gcc_jit_function_type *function_type,
> + size_t index)
> +{
> +  RETURN_NULL_IF_FAIL (function_type, NULL, NULL, "NULL function_type");
> +  size_t num_params = function_type->get_param_types ().length ();
> +  gcc::jit::recording::context *ctxt = function_type->m_ctxt;
> +  RETURN_NULL_IF_FAIL_PRINTF3 (index < num_params,
> +ctxt, NULL,
> +"index of %ld is too large (%s has %ld params)",
> +index,
> +function_type->get_debug_string (),
> +num_params);
> +  return (gcc_jit_type *)function_type->get_param_types ()[index];
> +}
> +

I'm retaining the above, since...

[...snip...]

>  
> +
> +/* Public entrypoint.  See description in libgccjit.h.
> +
> +   After error-checking, the real work is done by the
> +   gcc::jit::recording::fields::get_field method in
> +   jit-recording.c.  */
> +extern gcc_jit_field *
> +gcc_jit_struct_get_field (gcc_jit_struct *struct_type,
> +size_t index)
> +{
> +  RETURN_NULL_IF_FAIL (struct_type, NULL, NULL, "NULL struct type");
> +  RETURN_NULL_IF_FAIL (struct_type->get_fields (), NULL, NULL,
> + "NULL struct fields");
> +  RETURN_NULL_IF_FAIL ((int) index < struct_type->get_fields ()->length (),
> + NULL, NULL, "NULL struct type");

...copy error here; the message for this kind of failure needs
updating.  Do it in a similar way to how you did
gcc_jit_function_type_get_param_type above, using the ctxt of the
struct_type.

[...snip...]

> +#define LIBGCCJIT_HAVE_REFLECTION
> +
> +/* Reflection functions to get the number of parameters, return type of
> +   a function and whether a type is a bool from the C API.
> +
> +   This API entrypoint was added in LIBGCCJIT_ABI_15; you can test for its

16, rather than 15, again.

> +   presence using
> + #ifdef LIBGCCJIT_HAVE_REFLECTION

[...snip...]

OK for trunk with the above nits fixed, assuming that you have run the
full regression test suite (or do you need help with that?)

I can't remember, sorry, do you have push rights to the gcc git
repository?

Do you have a preference as to which patch you want me to look at next?
Otherwise I'll go through them in the order in
https://github.com/antoyo/rustc_codegen_gcc/tree/master/gcc-patches

Dave




[PATCH] i386: Add V8QI and other 64bit vector permutations [PR89021]

2021-06-10 Thread Uros Bizjak via Gcc-patches
In addition to V8QI permutations, several other missing permutations are
added for 64bit vector modes for TARGET_SSSE3 and TARGET_SSE4_1 targets.

2021-06-10  Uroš Bizjak  

gcc/
PR target/89021
* config/i386/i386-expand.c (ix86_split_mmx_punpck):
Handle V2SF mode.  Emit SHUFPS to fixup unpack-high for V2SF mode.
(expand_vec_perm_blend): Handle 64bit modes for TARGET_SSE4_1.
(expand_vec_perm_pshufb): Handle 64bit modes for TARGET_SSSE3.
(expand_vec_perm_pblendv): Handle 64bit modes for TARGET_SSE4_1.
(expand_vec_perm_interleave2): Handle 64bit modes.
(expand_vec_perm_even_odd_pack): Handle V8QI mode.
(expand_vec_perm_even_odd_1): Ditto.
(ix86_vectorize_vec_perm_const): Ditto.
* config/i386/i386.md (UNSPEC_PSHUFB): Move from ...
* config/i386/sse.md: ... here.
* config/i386/mmx.md (*vec_interleave_lowv2sf):
New insn_and_split pattern.
(*vec_interleave_highv2sf): Ditto.
(mmx_pshufbv8qi3): New insn pattern.
(*mmx_pblendw): Ditto.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Pushed to master.

Uros.
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index c3ce21b4387..9ee5257adf9 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -798,6 +798,15 @@ ix86_split_mmx_punpck (rtx operands[], bool high_p)
  GEN_INT (1), GEN_INT (5)));
   break;
 
+case E_V2SFmode:
+  sse_mode = V4SFmode;
+  double_sse_mode = V8SFmode;
+  mask = gen_rtx_PARALLEL (VOIDmode,
+  gen_rtvec (4,
+ GEN_INT (0), GEN_INT (4),
+ GEN_INT (1), GEN_INT (5)));
+  break;
+
 default:
   gcc_unreachable ();
 }
@@ -812,14 +821,26 @@ ix86_split_mmx_punpck (rtx operands[], bool high_p)
   rtx insn = gen_rtx_SET (dest, op2);
   emit_insn (insn);
 
+  /* Move bits 64:127 to bits 0:63.  */
   if (high_p)
 {
-  /* Move bits 64:127 to bits 0:63.  */
-  mask = gen_rtx_PARALLEL (VOIDmode,
-  gen_rtvec (4, GEN_INT (2), GEN_INT (3),
- GEN_INT (0), GEN_INT (0)));
-  dest = lowpart_subreg (V4SImode, dest, GET_MODE (dest));
-  op1 = gen_rtx_VEC_SELECT (V4SImode, dest, mask);
+  if (sse_mode == V4SFmode)
+   {
+ mask = gen_rtx_PARALLEL (VOIDmode,
+  gen_rtvec (4, GEN_INT (2), GEN_INT (3),
+ GEN_INT (4), GEN_INT (5)));
+ op2 = gen_rtx_VEC_CONCAT (V8SFmode, dest, dest);
+ op1 = gen_rtx_VEC_SELECT (V4SFmode, op2, mask);
+   }
+  else
+   {
+ mask = gen_rtx_PARALLEL (VOIDmode,
+  gen_rtvec (4, GEN_INT (2), GEN_INT (3),
+ GEN_INT (0), GEN_INT (1)));
+ dest = lowpart_subreg (V4SImode, dest, GET_MODE (dest));
+ op1 = gen_rtx_VEC_SELECT (V4SImode, dest, mask);
+   }
+
   insn = gen_rtx_SET (dest, op1);
   emit_insn (insn);
 }
@@ -17062,7 +17083,8 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
 ;
   else if (TARGET_AVX && (vmode == V4DFmode || vmode == V8SFmode))
 ;
-  else if (TARGET_SSE4_1 && GET_MODE_SIZE (vmode) == 16)
+  else if (TARGET_SSE4_1 && (GET_MODE_SIZE (vmode) == 16
+|| GET_MODE_SIZE (vmode) == 8))
 ;
   else
 return false;
@@ -17095,6 +17117,7 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
 case E_V8SFmode:
 case E_V2DFmode:
 case E_V4SFmode:
+case E_V4HImode:
 case E_V8HImode:
 case E_V8SImode:
 case E_V32HImode:
@@ -17111,6 +17134,12 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
   vmode = V8HImode;
   goto do_subreg;
 
+case E_V2SImode:
+  for (i = 0; i < 2; ++i)
+   mask |= (d->perm[i] >= 2 ? 3 : 0) << (i * 2);
+  vmode = V4HImode;
+  goto do_subreg;
+
 case E_V4SImode:
   for (i = 0; i < 4; ++i)
mask |= (d->perm[i] >= 4 ? 3 : 0) << (i * 2);
@@ -17132,7 +17161,9 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
vperm = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (nelt, rperm));
vperm = force_reg (vmode, vperm);
 
-   if (GET_MODE_SIZE (vmode) == 16)
+   if (GET_MODE_SIZE (vmode) == 8)
+ emit_insn (gen_mmx_pblendvb64 (target, op0, op1, vperm));
+   else if (GET_MODE_SIZE (vmode) == 16)
  emit_insn (gen_sse4_1_pblendvb (target, op0, op1, vperm));
else
  emit_insn (gen_avx2_pblendvb (target, op0, op1, vperm));
@@ -17152,6 +17183,16 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
   op1 = gen_lowpart (vmode, op1);
   break;
 
+case E_V8QImode:
+  for (i = 0; i < 8; i += 2)
+   if (d->perm[i] + 1 != d->perm[i + 1])
+ goto use_pblendvb;
+
+  for (i = 

libgo patch committed: Update libgo to Go 1.16.5

2021-06-10 Thread Ian Lance Taylor via Gcc-patches
This patch updates libgo to the Go 1.16.5 release.  Bootstrapped and
tested on x86_64-pc-linux-gnu.  Committed to tip and GCC 11 branch.

Ian
a7d86ad16c5afdbbbae5218c012e1bbf6966bf1d
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 1f38c9110ba..f16fb9facc3 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-5a801b15699cced5203af5c7339b375cd55ecbac
+bcafcb3c39530bb325514d6377747eb3127d1a03
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/MERGE b/libgo/MERGE
index 81cd0623486..ac842716022 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-9baddd3f21230c55f0ad2a10f5f20579dcf0a0bb
+7677616a263e8ded606cc8297cb67ddc667a876e
 
 The first line of this file holds the git revision number of the
 last merge done from the master library sources.
diff --git a/libgo/VERSION b/libgo/VERSION
index e592dfd1338..e336ec201bf 100644
--- a/libgo/VERSION
+++ b/libgo/VERSION
@@ -1 +1 @@
-go1.16.3
+go1.16.5
diff --git a/libgo/go/archive/zip/reader.go b/libgo/go/archive/zip/reader.go
index c288ad965bc..ddef2b7b5a5 100644
--- a/libgo/go/archive/zip/reader.go
+++ b/libgo/go/archive/zip/reader.go
@@ -99,7 +99,15 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
return err
}
z.r = r
-   z.File = make([]*File, 0, end.directoryRecords)
+   // Since the number of directory records is not validated, it is not
+   // safe to preallocate z.File without first checking that the specified
+   // number of files is reasonable, since a malformed archive may
+   // indicate it contains up to 1 << 128 - 1 files. Since each file has a
+   // header which will be _at least_ 30 bytes we can safely preallocate
+   // if (data size / 30) >= end.directoryRecords.
+   if (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
+   z.File = make([]*File, 0, end.directoryRecords)
+   }
z.Comment = end.comment
rs := io.NewSectionReader(r, 0, size)
if _, err = rs.Seek(int64(end.directoryOffset), io.SeekStart); err != 
nil {
@@ -628,10 +636,11 @@ func (b *readBuf) sub(n int) readBuf {
 }
 
 // A fileListEntry is a File and its ename.
-// If file == nil, the fileListEntry describes a directory, without metadata.
+// If file == nil, the fileListEntry describes a directory without metadata.
 type fileListEntry struct {
-   name string
-   file *File // nil for directories
+   name  string
+   file  *File
+   isDir bool
 }
 
 type fileInfoDirEntry interface {
@@ -640,20 +649,26 @@ type fileInfoDirEntry interface {
 }
 
 func (e *fileListEntry) stat() fileInfoDirEntry {
-   if e.file != nil {
+   if !e.isDir {
return headerFileInfo{}
}
return e
 }
 
 // Only used for directories.
-func (f *fileListEntry) Name() string   { _, elem, _ := split(f.name); 
return elem }
-func (f *fileListEntry) Size() int64{ return 0 }
-func (f *fileListEntry) ModTime() time.Time { return time.Time{} }
-func (f *fileListEntry) Mode() fs.FileMode  { return fs.ModeDir | 0555 }
-func (f *fileListEntry) Type() fs.FileMode  { return fs.ModeDir }
-func (f *fileListEntry) IsDir() bool{ return true }
-func (f *fileListEntry) Sys() interface{}   { return nil }
+func (f *fileListEntry) Name() string  { _, elem, _ := split(f.name); 
return elem }
+func (f *fileListEntry) Size() int64   { return 0 }
+func (f *fileListEntry) Mode() fs.FileMode { return fs.ModeDir | 0555 }
+func (f *fileListEntry) Type() fs.FileMode { return fs.ModeDir }
+func (f *fileListEntry) IsDir() bool   { return true }
+func (f *fileListEntry) Sys() interface{}  { return nil }
+
+func (f *fileListEntry) ModTime() time.Time {
+   if f.file == nil {
+   return time.Time{}
+   }
+   return f.file.FileHeader.Modified.UTC()
+}
 
 func (f *fileListEntry) Info() (fs.FileInfo, error) { return f, nil }
 
@@ -673,15 +688,32 @@ func toValidName(name string) string {
 func (r *Reader) initFileList() {
r.fileListOnce.Do(func() {
dirs := make(map[string]bool)
+   knownDirs := make(map[string]bool)
for _, file := range r.File {
+   isDir := len(file.Name) > 0 && 
file.Name[len(file.Name)-1] == '/'
name := toValidName(file.Name)
for dir := path.Dir(name); dir != "."; dir = 
path.Dir(dir) {
dirs[dir] = true
}
-   r.fileList = append(r.fileList, fileListEntry{name, 
file})
+   entry := fileListEntry{
+   name:  name,
+   file:  file,
+   isDir: isDir,
+   }
+   r.fileList = append(r.fileList, entry)
+   if isDir {

Re: Aligning stack offsets for spills

2021-06-10 Thread Segher Boessenkool
On Thu, Jun 10, 2021 at 02:28:34PM -0500, Peter Bergner via Gcc-patches wrote:
> On 6/7/21 2:00 PM, Jeff Law wrote:
> > I can't divulge many of the details right now, but one of the quirks of our
> > architecture is that reg+d addressing modes for our vector loads/stores 
> > require
> > the displacement to be aligned.  This is an artifact of how these 
> > instructions
> > are encoded.
> 
> Given what you're describing, it sounds like POWER has something similar.
> Our reg+displacement addressing uses 16-bit displacements using D, DS or DQ
> operand fields.  The D field encodes the entire 16-bits, but the DS and DQ
> fields only encode 14-bits and 12-bits respectively.

Yes, the low 2 resp. 4 bits of the offset are used for other things in
the instruction encoding for DS and DQ.

> The DS and DQ operands
> have the same maximum displacement as D operands, we just force that their
> bottom 2-bits/4-bits must be zero, so we don't need to include them in the
> insn encoding.  I believe this is all just handled in our legitimate address
> routines, but maybe Segher and/or Mike can correct me if I'm wrong?

This is all correct.  But probably the main thing is that our ABIs
require most things to be naturally aligned (up to 16 bytes).  The
machines do not require that (anymore), but requiring this in the ABI
still is a performance win afaics (and a lot easier for (compiler)
implementers -- most issues you describe just disappear ;-) )

Something tells me this won't work for you though?


Segher


Re: [PATCH] c++: Failure to delay noexcept parsing with ptr-operator [PR100752]

2021-06-10 Thread Marek Polacek via Gcc-patches
On Thu, Jun 10, 2021 at 03:09:29PM -0400, Jason Merrill wrote:
> On 6/8/21 8:25 PM, Marek Polacek wrote:
> > We weren't passing 'flags' to the recursive call to cp_parser_declarator
> > in the ptr-operator case and as an effect, delayed parsing of noexcept
> > didn't work as advertised.  The following change passes more than just
> > CP_PARSER_FLAGS_DELAY_NOEXCEPT but that doesn't seem to break anything.
> > 
> > I'm not passing member_p because I don't need it and because it breaks
> > a few tests.
> > 
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/branches?
> > 
> > PR c++/100752
> > 
> > gcc/cp/ChangeLog:
> > 
> > * parser.c (cp_parser_declarator): Pass flags down to
> > cp_parser_declarator.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/cpp0x/noexcept69.C: New test.
> > ---
> >   gcc/cp/parser.c |  3 +--
> >   gcc/testsuite/g++.dg/cpp0x/noexcept69.C | 12 
> >   2 files changed, 13 insertions(+), 2 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept69.C
> > 
> > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> > index d59a829d0b9..5930990ec1c 100644
> > --- a/gcc/cp/parser.c
> > +++ b/gcc/cp/parser.c
> > @@ -22066,8 +22066,7 @@ cp_parser_declarator (cp_parser* parser,
> > cp_parser_parse_tentatively (parser);
> > /* Parse the dependent declarator.  */
> > -  declarator = cp_parser_declarator (parser, dcl_kind,
> > -CP_PARSER_FLAGS_NONE,
> > +  declarator = cp_parser_declarator (parser, dcl_kind, flags,
> >  /*ctor_dtor_or_conv_p=*/NULL,
> >  /*parenthesized_p=*/NULL,
> >  /*member_p=*/false,
> 
> Should the other parameters also be passed down?  I'd think definitely
> member_p and static_p, not sure about ctor_dtor_or_conv_p and
> parenthesized_p.

Hmm, as I mentioned in the patch description, I tried, but passing member_p
broke a few tests and since it's not needed for this fix I gave up
investigating why.  I could look into it if you're curious :).
 
Marek



Re: [PATCH][version 3]add -ftrivial-auto-var-init and variable attribute "uninitialized" to gcc

2021-06-10 Thread Qing Zhao via Gcc-patches
Hi, Richard,

I need more discussion on the following comments you raised:

> On May 26, 2021, at 6:18 AM, Richard Biener  wrote:
> 
> +/* Expand the IFN_DEFERRED_INIT function according to its second 
> argument.  */
> +static void
> +expand_DEFERRED_INIT (internal_fn, gcall *stmt)
> +{
> +  tree var = gimple_call_lhs (stmt);
> +  tree init = NULL_TREE;
> +  enum auto_init_type init_type
> += (enum auto_init_type) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1));
> +
> +  switch (init_type)
> +{
> +default:
> +  gcc_unreachable ();
> +case AUTO_INIT_PATTERN:
> +  init = build_pattern_cst_for_auto_init (TREE_TYPE (var));
> +  expand_assignment (var, init, false);
> +  break;
> +case AUTO_INIT_ZERO:
> +  init = build_zero_cst (TREE_TYPE (var));
> +  expand_assignment (var, init, false);
> +  break;
> +}
> 
> I think actually building build_pattern_cst_for_auto_init can generate
> massive garbage and for big auto vars code size is also a concern and
> ideally on x86 you'd produce rep movq.  So I don't think going
> via expand_assignment is good.  Instead you possibly want to lower
> .DEFERRED_INIT to MEMs following expand_builtin_memset and
> eventually enhance that to allow storing pieces larger than a byte.

When I tried to lower .DEFERRED_INIT to MEMs for  “AUTO_INIT_PATTERN”, I have 
the following questions:

1. If .DEFERRED_INIT will be lowered to MEMS through “memset”, then we 
basically initialize the whole memory covering the
auto variable, including paddings. Right?
2. Only when the value that is used to initialization has a repeated 
byte-pattern, we can lower it through “memset”. Otherwise,
If the value that is used to initialization does Not have a repeated 
byte-pattern, we can NOT lower it through “memset”, right?

Currently, for the values that are used to initialize for “AUTO_INIT_PATTERN”, 
we have:

  /* The following value is a guaranteed unmappable pointer value and has a
 repeated byte-pattern which makes it easier to synthesize.  We use it for
 pointers as well as integers so that aggregates are likely to be
 initialized with this repeated value.  */
  uint64_t largevalue = 0xull;
  /* For 32-bit platforms it's a bit trickier because, across systems, only the
 zero page can reasonably be expected to be unmapped, and even then we need
 a very low address.  We use a smaller value, and that value sadly doesn't
 have a repeated byte-pattern.  We don't use it for integers.  */
  uint32_t smallvalue = 0x00AA;

In additional to the above, for BOOLEAN_TYPE:

case BOOLEAN_TYPE:
  /* We think that initializing the boolean variable to 0 other than 1
 is better even for pattern initialization.  */

Due to “BOOLEAN_TYPE” and “POINTER_TYPE”,  we cannot always have a repeated 
byte-pattern for variables that include BOOLEAN_TYPE
Or Pointer types. Therefore, lowering the .DEFERRED_INIT for “PATTERN” 
initialization through “memset” is not always possible. 

Let me know if I miss anything in the above. Do you have other suggestions?

thanks.

Qing



Re: [PATCH] rs6000: Add new __builtin_vsx_build_pair and __builtin_mma_build_acc built-ins

2021-06-10 Thread Segher Boessenkool
On Thu, Jun 10, 2021 at 10:43:05AM -0500, Peter Bergner wrote:
> On 6/9/21 4:38 PM, Segher Boessenkool wrote:
> > I think this reads simpler as
> >   /* The ASSEMBLE builtin source operands are reversed in little-endian
> >  mode, so reorder them.  */
> >   if (fcode == VSX_BUILTIN_ASSEMBLE_PAIR_INTERNAL && !WORDS_BIG_ENDIAN)
> > std::swap (op[1], op[2]);
> >   pat = GEN_FCN (icode) (op[0], op[1], op[2]);
> > do you agree?
> 
> Do I think C++ is simpler than plain C?  Is this a trick question? ;-)

I *like* std::swap.  It is one of the few C++ things that is clearly
nice: it gives nice, unsurprising semantics, for nice, unsurprising
syntax, and it does exactly what you expect, and this can be described
in a few words, without needing any special concepts.  It does something
that cannot be done easily some other way.  It is utterly local.

Yup, I like it.

I often do not like C++ because it *is* surprising, often has things
spread out over different parts of your program, and distracts from the
one kind of programming style that C++ is well suited for: imperative
programming.  That is also the style that most of most compilers are
written in, for good reasons.

The main consumers of programs are *humans*.  So programs have to be
clear to people.  Modern C style helps that a lot.  Most C++ is the
opposite.  Perhaps this is because C++ gives you so many ways to write
unclear programs, because it has so many features that can be overused,
I do not know what it is exactly.



Either way, I asked if you like my suggestion, you do not have to take
it if you don't :-)

> >> +int index = WORDS_BIG_ENDIAN ? i: nvecs - 1 - i;
> > 
> > Space before colon.
> 
> Ah, thanks for catching that!

Yeah I do not miss the important problems!

> Ok, I'll retest with the above (but still removing the assemble
> built-in documentation) and push it if it's clean.  Thanks!

Great, thank you!


Segher


Re: [PATCH] c++: normalization of non-templated return-type-req [PR100946]

2021-06-10 Thread Jason Merrill via Gcc-patches

On 6/10/21 4:17 PM, Patrick Palka wrote:

On Thu, 10 Jun 2021, Jason Merrill wrote:


On 6/9/21 3:34 PM, Patrick Palka wrote:

Here the satisfaction cache is conflating the satisfaction value of the
two return-type-requirements because the corresponding constrained
'auto's have level 2, but they capture an empty current_template_parms.
This ultimately causes the satisfaction cache to think the type
constraint doesn't depend on the deduced type of the expression.

When normalizing the constraints on an 'auto', the assumption made by
normalize_placeholder_type_constraints is that the level of the 'auto'
is one greater than the captured current_template_parms, an assumption
which is not holding here.  To fix this, this patch adds a dummy level
to current_template_parms to match processing_template_decl when parsing
a non-templated return-type-requirement.  This patch also makes us
verify this assumption upon creation of a constrained 'auto'.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/11?

PR c++/100946

gcc/cp/ChangeLog:

* parser.c (cp_parser_compound_requirement): When parsing a
non-templated return-type-requirement, add a dummy level
to current_template_parms.
* pt.c (make_constrained_placeholder_type): Verify the depth
of current_template_parms is consistent with the level of
the 'auto'.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-return-req3.C: New test.
---
   gcc/cp/parser.c   | 12 
   gcc/cp/pt.c   |  8 
   gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C |  6 ++
   3 files changed, 26 insertions(+)
   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d59a829d0b9..8278a5608ae 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -29181,6 +29181,18 @@ cp_parser_compound_requirement (cp_parser *parser)
 cp_lexer_consume_token (parser->lexer);
 cp_token *tok = cp_lexer_peek_token (parser->lexer);
   +  auto ctp = make_temp_override (current_template_parms);
+  if (!current_template_parms)
+   {
+ /* We're parsing a return-type-requirement within a non-templated
+requires-expression.  Update current_template_parms to agree with
+processing_template_decl so that the normalization context that's
+captured by the corresponding constrained 'auto' is sensible.  */
+ gcc_checking_assert (processing_template_decl == 1);
+ current_template_parms
+   = build_tree_list (size_int (1), make_tree_vec (0));
+   }


How about handling this in normalization, rather than in the parser?


That works nicely too, how does the below look?  Tested
x86_64-pc-linux-gnu.


OK, thanks.


If you set current_template_parms here, when is it cleared?


The 'ctp' temp_override would take care of that.


Ah, of course, somehow I overlooked that line.


-- >8 --

Subject: [PATCH] c++: normalization of non-templated return-type-req
  [PR100946]

Here the satisfaction cache is conflating the satisfaction value of the
two return-type-requirements because the corresponding constrained
'auto's have level 2, but they capture an empty current_template_parms.
This ultimately causes the satisfaction cache to think the type
constraint doesn't depend on the deduced type of the expression.

When normalizing the constraints on an 'auto', the assumption made by
normalize_placeholder_type_constraints is that the level of the 'auto'
is one greater than the depth of the captured current_template_parms, an
assumption which is not holding here.  This patch relaxes makes
normalize_placeholder_type_constraints adjust the normalization context
appropriately in this situation.

PR c++/100946

gcc/cp/ChangeLog:

* constraint.cc (normalize_placeholder_type_constraints): When
normalizing a non-templated return-type-requirement, add a dummy
level to initial_parms.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-return-req3.C: New test.
---
  gcc/cp/constraint.cc  | 9 +
  gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C | 6 ++
  2 files changed, 15 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 03ce8eb9ff2..74b16d27101 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3065,6 +3065,15 @@ normalize_placeholder_type_constraints (tree t, bool 
diag)
   scope for this placeholder type; use them as the initial template
   parameters for normalization.  */
tree initial_parms = TREE_PURPOSE (ci);
+
+  if (!initial_parms && TEMPLATE_TYPE_LEVEL (t) == 2)
+/* This is a return-type-requirement of a non-templated 
requires-expression,
+   which are parsed under processing_template_decl == 1 

Re: [PATCH] c++: normalization of non-templated return-type-req [PR100946]

2021-06-10 Thread Patrick Palka via Gcc-patches
On Thu, 10 Jun 2021, Jason Merrill wrote:

> On 6/9/21 3:34 PM, Patrick Palka wrote:
> > Here the satisfaction cache is conflating the satisfaction value of the
> > two return-type-requirements because the corresponding constrained
> > 'auto's have level 2, but they capture an empty current_template_parms.
> > This ultimately causes the satisfaction cache to think the type
> > constraint doesn't depend on the deduced type of the expression.
> > 
> > When normalizing the constraints on an 'auto', the assumption made by
> > normalize_placeholder_type_constraints is that the level of the 'auto'
> > is one greater than the captured current_template_parms, an assumption
> > which is not holding here.  To fix this, this patch adds a dummy level
> > to current_template_parms to match processing_template_decl when parsing
> > a non-templated return-type-requirement.  This patch also makes us
> > verify this assumption upon creation of a constrained 'auto'.
> > 
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > trunk/11?
> > 
> > PR c++/100946
> > 
> > gcc/cp/ChangeLog:
> > 
> > * parser.c (cp_parser_compound_requirement): When parsing a
> > non-templated return-type-requirement, add a dummy level
> > to current_template_parms.
> > * pt.c (make_constrained_placeholder_type): Verify the depth
> > of current_template_parms is consistent with the level of
> > the 'auto'.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/cpp2a/concepts-return-req3.C: New test.
> > ---
> >   gcc/cp/parser.c   | 12 
> >   gcc/cp/pt.c   |  8 
> >   gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C |  6 ++
> >   3 files changed, 26 insertions(+)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C
> > 
> > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> > index d59a829d0b9..8278a5608ae 100644
> > --- a/gcc/cp/parser.c
> > +++ b/gcc/cp/parser.c
> > @@ -29181,6 +29181,18 @@ cp_parser_compound_requirement (cp_parser *parser)
> > cp_lexer_consume_token (parser->lexer);
> > cp_token *tok = cp_lexer_peek_token (parser->lexer);
> >   +  auto ctp = make_temp_override (current_template_parms);
> > +  if (!current_template_parms)
> > +   {
> > + /* We're parsing a return-type-requirement within a non-templated
> > +requires-expression.  Update current_template_parms to agree with
> > +processing_template_decl so that the normalization context that's
> > +captured by the corresponding constrained 'auto' is sensible.  */
> > + gcc_checking_assert (processing_template_decl == 1);
> > + current_template_parms
> > +   = build_tree_list (size_int (1), make_tree_vec (0));
> > +   }
> 
> How about handling this in normalization, rather than in the parser?

That works nicely too, how does the below look?  Tested
x86_64-pc-linux-gnu.

> 
> If you set current_template_parms here, when is it cleared?

The 'ctp' temp_override would take care of that.

-- >8 --

Subject: [PATCH] c++: normalization of non-templated return-type-req
 [PR100946]

Here the satisfaction cache is conflating the satisfaction value of the
two return-type-requirements because the corresponding constrained
'auto's have level 2, but they capture an empty current_template_parms.
This ultimately causes the satisfaction cache to think the type
constraint doesn't depend on the deduced type of the expression.

When normalizing the constraints on an 'auto', the assumption made by
normalize_placeholder_type_constraints is that the level of the 'auto'
is one greater than the depth of the captured current_template_parms, an
assumption which is not holding here.  This patch relaxes makes
normalize_placeholder_type_constraints adjust the normalization context
appropriately in this situation.

PR c++/100946

gcc/cp/ChangeLog:

* constraint.cc (normalize_placeholder_type_constraints): When
normalizing a non-templated return-type-requirement, add a dummy
level to initial_parms.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-return-req3.C: New test.
---
 gcc/cp/constraint.cc  | 9 +
 gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C | 6 ++
 2 files changed, 15 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 03ce8eb9ff2..74b16d27101 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3065,6 +3065,15 @@ normalize_placeholder_type_constraints (tree t, bool 
diag)
  scope for this placeholder type; use them as the initial template
  parameters for normalization.  */
   tree initial_parms = TREE_PURPOSE (ci);
+
+  if (!initial_parms && TEMPLATE_TYPE_LEVEL (t) == 2)
+/* This is a return-type-requirement of a non-templated 
requires-expression,
+   which are parsed 

Re: [PATCH] c++: matching deduced template template parameters [PR67829]

2021-06-10 Thread Jason Merrill via Gcc-patches

On 6/10/21 3:45 PM, Patrick Palka wrote:

On Thu, 10 Jun 2021, Jason Merrill wrote:


On 6/9/21 3:34 PM, Patrick Palka wrote:

During deduction, when the template of a BOUND_TEMPLATE_TEMPLATE_PARM is
a template template parameter, we need to consider the
TEMPLATE_TEMPLATE_PARAMETER rather than the TEMPLATE_DECL thereof,
because the canonical form of a template template parameter in a
template argument list is the TEMPLATE_TEMPLATE_PARAMETER tree.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

PR c++/67829

gcc/cp/ChangeLog:

* pt.c (unify) : When
the TEMPLATE_DECL of a BOUND_TEMPLATE_TEMPLATE_PARM argument is
a template template parameter, adjust to the
TEMPLATE_TEMPLATE_PARAMETER before falling through.

gcc/testsuite/ChangeLog:

* g++.dg/template/ttp34.C: New test.
* g++.dg/template/ttp34a.C: New test.
* g++.dg/template/ttp34b.C: New test.
---
   gcc/cp/pt.c|  4 
   gcc/testsuite/g++.dg/template/ttp34.C  | 14 ++
   gcc/testsuite/g++.dg/template/ttp34a.C | 14 ++
   gcc/testsuite/g++.dg/template/ttp34b.C | 14 ++
   4 files changed, 46 insertions(+)
   create mode 100644 gcc/testsuite/g++.dg/template/ttp34.C
   create mode 100644 gcc/testsuite/g++.dg/template/ttp34a.C
   create mode 100644 gcc/testsuite/g++.dg/template/ttp34b.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 05679b12973..963a182b9e5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -23555,6 +23555,10 @@ unify (tree tparms, tree targs, tree parm, tree
arg, int strict,
return 1;
  arg = TYPE_TI_TEMPLATE (arg);
+ if (TREE_CODE (TREE_TYPE (arg)) == TEMPLATE_TEMPLATE_PARM)
+   /* If the template is a template template parameter, use the
+  TEMPLATE_TEMPLATE_PARM for matching.  */
+   arg = TREE_TYPE (arg);


Why don't we need the same thing for non-bound ttp unification?


It seems for non-bound ttp unification, if the argument is itself a ttp
then we can rely on it always being represented as the
TEMPLATE_TEMPLATE_PARAMETER tree instead of as the TEMPLATE_DECL thereof,
so this adjustment isn't necessary.

I tested this empirically with the following assert

@@ -23566,6 +23566,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
   || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
 {
+ if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
+ && TREE_CODE (arg) == TEMPLATE_DECL)
+   gcc_assert (TREE_CODE (TREE_TYPE (arg)) != TEMPLATE_TEMPLATE_PARM);
   /* Deduce template name TT from TT, TT<>, TT and TT.  */

   /* Simple cases: Value already set, does match or doesn't.  */

which survives the testsuite.


Sounds good.  Let's use DECL_TEMPLATE_TEMPLATE_PARM_P for the test; OK 
with that change.





  /* Fall through to deduce template name.  */
}
diff --git a/gcc/testsuite/g++.dg/template/ttp34.C
b/gcc/testsuite/g++.dg/template/ttp34.C
new file mode 100644
index 000..67094063ba5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34.C
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template class Purr;
+
+template class, class, class>
+class Meow;
+
+template class P>
+class Meow, int> { }; // 1
+
+template class P, class T>
+class Meow, T>; // 2
+
+Meow, int> kitty;
diff --git a/gcc/testsuite/g++.dg/template/ttp34a.C
b/gcc/testsuite/g++.dg/template/ttp34a.C
new file mode 100644
index 000..e3303dcf212
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34a.C
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template class Purr;
+
+template class, class>
+class Meow;
+
+template class P>
+class Meow > { }; // 1
+
+template class P, class T>
+class Meow >; // 2
+
+Meow > kitty;
diff --git a/gcc/testsuite/g++.dg/template/ttp34b.C
b/gcc/testsuite/g++.dg/template/ttp34b.C
new file mode 100644
index 000..ed3b3e8ab05
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34b.C
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template class Purr;
+
+template class>
+class Meow;
+
+template class P>
+class Meow, P> { }; // 1
+
+template class P, class T>
+class Meow, P>; // 2
+
+Meow, Purr> kitty;










Re: [PATCH] c++: matching deduced template template parameters [PR67829]

2021-06-10 Thread Patrick Palka via Gcc-patches
On Thu, 10 Jun 2021, Jason Merrill wrote:

> On 6/9/21 3:34 PM, Patrick Palka wrote:
> > During deduction, when the template of a BOUND_TEMPLATE_TEMPLATE_PARM is
> > a template template parameter, we need to consider the
> > TEMPLATE_TEMPLATE_PARAMETER rather than the TEMPLATE_DECL thereof,
> > because the canonical form of a template template parameter in a
> > template argument list is the TEMPLATE_TEMPLATE_PARAMETER tree.
> > 
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > trunk?
> > 
> > PR c++/67829
> > 
> > gcc/cp/ChangeLog:
> > 
> > * pt.c (unify) : When
> > the TEMPLATE_DECL of a BOUND_TEMPLATE_TEMPLATE_PARM argument is
> > a template template parameter, adjust to the
> > TEMPLATE_TEMPLATE_PARAMETER before falling through.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/template/ttp34.C: New test.
> > * g++.dg/template/ttp34a.C: New test.
> > * g++.dg/template/ttp34b.C: New test.
> > ---
> >   gcc/cp/pt.c|  4 
> >   gcc/testsuite/g++.dg/template/ttp34.C  | 14 ++
> >   gcc/testsuite/g++.dg/template/ttp34a.C | 14 ++
> >   gcc/testsuite/g++.dg/template/ttp34b.C | 14 ++
> >   4 files changed, 46 insertions(+)
> >   create mode 100644 gcc/testsuite/g++.dg/template/ttp34.C
> >   create mode 100644 gcc/testsuite/g++.dg/template/ttp34a.C
> >   create mode 100644 gcc/testsuite/g++.dg/template/ttp34b.C
> > 
> > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> > index 05679b12973..963a182b9e5 100644
> > --- a/gcc/cp/pt.c
> > +++ b/gcc/cp/pt.c
> > @@ -23555,6 +23555,10 @@ unify (tree tparms, tree targs, tree parm, tree
> > arg, int strict,
> > return 1;
> >   arg = TYPE_TI_TEMPLATE (arg);
> > + if (TREE_CODE (TREE_TYPE (arg)) == TEMPLATE_TEMPLATE_PARM)
> > +   /* If the template is a template template parameter, use the
> > +  TEMPLATE_TEMPLATE_PARM for matching.  */
> > +   arg = TREE_TYPE (arg);
> 
> Why don't we need the same thing for non-bound ttp unification?

It seems for non-bound ttp unification, if the argument is itself a ttp
then we can rely on it always being represented as the
TEMPLATE_TEMPLATE_PARAMETER tree instead of as the TEMPLATE_DECL thereof,
so this adjustment isn't necessary.

I tested this empirically with the following assert

@@ -23566,6 +23566,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
   if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
  || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
+ if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
+ && TREE_CODE (arg) == TEMPLATE_DECL)
+   gcc_assert (TREE_CODE (TREE_TYPE (arg)) != TEMPLATE_TEMPLATE_PARM);
  /* Deduce template name TT from TT, TT<>, TT and TT.  */

  /* Simple cases: Value already set, does match or doesn't.  */

which survives the testsuite.

> 
> >   /* Fall through to deduce template name.  */
> > }
> > diff --git a/gcc/testsuite/g++.dg/template/ttp34.C
> > b/gcc/testsuite/g++.dg/template/ttp34.C
> > new file mode 100644
> > index 000..67094063ba5
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/template/ttp34.C
> > @@ -0,0 +1,14 @@
> > +// PR c++/67829
> > +
> > +template class Purr;
> > +
> > +template class, class, class>
> > +class Meow;
> > +
> > +template class P>
> > +class Meow, int> { }; // 1
> > +
> > +template class P, class T>
> > +class Meow, T>; // 2
> > +
> > +Meow, int> kitty;
> > diff --git a/gcc/testsuite/g++.dg/template/ttp34a.C
> > b/gcc/testsuite/g++.dg/template/ttp34a.C
> > new file mode 100644
> > index 000..e3303dcf212
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/template/ttp34a.C
> > @@ -0,0 +1,14 @@
> > +// PR c++/67829
> > +
> > +template class Purr;
> > +
> > +template class, class>
> > +class Meow;
> > +
> > +template class P>
> > +class Meow > { }; // 1
> > +
> > +template class P, class T>
> > +class Meow >; // 2
> > +
> > +Meow > kitty;
> > diff --git a/gcc/testsuite/g++.dg/template/ttp34b.C
> > b/gcc/testsuite/g++.dg/template/ttp34b.C
> > new file mode 100644
> > index 000..ed3b3e8ab05
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/template/ttp34b.C
> > @@ -0,0 +1,14 @@
> > +// PR c++/67829
> > +
> > +template class Purr;
> > +
> > +template class>
> > +class Meow;
> > +
> > +template class P>
> > +class Meow, P> { }; // 1
> > +
> > +template class P, class T>
> > +class Meow, P>; // 2
> > +
> > +Meow, Purr> kitty;
> > 
> 
> 



[PATCH] PR tree-optimization/96392 Optimize x+0.0 if x is an integer

2021-06-10 Thread Roger Sayle

The patch implements a missed optimization enhancement.  Under usual
IEEE rules, x+0.0 can't be simplified to x when x might potentially
be an IEEE minus zero (-0.0).  The current logic in the middle-end
checks whether the type of x should honor signed zeros, but with this
patch we introduce tree_expr_maybe_real_minus_zero_p that allows us
to confirm that the value can't possibly be -0.0, for example, the result
of a conversion from an integer type, or the result of fabs (or has a
type that doesn't honor signed zero).

Whilst modifying match.pd, I also converted some additional folding
transformations from "testing the type" to "testing the value".

The following patch has been tested on x86_64-pc-linux-gnu with
a make bootstrap and make -k check with no new failures.

Ok for mainline?


2020-06-10  Roger Sayle  

gcc/ChangeLog
PR tree-optimization/96392
* fold-const.c (fold_real_zero_addition_p): Take both arguments
of the addition or subtraction, not just the zero.  Use this
other argument in tests for signaling NaNs and signed zeros.
(tree_expr_maybe_real_minus_zero_p): New predicate.
* fold-const.h (fold_real_zero_addition_p): Update prototype.
(tree_expr_maybe_real_minus_zero_p): New function prototype.
* match.pd: Update calls to fold_real_zero_addition_p.
Replace HONOR_NANS with tree_expr_maybe_nan_p.
Replace HONOR_SIGNED_ZEROS with tree_expr_maybe_real_minus_zero_p.
Replace HONOR_SNANS with tree_expr_maybe_signaling_nan_p.
* tree-ssa-reassoc.c (eliminate_using_constants): Update
call to fold_real_zero_addition_p.

gcc/testsuite/ChangeLog
PR tree-optimization/96392
* gcc.dg/pr96392.c: New test.

Roger
--
Roger Sayle
NextMove Software
Cambridge, UK

diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 6e5835a..95673d2 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -7127,11 +7127,13 @@ fold_binary_op_with_conditional_arg (location_t loc,
 }
 
 
-/* Subroutine of fold() that checks for the addition of +/- 0.0.
+/* Subroutine of fold() that checks for the addition of ARG +/- 0.0.
 
-   If !NEGATE, return true if ADDEND is +/-0.0 and, for all X of type
-   TYPE, X + ADDEND is the same as X.  If NEGATE, return true if X -
-   ADDEND is the same as X.
+   If !NEGATE, return true if ZERO_ARG is +/-0.0 and, for all ARG of
+   type TYPE, ARG + ZERO_ARG is the same as ARG.  If NEGATE, return true
+   if ARG - ZERO_ARG is the same as X.
+
+   If ARG is NULL, check for any value of type TYPE.
 
X + 0 and X - 0 both give X when X is NaN, infinite, or nonzero
and finite.  The problematic cases are when X is zero, and its mode
@@ -7140,13 +7142,14 @@ fold_binary_op_with_conditional_arg (location_t loc,
modes, X + 0 is not the same as X because -0 + 0 is 0.  */
 
 bool
-fold_real_zero_addition_p (const_tree type, const_tree addend, int negate)
+fold_real_zero_addition_p (const_tree type, const_tree arg,
+   const_tree zero_arg, int negate)
 {
-  if (!real_zerop (addend))
+  if (!real_zerop (zero_arg))
 return false;
 
   /* Don't allow the fold with -fsignaling-nans.  */
-  if (HONOR_SNANS (type))
+  if (arg ? tree_expr_maybe_signaling_nan_p (arg) : HONOR_SNANS (type))
 return false;
 
   /* Allow the fold if zeros aren't signed, or their sign isn't important.  */
@@ -7158,19 +7161,20 @@ fold_real_zero_addition_p (const_tree type, const_tree 
addend, int negate)
 return false;
 
   /* In a vector or complex, we would need to check the sign of all zeros.  */
-  if (TREE_CODE (addend) == VECTOR_CST)
-addend = uniform_vector_p (addend);
-  if (!addend || TREE_CODE (addend) != REAL_CST)
+  if (TREE_CODE (zero_arg) == VECTOR_CST)
+zero_arg = uniform_vector_p (zero_arg);
+  if (!zero_arg || TREE_CODE (zero_arg) != REAL_CST)
 return false;
 
   /* Treat x + -0 as x - 0 and x - -0 as x + 0.  */
-  if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
+  if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (zero_arg)))
 negate = !negate;
 
   /* The mode has signed zeros, and we have to honor their sign.
- In this situation, there is only one case we can return true for.
- X - 0 is the same as X with default rounding.  */
-  return negate;
+ In this situation, there are only two cases we can return true for.
+ (i) X - 0 is the same as X with default rounding.
+ (ii) X + 0 is X when X can't possibly be -0.0.  */
+  return negate || (arg && !tree_expr_maybe_real_minus_zero_p (arg));
 }
 
 /* Subroutine of match.pd that optimizes comparisons of a division by
@@ -14375,6 +14379,44 @@ tree_expr_maybe_nan_p (const_tree x)
 }
 }
 
+/* Return true if expression X could evaluate to -0.0.
+   This function returns true if uncertain.  */
+
+bool
+tree_expr_maybe_real_minus_zero_p (const_tree x)
+{
+  if (!HONOR_SIGNED_ZEROS (x))
+return false;
+  switch (TREE_CODE (x))
+{
+case REAL_CST:
+  return 

Re: Aligning stack offsets for spills

2021-06-10 Thread Peter Bergner via Gcc-patches
On 6/7/21 2:00 PM, Jeff Law wrote:
> I can't divulge many of the details right now, but one of the quirks of our
> architecture is that reg+d addressing modes for our vector loads/stores 
> require
> the displacement to be aligned.  This is an artifact of how these instructions
> are encoded.

Given what you're describing, it sounds like POWER has something similar.
Our reg+displacement addressing uses 16-bit displacements using D, DS or DQ
operand fields.  The D field encodes the entire 16-bits, but the DS and DQ
fields only encode 14-bits and 12-bits respectively.  The DS and DQ operands
have the same maximum displacement as D operands, we just force that their
bottom 2-bits/4-bits must be zero, so we don't need to include them in the
insn encoding.  I believe this is all just handled in our legitimate address
routines, but maybe Segher and/or Mike can correct me if I'm wrong?

Peter


Re: [PATCH] c++: matching deduced template template parameters [PR67829]

2021-06-10 Thread Jason Merrill via Gcc-patches

On 6/9/21 3:34 PM, Patrick Palka wrote:

During deduction, when the template of a BOUND_TEMPLATE_TEMPLATE_PARM is
a template template parameter, we need to consider the
TEMPLATE_TEMPLATE_PARAMETER rather than the TEMPLATE_DECL thereof,
because the canonical form of a template template parameter in a
template argument list is the TEMPLATE_TEMPLATE_PARAMETER tree.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

PR c++/67829

gcc/cp/ChangeLog:

* pt.c (unify) : When
the TEMPLATE_DECL of a BOUND_TEMPLATE_TEMPLATE_PARM argument is
a template template parameter, adjust to the
TEMPLATE_TEMPLATE_PARAMETER before falling through.

gcc/testsuite/ChangeLog:

* g++.dg/template/ttp34.C: New test.
* g++.dg/template/ttp34a.C: New test.
* g++.dg/template/ttp34b.C: New test.
---
  gcc/cp/pt.c|  4 
  gcc/testsuite/g++.dg/template/ttp34.C  | 14 ++
  gcc/testsuite/g++.dg/template/ttp34a.C | 14 ++
  gcc/testsuite/g++.dg/template/ttp34b.C | 14 ++
  4 files changed, 46 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/template/ttp34.C
  create mode 100644 gcc/testsuite/g++.dg/template/ttp34a.C
  create mode 100644 gcc/testsuite/g++.dg/template/ttp34b.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 05679b12973..963a182b9e5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -23555,6 +23555,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
return 1;
  
  	  arg = TYPE_TI_TEMPLATE (arg);

+ if (TREE_CODE (TREE_TYPE (arg)) == TEMPLATE_TEMPLATE_PARM)
+   /* If the template is a template template parameter, use the
+  TEMPLATE_TEMPLATE_PARM for matching.  */
+   arg = TREE_TYPE (arg);


Why don't we need the same thing for non-bound ttp unification?


  /* Fall through to deduce template name.  */
}
diff --git a/gcc/testsuite/g++.dg/template/ttp34.C 
b/gcc/testsuite/g++.dg/template/ttp34.C
new file mode 100644
index 000..67094063ba5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34.C
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template class Purr;
+
+template class, class, class>
+class Meow;
+
+template class P>
+class Meow, int> { }; // 1
+
+template class P, class T>
+class Meow, T>; // 2
+
+Meow, int> kitty;
diff --git a/gcc/testsuite/g++.dg/template/ttp34a.C 
b/gcc/testsuite/g++.dg/template/ttp34a.C
new file mode 100644
index 000..e3303dcf212
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34a.C
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template class Purr;
+
+template class, class>
+class Meow;
+
+template class P>
+class Meow > { }; // 1
+
+template class P, class T>
+class Meow >; // 2
+
+Meow > kitty;
diff --git a/gcc/testsuite/g++.dg/template/ttp34b.C 
b/gcc/testsuite/g++.dg/template/ttp34b.C
new file mode 100644
index 000..ed3b3e8ab05
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34b.C
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template class Purr;
+
+template class>
+class Meow;
+
+template class P>
+class Meow, P> { }; // 1
+
+template class P, class T>
+class Meow, P>; // 2
+
+Meow, Purr> kitty;





Re: [PATCH] c++: Failure to delay noexcept parsing with ptr-operator [PR100752]

2021-06-10 Thread Jason Merrill via Gcc-patches

On 6/8/21 8:25 PM, Marek Polacek wrote:

We weren't passing 'flags' to the recursive call to cp_parser_declarator
in the ptr-operator case and as an effect, delayed parsing of noexcept
didn't work as advertised.  The following change passes more than just
CP_PARSER_FLAGS_DELAY_NOEXCEPT but that doesn't seem to break anything.

I'm not passing member_p because I don't need it and because it breaks
a few tests.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/branches?

PR c++/100752

gcc/cp/ChangeLog:

* parser.c (cp_parser_declarator): Pass flags down to
cp_parser_declarator.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/noexcept69.C: New test.
---
  gcc/cp/parser.c |  3 +--
  gcc/testsuite/g++.dg/cpp0x/noexcept69.C | 12 
  2 files changed, 13 insertions(+), 2 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept69.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d59a829d0b9..5930990ec1c 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -22066,8 +22066,7 @@ cp_parser_declarator (cp_parser* parser,
cp_parser_parse_tentatively (parser);
  
/* Parse the dependent declarator.  */

-  declarator = cp_parser_declarator (parser, dcl_kind,
-CP_PARSER_FLAGS_NONE,
+  declarator = cp_parser_declarator (parser, dcl_kind, flags,
 /*ctor_dtor_or_conv_p=*/NULL,
 /*parenthesized_p=*/NULL,
 /*member_p=*/false,


Should the other parameters also be passed down?  I'd think definitely 
member_p and static_p, not sure about ctor_dtor_or_conv_p and 
parenthesized_p.



diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept69.C 
b/gcc/testsuite/g++.dg/cpp0x/noexcept69.C
new file mode 100644
index 000..9b87ba0cafb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept69.C
@@ -0,0 +1,12 @@
+// PR c++/100752
+// { dg-do compile { target c++11 } }
+
+struct S {
+  void f() noexcept {}
+  S () noexcept(noexcept(f())) { f(); return *this; }
+};
+
+struct X {
+  int& f() noexcept(noexcept(i));
+  int i;
+};

base-commit: c4574d23cb07340918793a5a98ae7bb2988b3791





Re: [PATCH] c++: normalization of non-templated return-type-req [PR100946]

2021-06-10 Thread Jason Merrill via Gcc-patches

On 6/9/21 3:34 PM, Patrick Palka wrote:

Here the satisfaction cache is conflating the satisfaction value of the
two return-type-requirements because the corresponding constrained
'auto's have level 2, but they capture an empty current_template_parms.
This ultimately causes the satisfaction cache to think the type
constraint doesn't depend on the deduced type of the expression.

When normalizing the constraints on an 'auto', the assumption made by
normalize_placeholder_type_constraints is that the level of the 'auto'
is one greater than the captured current_template_parms, an assumption
which is not holding here.  To fix this, this patch adds a dummy level
to current_template_parms to match processing_template_decl when parsing
a non-templated return-type-requirement.  This patch also makes us
verify this assumption upon creation of a constrained 'auto'.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/11?

PR c++/100946

gcc/cp/ChangeLog:

* parser.c (cp_parser_compound_requirement): When parsing a
non-templated return-type-requirement, add a dummy level
to current_template_parms.
* pt.c (make_constrained_placeholder_type): Verify the depth
of current_template_parms is consistent with the level of
the 'auto'.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-return-req3.C: New test.
---
  gcc/cp/parser.c   | 12 
  gcc/cp/pt.c   |  8 
  gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C |  6 ++
  3 files changed, 26 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d59a829d0b9..8278a5608ae 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -29181,6 +29181,18 @@ cp_parser_compound_requirement (cp_parser *parser)
cp_lexer_consume_token (parser->lexer);
cp_token *tok = cp_lexer_peek_token (parser->lexer);
  
+  auto ctp = make_temp_override (current_template_parms);

+  if (!current_template_parms)
+   {
+ /* We're parsing a return-type-requirement within a non-templated
+requires-expression.  Update current_template_parms to agree with
+processing_template_decl so that the normalization context that's
+captured by the corresponding constrained 'auto' is sensible.  */
+ gcc_checking_assert (processing_template_decl == 1);
+ current_template_parms
+   = build_tree_list (size_int (1), make_tree_vec (0));
+   }


How about handling this in normalization, rather than in the parser?

If you set current_template_parms here, when is it cleared?


bool saved_result_type_constraint_p = 
parser->in_result_type_constraint_p;
parser->in_result_type_constraint_p = true;
/* C++20 allows either a type-id or a type-constraint. Parsing
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b0155a9c370..05679b12973 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -28131,6 +28131,14 @@ make_constrained_placeholder_type (tree type, tree 
con, tree args)
expr = build_concept_check (expr, type, args, tf_warning_or_error);
--processing_template_decl;
  
+  /* Verify the normalization context is consistent with the level of

+ this 'auto'.  */
+  if (TEMPLATE_TYPE_LEVEL (type) == 1)
+gcc_checking_assert (!current_template_parms);
+  else
+gcc_checking_assert (1 + TMPL_PARMS_DEPTH (current_template_parms)
+== TEMPLATE_TYPE_LEVEL (type));
+
PLACEHOLDER_TYPE_CONSTRAINTS_INFO (type)
  = build_tree_list (current_template_parms, expr);
  
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C

new file mode 100644
index 000..a546c6457be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C
@@ -0,0 +1,6 @@
+// PR c++/100946
+// { dg-do compile { target c++20 } }
+
+template concept C = __is_same(T, int);
+static_assert(requires { { 0 } -> C; });
+static_assert(requires { { true } -> C; }); // { dg-error "failed" }





Re: [PATCH] c++: Add C++23 consteval if support - P1938R3 [PR100974]

2021-06-10 Thread Jason Merrill via Gcc-patches

On 6/10/21 10:44 AM, Jakub Jelinek wrote:

On Thu, Jun 10, 2021 at 10:09:26AM -0400, Jason Merrill wrote:

--- gcc/cp/parser.c.jj  2021-06-09 21:54:39.482193853 +0200
+++ gcc/cp/parser.c 2021-06-10 10:09:23.753052980 +0200
@@ -10902,6 +10902,11 @@ cp_parser_lambda_expression (cp_parser*
   bool discarded = in_discarded_stmt;
   in_discarded_stmt = 0;
+/* Similarly the body of a lambda in immediate function context is not
+   in immediate function context.  */
+bool immediate_fn_ctx_p = in_immediate_fn_ctx_p;


It's hard to distinguish between these two names when reading the code;
let's give the local variable a name including "saved".


Will do.


+   if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
+ error ("% requires compound statement");
+
+   in_immediate_fn_ctx_p |= ce > 0;
+   cp_parser_implicitly_scoped_statement (parser, NULL, guard_tinfo);


Maybe use cp_parser_compound_statement directly instead of this and checking
CPP_OPEN_BRACE above?  Either way is fine.


I thought doing it this way will provide better diagnostics for what I think
can be a common bug - people so used to normal if not requiring compound
statements forgetting those {}s from time to time.



What the patch currently diagnoses is:
consteval-if2.C:13:6: error: ‘if consteval’ requires compound statement
   13 |   if consteval if (true) {} // { dg-error "'if consteval' requires 
compound statement" }
  |  ^
while with cp_parser_compound_statement directly it diagnoses:
consteval-if2.C:13:16: error: expected ‘{’ before ‘if’
   13 |   if consteval if (true) {} // { dg-error "'if consteval' requires 
compound statement" }
  |^~
What do you prefer?


The second is clearer about the fix, the first is clearer about the 
problem.  Maybe add a fixit to the first error?



Dunno if the fine detail that in the grammar only one of the statements
is compound-statement and then there is a requirement that the other
statement has to be a compound-statement shouldn't affect how it is
reported.


The difference was to prevent "else ;" from binding to an enclosing if 
rather than the if consteval.



+  if (TREE_CODE (t) == IF_STMT && IF_STMT_CONSTEVAL_P (t))
+{
+  /* Evaluate the condition as if it was
+if (__builtin_is_constant_evaluated ()).  */
+  if (ctx->manifestly_const_eval)
+   val = boolean_true_node;
+  else
+   {
+ *non_constant_p = true;
+ return t;
+   }


Why set *non_constant_p?  Shouldn't this just be

val = boolean_false_node;

so we constant-evaluate the else clause when we are trying to
constant-evaluate in a non-manifestly-constant-evaluated context?


It matches what we do for CP_BUILT_IN_IS_CONSTANT_EVALUATED calls:
   /* For __builtin_is_constant_evaluated, defer it if not
  ctx->manifestly_const_eval, otherwise fold it to true.  */
   if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
  BUILT_IN_FRONTEND))
 {
   if (!ctx->manifestly_const_eval)
 {
   *non_constant_p = true;
   return t;
 }
   return boolean_true_node;
 }
I believe we sometimes try to constexpr evaluate something without
having manifestly_const_eval = true even on expressions that
are in manifestly constant evaluated contexts and am worried if
we just folded it to boolean_false_node we could get a constant expression
and replace the expression with that, even before we actually try to
constant evaluate it with manifestly_const_eval = true.

If I do (for the CP_BUILT_IN_IS_CONSTANT_EVALUATED):
--- gcc/cp/constexpr.c.jj   2021-06-10 15:27:31.123353594 +0200
+++ gcc/cp/constexpr.c  2021-06-10 16:26:38.368168281 +0200
@@ -1320,10 +1320,7 @@ cxx_eval_builtin_function_call (const co
 BUILT_IN_FRONTEND))
  {
if (!ctx->manifestly_const_eval)
-   {
- *non_constant_p = true;
- return t;
-   }
+   return boolean_false_node;
return boolean_true_node;
  }
  
then

FAIL: g++.dg/cpp2a/is-constant-evaluated1.C  -std=c++14 execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated1.C  -std=c++17 execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated1.C  -std=c++2a execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated1.C  -std=c++17 -fconcepts execution 
test
FAIL: g++.dg/cpp2a/is-constant-evaluated2.C  -std=c++14 execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated2.C  -std=c++17 execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated2.C  -std=c++2a execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated2.C  -std=c++17 -fconcepts execution 
test
FAIL: g++.dg/cpp2a/is-constant-evaluated9.C  -std=gnu++2a (test for excess 
errors)
at least regresses.


OK, just add a comment then.


+  if (TREE_CODE (t) != IF_STMT || !IF_STMT_CONSTEVAL_P (t))
+   {
+ if (integer_zerop (tmp))
+   return RECUR (TREE_OPERAND (t, 2), 

Re: [PATCH] rs6000: Add new __builtin_vsx_build_pair and __builtin_mma_build_acc built-ins

2021-06-10 Thread Peter Bergner via Gcc-patches
On 6/10/21 10:43 AM, Peter Bergner wrote:
> On 6/9/21 4:38 PM, Segher Boessenkool wrote:
>> Okay for trunk and 11 with at least that space fixed.  Thanks!
> 
> Ok, I'll retest with the above (but still removing the assemble
> built-in documentation) and push it if it's clean.  Thanks!

Testing was clean on the updated patch so I pushed it to trunk.
I'll let it bake a day or two before backporting.  Thanks!

Peter




Re: [PATCH] PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514

2021-06-10 Thread Harald Anlauf via Gcc-patches
Hi Bernhard,

> > +static bool
> > +substring_has_constant_len (gfc_expr *e)
> > +{
> > +  ptrdiff_t istart, iend;
> > +  size_t length;
> > +  bool equal_length = false;
> > +
> > +  if (e->ts.type != BT_CHARACTER
> > +  || !(e->ref && e->ref->type == REF_SUBSTRING)
>
> iff we ever can get here with e->ref == NULL then the below will not
> work too well. If so then maybe
>   if (e->ts.type != BT_CHARACTER
>   || ! e->ref
>   || e->ref->type != REF_SUBSTRING
>
> ?

as you already realized, the logic was fine, but probably less
readable than your version.  I've changed the code accordingly.

> > +  else if (substring_has_constant_len (e))
> > +{
> > +  result = gfc_get_constant_expr (BT_INTEGER, k, >where);
> > +  mpz_set_si (result->value.integer,
> > + e->value.character.length);
>
> I think the mpz_set_si args above fit on one line.

That's true.

Since this block is exactly the same as for constant strings,
which is handled in the first condition, I've thought some more
and am convinced now that these two can be fused.  Done now.

I've also added two cornercases to the testcase, and regtested again.

> btw.. there's a commentary typo in add_init_expr_to_sym():
> s/skeep/skip/

That is a completely unrelated issue in a different file, right?

Thanks for your constructive comments!

Harald

diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index c27b47aa98f..42ddc62f3c6 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -4512,6 +4512,61 @@ gfc_simplify_leadz (gfc_expr *e)
 }


+/* Check for constant length of a substring.  */
+
+static bool
+substring_has_constant_len (gfc_expr *e)
+{
+  ptrdiff_t istart, iend;
+  size_t length;
+  bool equal_length = false;
+
+  if (e->ts.type != BT_CHARACTER
+  || !e->ref
+  || e->ref->type != REF_SUBSTRING
+  || !e->ref->u.ss.start
+  || e->ref->u.ss.start->expr_type != EXPR_CONSTANT
+  || !e->ref->u.ss.end
+  || e->ref->u.ss.end->expr_type != EXPR_CONSTANT
+  || !e->ref->u.ss.length
+  || !e->ref->u.ss.length->length
+  || e->ref->u.ss.length->length->expr_type != EXPR_CONSTANT)
+return false;
+
+  /* Basic checks on substring starting and ending indices.  */
+  if (!gfc_resolve_substring (e->ref, _length))
+return false;
+
+  istart = gfc_mpz_get_hwi (e->ref->u.ss.start->value.integer);
+  iend = gfc_mpz_get_hwi (e->ref->u.ss.end->value.integer);
+  length = gfc_mpz_get_hwi (e->ref->u.ss.length->length->value.integer);
+
+  if (istart <= iend)
+{
+  if (istart < 1)
+	{
+	  gfc_error ("Substring start index (%ld) at %L below 1",
+		 (long) istart, >ref->u.ss.start->where);
+	  return false;
+	}
+  if (iend > (ssize_t) length)
+	{
+	  gfc_error ("Substring end index (%ld) at %L exceeds string "
+		 "length", (long) iend, >ref->u.ss.end->where);
+	  return false;
+	}
+  length = iend - istart + 1;
+}
+  else
+length = 0;
+
+  /* Fix substring length.  */
+  e->value.character.length = length;
+
+  return true;
+}
+
+
 gfc_expr *
 gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
 {
@@ -4521,7 +4576,8 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
   if (k == -1)
 return _bad_expr;

-  if (e->expr_type == EXPR_CONSTANT)
+  if (e->expr_type == EXPR_CONSTANT
+  || substring_has_constant_len (e))
 {
   result = gfc_get_constant_expr (BT_INTEGER, k, >where);
   mpz_set_si (result->value.integer, e->value.character.length);
diff --git a/gcc/testsuite/gfortran.dg/pr100950.f90 b/gcc/testsuite/gfortran.dg/pr100950.f90
new file mode 100644
index 000..54c459adf99
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr100950.f90
@@ -0,0 +1,22 @@
+! { dg-do run }
+! PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514
+
+program p
+  character(8), parameter :: u = "123"
+  character(8):: x = "", s
+  character(2):: w(2) = [character(len(x(3:4))) :: 'a','b' ]
+  character(*), parameter :: y(*) = [character(len(u(3:4))) :: 'a','b' ]
+  character(*), parameter :: z(*) = [character(len(x(3:4))) :: 'a','b' ]
+  character(*), parameter :: t(*) = [character(len(x( :2))) :: 'a','b' ]
+  character(*), parameter :: v(*) = [character(len(x(7: ))) :: 'a','b' ]
+  if (len (y) /= 2) stop 1
+  if (len (z) /= 2) stop 2
+  if (any (w /= y)) stop 3
+  if (len ([character(len(u(3:4))) :: 'a','b' ]) /= 2)  stop 4
+  if (len ([character(len(x(3:4))) :: 'a','b' ]) /= 2)  stop 5
+  if (any ([character(len(x(3:4))) :: 'a','b' ]  /= y)) stop 6
+  write(s,*) [character(len(x(3:4))) :: 'a','b' ]
+  if (s /= " a b") stop 7
+  if (len (t) /= 2) stop 8
+  if (len (v) /= 2) stop 9
+end


[committed] d: Fix ICE in TypeInfoDeclaration, at dmd/declaration.c (PR100967)

2021-06-10 Thread Iain Buclaw via Gcc-patches
Hi,

This patch fixes an ICE in the constructor of TypeInfoDeclaration from
within the D language front-end.  Generates a stub TypeInfo class even
if the root Object class is missing.  The front-end will take care of
issuing an error and abort the compilation when running semantic on
constructed TypeInfo objects.

The errors issued by the code generation pass relating to missing or
disabled RTTI has been consolidated into a single function, so that a
meaningful error will be emitted before the front-end terminates.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32,
committed to mainline, and backported to the gcc-9, gcc-10, and gcc-11
release branches.

Regards,
Iain

---
gcc/d/ChangeLog:

PR d/100967
* d-frontend.cc (getTypeInfoType): Move TypeInfo checks to
check_typeinfo_type and call new function.
* d-tree.h (check_typeinfo_type): Declare.
* typeinfo.cc: Include dmd/scope.h.
(create_frontend_tinfo_types): Generate front-end types even if Object
is missing.
(build_typeinfo): Move TypeInfo checks to check_typeinfo_type and call
new function.
(check_typeinfo_type): New function.

gcc/testsuite/ChangeLog:

PR d/100967
* gdc.dg/pr100967.d: New test.
---
 gcc/d/d-frontend.cc | 33 +---
 gcc/d/d-tree.h  |  1 +
 gcc/d/typeinfo.cc   | 38 +++--
 gcc/testsuite/gdc.dg/pr100967.d | 11 ++
 4 files changed, 45 insertions(+), 38 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/pr100967.d

diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc
index 84c70f8ee6a..30fc6d435d0 100644
--- a/gcc/d/d-frontend.cc
+++ b/gcc/d/d-frontend.cc
@@ -185,39 +185,8 @@ eval_builtin (Loc loc, FuncDeclaration *fd, Expressions 
*arguments)
 Type *
 getTypeInfoType (Loc loc, Type *type, Scope *sc)
 {
-  if (!global.params.useTypeInfo)
-{
-  /* Even when compiling without RTTI we should still be able to evaluate
-TypeInfo at compile-time, just not at run-time.  */
-  if (!sc || !(sc->flags & SCOPEctfe))
-   {
- static int warned = 0;
-
- if (!warned)
-   {
- error_at (make_location_t (loc),
-   "% cannot be used with 
%<-fno-rtti%>");
- warned = 1;
-   }
-   }
-}
-
-  if (Type::dtypeinfo == NULL
-  || (Type::dtypeinfo->storage_class & STCtemp))
-{
-  /* If TypeInfo has not been declared, warn about each location once.  */
-  static Loc warnloc;
-
-  if (!loc.equals (warnloc))
-   {
- error_at (make_location_t (loc),
-   "% could not be found, "
-   "but is implicitly used");
- warnloc = loc;
-   }
-}
-
   gcc_assert (type->ty != Terror);
+  check_typeinfo_type (loc, sc);
   create_typeinfo (type, sc ? sc->_module->importedFrom : NULL);
   return type->vtinfo->type;
 }
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index bb731a60541..6ef9af2a991 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -670,6 +670,7 @@ extern tree layout_classinfo (ClassDeclaration *);
 extern unsigned base_vtable_offset (ClassDeclaration *, BaseClass *);
 extern tree get_typeinfo_decl (TypeInfoDeclaration *);
 extern tree get_classinfo_decl (ClassDeclaration *);
+extern void check_typeinfo_type (const Loc &, Scope *);
 extern tree build_typeinfo (const Loc &, Type *);
 extern void create_typeinfo (Type *, Module *);
 extern void create_tinfo_types (Module *);
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index 503480b491d..9d6464deb07 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dmd/identifier.h"
 #include "dmd/module.h"
 #include "dmd/mtype.h"
+#include "dmd/scope.h"
 #include "dmd/template.h"
 #include "dmd/target.h"
 
@@ -244,8 +245,8 @@ create_tinfo_types (Module *mod)
 static void
 create_frontend_tinfo_types (void)
 {
-  /* If there's no Object class defined, then neither can TypeInfo be.  */
-  if (object_module == NULL || ClassDeclaration::object == NULL)
+  /* If there's no object module, then neither can there be TypeInfo.  */
+  if (object_module == NULL)
 return;
 
   /* Create all frontend TypeInfo classes declarations.  We rely on all
@@ -1373,16 +1374,19 @@ get_classinfo_decl (ClassDeclaration *decl)
   return decl->csym;
 }
 
-/* Returns typeinfo reference for TYPE.  */
+/* Performs sanity checks on the `object.TypeInfo' type, raising an error if
+   RTTI is disabled, or the type is missing.  */
 
-tree
-build_typeinfo (const Loc , Type *type)
+void
+check_typeinfo_type (const Loc , Scope *sc)
 {
   if (!global.params.useTypeInfo)
 {
   static int warned = 0;
 
-  if (!warned)
+  /* Even when compiling without RTTI we should still be able to evaluate
+TypeInfo at compile-time, just not at run-time.  */
+  if (!warned && (!sc 

Re: [RFC] mask out mult expr ctz bits from nonzero bits

2021-06-10 Thread Jeff Law via Gcc-patches




On 1/27/2021 6:47 AM, Alexandre Oliva wrote:

While looking into the possibility of introducing setmemM patterns on
RISC-V to undo the transformation from loops of word writes into
memset, I was disappointed to find out that get_nonzero_bits would
take into account the range of the length passed to memset, but not
the trivially-available observation that this length was a multiple of
the word size.  This knowledge, if passed on to setmemM, could enable
setmemM to output more efficient code.

In the end, I did not introduce a setmemM pattern, nor the machinery
to pass the ctz of the length on to it along with other useful
information, but I figured this small improvement to nonzero_bits
could still improve code generation elsewhere.
https://gcc.gnu.org/pipermail/gcc-patches/2021-January/564341.html


Regstrapped on x86_64-linux-gnu.  No analysis of codegen impact yet.
Does this seem worth pursuing, presumably for stage1?


for  gcc/ChangeLog

* tree-ssanames.c (get_nonzero_bits): Zero out low bits of
integral types, when a MULT_EXPR INTEGER_CST operand ensures
the result will be a multiple of a power of two.
Your call on whether or not to pursue -- I'm not sure how often this 
helps us in practice.


If you want to pursue, I'd suggest some tests to show when/how its helpful.

jeff



[GCC-9][committed] PR d/90651 (ICE in FuncDeclaration::semantic3, at d/dmd/func.c:1524)

2021-06-10 Thread Iain Buclaw via Gcc-patches
Hi,

When looking into fixing PR100967, I noticed that the gcc-9 release
branch first needed a patch to address another issue that didn't
originally get backported from GCC-10.

This fixes segmentation fault in FuncDeclaration::semantic3.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and
committed to the gcc-9 release branch.

Regards,
Iain.

---
gcc/d/ChangeLog:

PR d/90651
* dmd/expressionsem.c (ExpressionSemanticVisitor::visit (TypeidExp)):
Error when TypeInfo doesn't exist.
* dmd/func.c (FuncDeclaration::semantic3): Likewise.
* dmd/mtype.c (TypeClass::dotExp): Likewise.
* typeinfo.cc (object_module): New variable.
(make_frontend_typeinfo): Update signature.  Set temporary on
generated TypeInfo classes.
(create_tinfo_types): Set object_module.  Move generation of front-end
typeinfo into ...
(create_frontend_tinfo_types): ... New function.
(layout_typeinfo): Call create_frontend_tinfo_types.
(layout_classinfo): Likewise.
(layout_cpp_typeinfo): Likewise.
(create_typeinfo): Likewise.

gcc/testsuite/ChangeLog:

PR d/90651
* gdc.test/fail_compilation/extra-files/minimal/object.d: New file.
* gdc.test/fail_compilation/fail19911a.d: New test.
* gdc.test/fail_compilation/fail19911b.d: New test.
* gdc.test/fail_compilation/fail19911c.d: New test.
* gdc.test/fail_compilation/fail19922.d: New test.
* gdc.test/fail_compilation/fail19923.d: New test.

(cherry picked from commit 88ad43b1f91f7cd2ba9c342c6c1a6da82e6088bf)
---
 gcc/d/dmd/expressionsem.c | 18 ++--
 gcc/d/dmd/func.c  | 12 +++
 gcc/d/dmd/mtype.c |  7 +-
 gcc/d/typeinfo.cc | 85 +--
 .../extra-files/minimal/object.d  |  1 +
 .../gdc.test/fail_compilation/fail19911a.d| 11 +++
 .../gdc.test/fail_compilation/fail19911b.d| 13 +++
 .../gdc.test/fail_compilation/fail19911c.d| 17 
 .../gdc.test/fail_compilation/fail19922.d | 19 +
 .../gdc.test/fail_compilation/fail19923.d | 19 +
 10 files changed, 168 insertions(+), 34 deletions(-)
 create mode 100644 
gcc/testsuite/gdc.test/fail_compilation/extra-files/minimal/object.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail19911a.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail19911b.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail19911c.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail19922.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail19923.d

diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index 75794a03285..847a0796792 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -1806,11 +1806,19 @@ public:
 Expression *e;
 if (ea && ta->toBasetype()->ty == Tclass)
 {
-/* Get the dynamic type, which is .classinfo
-*/
-ea = semantic(ea, sc);
-e = new TypeidExp(ea->loc, ea);
-e->type = Type::typeinfoclass->type;
+if (!Type::typeinfoclass)
+{
+error(exp->loc, "`object.TypeInfo_Class` could not be found, 
but is implicitly used");
+e = new ErrorExp();
+}
+else
+{
+/* Get the dynamic type, which is .classinfo
+*/
+ea = semantic(ea, sc);
+e = new TypeidExp(ea->loc, ea);
+e->type = Type::typeinfoclass->type;
+}
 }
 else if (ta->ty == Terror)
 {
diff --git a/gcc/d/dmd/func.c b/gcc/d/dmd/func.c
index 568decc8cee..04c70cf3b7b 100644
--- a/gcc/d/dmd/func.c
+++ b/gcc/d/dmd/func.c
@@ -1520,6 +1520,18 @@ void FuncDeclaration::semantic3(Scope *sc)
 {
 if (f->linkage == LINKd)
 {
+// Variadic arguments depend on Typeinfo being defined
+if (!global.params.useTypeInfo || !Type::dtypeinfo || 
!Type::typeinfotypelist)
+{
+if (!global.params.useTypeInfo)
+error("D-style variadic functions cannot be used with 
-betterC");
+else if (!Type::typeinfotypelist)
+error("`object.TypeInfo_Tuple` could not be found, but 
is implicitly used in D-style variadic functions");
+else
+error("`object.TypeInfo` could not be found, but is 
implicitly used in D-style variadic functions");
+fatal();
+}
+
 // Declare _arguments[]
 v_arguments = new VarDeclaration(Loc(), 
Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
 v_arguments->storage_class |= STCtemp | STCparameter;
diff --git 

Re: [PATCH] c++: Add C++23 consteval if support - P1938R3 [PR100974]

2021-06-10 Thread Jakub Jelinek via Gcc-patches
On Thu, Jun 10, 2021 at 04:44:09PM +0200, Jakub Jelinek wrote:
> > Maybe use cp_parser_compound_statement directly instead of this and checking
> > CPP_OPEN_BRACE above?  Either way is fine.
> 
> I thought doing it this way will provide better diagnostics for what I think
> can be a common bug - people so used to normal if not requiring compound
> statements forgetting those {}s from time to time.

What the patch currently diagnoses is:
consteval-if2.C:13:6: error: ‘if consteval’ requires compound statement
   13 |   if consteval if (true) {} // { dg-error "'if consteval' requires 
compound statement" }
  |  ^
while with cp_parser_compound_statement directly it diagnoses:
consteval-if2.C:13:16: error: expected ‘{’ before ‘if’
   13 |   if consteval if (true) {} // { dg-error "'if consteval' requires 
compound statement" }
  |^~
What do you prefer?
Dunno if the fine detail that in the grammar only one of the statements
is compound-statement and then there is a requirement that the other
statement has to be a compound-statement shouldn't affect how it is
reported.

Jakub



Re: libstdc++ PR 57272 Fancy pointer support in Hashtable

2021-06-10 Thread François Dumont via Gcc-patches

I would like to renew this proposal.

I considered all your feedbacks expect:

On 02/11/20 3:11 pm, Jonathan Wakely wrote:


There's no point doing it if you still use raw pointers.

It either has to be done completely, or it's a waste of time and
energy.



Why ? Can you provide the Standard documentation explaining why the 
custom pointer must the used everywhere ?


For the moment I considered that fancy pointer types are meant to allow 
access to some special memory area in which a simple raw pointer is not 
enough to describe an instance location. This is why this patch is 
making sure that the fancy pointer is stored and returned to the 
allocator without any loss of information.


Otherwise, for internal Hashtable purpose simple raw pointers are still 
being used. I cannot imagine that any user is expecting to improve 
container performances with a hand written pointer implementation.


For the moment I ignore the comment in the PR about limiting operations 
done with the pointer (except that I am not using it everywhere of 
course). I will propose to add move semantic on those pointers if this 
patch is accepted.


François

diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index 4bdbe7dd9cc..c77cb50c3d9 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -182,8 +182,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  _RehashPolicy, _Traits>,
   private __detail::_Hashtable_alloc<
 	__alloc_rebind<_Alloc,
-		   __detail::_Hash_node<_Value,
-	_Traits::__hash_cached::value>>>
+		   __detail::__get_node_type<_Alloc, _Value,
+		_Traits::__hash_cached::value>>>
 {
   static_assert(is_same::type, _Value>::value,
 	  "unordered container must have a non-const, non-volatile value_type");
@@ -195,21 +195,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   using __traits_type = _Traits;
   using __hash_cached = typename __traits_type::__hash_cached;
   using __constant_iterators = typename __traits_type::__constant_iterators;
-  using __node_type = __detail::_Hash_node<_Value, __hash_cached::value>;
+  using __node_type = __detail::__get_node_type<
+	_Alloc, _Value, _Traits::__hash_cached::value>;
   using __node_alloc_type = __alloc_rebind<_Alloc, __node_type>;
-
   using __hashtable_alloc = __detail::_Hashtable_alloc<__node_alloc_type>;
 
   using __node_value_type =
-	__detail::_Hash_node_value<_Value, __hash_cached::value>;
+	typename __node_type::__node_value_cache_type;
   using __node_ptr = typename __hashtable_alloc::__node_ptr;
-  using __value_alloc_traits =
-	typename __hashtable_alloc::__value_alloc_traits;
   using __node_alloc_traits =
 	typename __hashtable_alloc::__node_alloc_traits;
-  using __node_base = typename __hashtable_alloc::__node_base;
-  using __node_base_ptr = typename __hashtable_alloc::__node_base_ptr;
+  using __node_base = typename __node_type::__node_base;
+  using __value_alloc_traits =
+	typename __node_alloc_traits::template rebind_traits<_Value>;
   using __buckets_ptr = typename __hashtable_alloc::__buckets_ptr;
+  using __buckets_ptr_traits = std::pointer_traits<__buckets_ptr>;
 
   using __insert_base = __detail::_Insert<_Key, _Value, _Alloc, _ExtractKey,
 	  _Equal, _Hash,
@@ -233,15 +233,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   using const_iterator = typename __insert_base::const_iterator;
 
-  using local_iterator = __detail::_Local_iterator;
+  using local_iterator = __detail::__local_iterator<
+	__node_ptr, key_type, value_type,
+	_ExtractKey, _Hash, _RangeHash, _Unused,
+	__constant_iterators::value, __hash_cached::value>;
 
-  using const_local_iterator = __detail::_Local_const_iterator<
-			key_type, _Value,
-			_ExtractKey, _Hash, _RangeHash, _Unused,
-			__constant_iterators::value, __hash_cached::value>;
+  using const_local_iterator = __detail::__const_local_iterator<
+	__node_ptr, key_type, value_type,
+	_ExtractKey, _Hash, _RangeHash, _Unused,
+	__constant_iterators::value, __hash_cached::value>;
 
 private:
   using __rehash_type = _RehashPolicy;
@@ -376,7 +376,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
 private:
-  __buckets_ptr		_M_buckets		= &_M_single_bucket;
+  __buckets_ptr		_M_buckets =
+			__buckets_ptr_traits::pointer_to(_M_single_bucket);
   size_type			_M_bucket_count		= 1;
   __node_base		_M_before_begin;
   size_type			_M_element_count	= 0;
@@ -388,13 +389,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // qualified.
   // Note that we can't leave hashtable with 0 bucket without adding
   // numerous checks in the code to avoid 0 modulus.
-  __node_base_ptr		_M_single_bucket	= nullptr;
+  __node_base*		_M_single_bucket	= nullptr;
 
   void
   _M_update_bbegin()
   {
-	if (_M_begin())
-	  _M_buckets[_M_bucket_index(*_M_begin())] = &_M_before_begin;
+	if (auto __begin = 

Re: GCC documentation: porting to Sphinx

2021-06-10 Thread Joseph Myers
On Thu, 10 Jun 2021, Martin Liška wrote:

> 1) Can we organize the new documentation in $gccroot/doc folder 
> similarly to what I have in texi2rst-generated repo? Would be beneficial 
> as we can have a single Makefile and shared content will be in a same 
> depth to the individual manuals.

Where languages have their own manuals, I think it's more appropriate for 
those to go under the language-specific directories.

That doesn't stop the use of shared makefile code.  Make-lang.in is a 
fragment included from gcc/Makefile.in ("-include $(LANG_MAKEFRAGS)").  I 
certainly expect it should be possible to write GNU make code in 
gcc/Makefile.in for building and installing manuals, such that 
subdirectories only need to define a few variables describing what manuals 
they have and everything else is handled by common code.

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


RE: [GCC][PATCH] arm: Fix multilib mapping for CDE extensions.

2021-06-10 Thread Srinath Parvathaneni via Gcc-patches
Hi Richard,

I have all addressed all your review comments in the trailing in the patch 
attached.

Please review and let me know if it ok for master?

Regards,
Srinath.  
> -Original Message-
> From: Richard Earnshaw 
> Sent: 02 June 2021 15:20
> To: Srinath Parvathaneni ; gcc-
> patc...@gcc.gnu.org
> Cc: Richard Earnshaw 
> Subject: Re: [GCC][PATCH] arm: Fix multilib mapping for CDE extensions.
> 
> 
> 
> On 01/06/2021 18:08, Srinath Parvathaneni via Gcc-patches wrote:
> > Hi All,
> >
> > On passing +cdecp[0-7] extension to the -march string in command line
> > options, multilib linking is failing as mentioned in PR100856. This
> > patch fixes this issue by generating a separate -march string only for
> multilib comparison.
> >
> > Regression tested on arm-none-eabi and found no regressions.
> >
> > Ok for master?
> >
> Not as it stands.  More comments below.
> 
> > Regards,
> > Srinath.
> >
> > gcc/ChangeLog:
> >
> > 2021-06-01  Srinath Parvathaneni  
> >
> > PR target/100856
> > * common/config/arm/arm-common.c (arm_canon_arch_option):
> Modify
> > function to generate canonical march string after removing cde
> related
> > compiler extensions.
> > (arm_canon_arch_multilib_option): Define function.
> > * config/arm/arm-cpus.in (CDE_LIST): Define fgroup.
> > * config/arm/arm.h (arm_canon_arch_multilib_option): Define
> macro.
> > (CANON_ARCH_MULTILIB_SPEC_FUNCTION): Define macro.
> > (ARCH_CANONICAL_MULTILIB_SPECS): Define macro.
> > (TARGET_MULTLILIB_ARCH): Define macro.
> > * gcc.c (used_arg_t::operator ()): Add condition to generate separate
> > march string for multilib matching.
> >
> > gcc/testsuite/ChangeLog:
> >
> > 2021-06-01  Srinath Parvathaneni  
> >
> > PR target/100856
> > * gcc.target/arm/acle/pr100856.c: New test.
> > * gcc.target/arm/multilib.exp: Modify.
> >
> >
> >
> > ### Attachment also inlined for ease of reply
> ###
> >
> >
> > diff --git a/gcc/common/config/arm/arm-common.c
> > b/gcc/common/config/arm/arm-common.c
> > index
> >
> 9980af6885c3dfe68f61fa0f39b23022b4e59c19..7d8c6e5253f3f1683eed99f479
> a0
> > 9186a46c2d22 100644
> > --- a/gcc/common/config/arm/arm-common.c
> > +++ b/gcc/common/config/arm/arm-common.c
> > @@ -616,6 +616,8 @@ public:
> >   }
> >   };
> >
> > +static int multilib_arch = 0;
> 
> Please, no!  Instead...
> 
> > +
> >   /* Generate a canonical representation of the -march option from the
> >  current -march string (if given) and other options on the command
> >  line that might affect the architecture.  This aids multilib
> > selection @@ -703,6 +705,14 @@ arm_canon_arch_option (int argc, const
> > char **argv)
> 
> This function should be renamed arm_canon_arch_option_1 and given an
> extra (bool) parameter to control the behaviour.  Then
> arm_canon_arch_option can call it with the parameter false to maintain the
> existing behaviour and arm_canon_arch_multilib_option can pass true.
> 
> > arm_initialize_isa (target_isa, selected_arch->common.isa_bits);
> > arm_parse_option_features (target_isa, _arch->common,
> >  strchr (arch, '+'));
> > +  if (multilib_arch == 1)
> > +   {
> > + const enum isa_feature cde_bitlist[] = {ISA_ALL_CDE, isa_nobit};
> 
> This is too specific, but that's mostly a naming problem.  Instead we need a
> new feature group IGNORE_FOR_MULTILIB (which at present just contains
> ALL_CDE).
> 
> > + sbitmap isa_cdebits = sbitmap_alloc (isa_num_bits);
> > + arm_initialize_isa (isa_cdebits, cde_bitlist);
> > + bitmap_and_compl (target_isa, target_isa, isa_cdebits);
> > +   }
> > +
> > if (fpu && strcmp (fpu, "auto") != 0)
> > {
> >   /* We assume that architectures do not have any FPU bits @@
> > -786,18 +796,27 @@ arm_canon_arch_option (int argc, const char **argv)
> >
> > arm_initialize_isa (base_isa, selected_arch->common.isa_bits);
> >
> > -  /* Architecture has no extension options, so just return the canonical
> > - architecture name.  */
> > -  if (selected_arch->common.extensions == NULL)
> > -return selected_arch->common.name;
> > -
> > /* We're only interested in extension bits.  */
> > bitmap_and_compl (target_isa, target_isa, base_isa);
> >
> > +  /* Architecture has no extension options, so just return the canonical
> > + architecture name.  */
> > +  if (multilib_arch == 0 && selected_arch->common.extensions == NULL)
> > +return selected_arch->common.name;
> > /* There are no extensions needed.  Just return the canonical
> architecture
> >name.  */
> > -  if (bitmap_empty_p (target_isa))
> > +  else if (multilib_arch == 0 && bitmap_empty_p (target_isa))
> >   return selected_arch->common.name;
> > +  else if (multilib_arch == 1
> > +  && (selected_arch->common.extensions == NULL
> > +  || bitmap_empty_p (target_isa)))
> > +{
> > +  canonical_arch = (char *) xmalloc (strlen 

[GCC][PATCH] arm: Fix polymorphic variants failing with undefined reference to `__ARM_undef` error.

2021-06-10 Thread Srinath Parvathaneni via Gcc-patches
Hi,

This patch fixes the issue mentioned in PR101016, which is mve polymorphic 
variants
failing at linking with undefined reference to "__ARM_undef" error.

Regression tested on arm-none-eabi and found no regressions.

Ok for master?

Regards,
Srinath.

gcc/ChangeLog:

2021-06-10  Srinath Parvathaneni  

PR target/101016
* config/arm/arm_mve.h (__arm_vld1q): Change __ARM_mve_coerce(p0,
int8_t const *) to __ARM_mve_coerce1(p0, int8_t *) in the argument for
the polymorphic variants matching code.
(__arm_vld1q_z): Likewise.
(__arm_vld2q): Likewise.
(__arm_vld4q): Likewise.
(__arm_vldrbq_gather_offset): Likewise.
(__arm_vldrbq_gather_offset_z): Likewise.

gcc/testsuite/ChangeLog:

2021-06-10  Srinath Parvathaneni  

PR target/101016
* gcc.target/arm/mve/intrinsics/pr101016.c: New test.



### Attachment also inlined for ease of reply###


diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h
index 
1380f3acbfe64026bc882c308bb1c243e27ac4b3..83f10036990fc3df956fb2fa4818d1304138b485
 100644
--- a/gcc/config/arm/arm_mve.h
+++ b/gcc/config/arm/arm_mve.h
@@ -37565,47 +37565,47 @@ extern void *__ARM_undef;
 
 #define __arm_vld1q(p0) (\
   _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \
-  int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_s8 (__ARM_mve_coerce(p0, 
int8_t const *)), \
-  int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_s16 (__ARM_mve_coerce(p0, 
int16_t const *)), \
-  int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_s32 (__ARM_mve_coerce(p0, 
int32_t const *)), \
-  int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_u8 (__ARM_mve_coerce(p0, 
uint8_t const *)), \
-  int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_u16 (__ARM_mve_coerce(p0, 
uint16_t const *)), \
-  int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_u32 (__ARM_mve_coerce(p0, 
uint32_t const *)), \
-  int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld1q_f16 (__ARM_mve_coerce(p0, 
float16_t const *)), \
-  int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld1q_f32 (__ARM_mve_coerce(p0, 
float32_t const *
+  int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_s8 (__ARM_mve_coerce1(p0, 
int8_t *)), \
+  int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_s16 (__ARM_mve_coerce1(p0, 
int16_t *)), \
+  int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_s32 (__ARM_mve_coerce1(p0, 
int32_t *)), \
+  int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_u8 (__ARM_mve_coerce1(p0, 
uint8_t *)), \
+  int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_u16 (__ARM_mve_coerce1(p0, 
uint16_t *)), \
+  int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_u32 (__ARM_mve_coerce1(p0, 
uint32_t *)), \
+  int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld1q_f16 
(__ARM_mve_coerce1(p0, float16_t *)), \
+  int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld1q_f32 
(__ARM_mve_coerce1(p0, float32_t *
 
 #define __arm_vld1q_z(p0,p1) ( \
   _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \
-  int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_z_s8 (__ARM_mve_coerce(p0, 
int8_t const *), p1), \
-  int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_z_s16 (__ARM_mve_coerce(p0, 
int16_t const *), p1), \
-  int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_z_s32 (__ARM_mve_coerce(p0, 
int32_t const *), p1), \
-  int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_z_u8 (__ARM_mve_coerce(p0, 
uint8_t const *), p1), \
-  int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_z_u16 
(__ARM_mve_coerce(p0, uint16_t const *), p1), \
-  int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_z_u32 
(__ARM_mve_coerce(p0, uint32_t const *), p1), \
-  int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld1q_z_f16 
(__ARM_mve_coerce(p0, float16_t const *), p1), \
-  int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld1q_z_f32 
(__ARM_mve_coerce(p0, float32_t const *), p1)))
+  int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_z_s8 (__ARM_mve_coerce1(p0, 
int8_t *), p1), \
+  int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_z_s16 
(__ARM_mve_coerce1(p0, int16_t *), p1), \
+  int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_z_s32 
(__ARM_mve_coerce1(p0, int32_t *), p1), \
+  int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_z_u8 (__ARM_mve_coerce1(p0, 
uint8_t *), p1), \
+  int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_z_u16 
(__ARM_mve_coerce1(p0, uint16_t *), p1), \
+  int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_z_u32 
(__ARM_mve_coerce1(p0, uint32_t *), p1), \
+  int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld1q_z_f16 
(__ARM_mve_coerce1(p0, float16_t *), p1), \
+  int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld1q_z_f32 
(__ARM_mve_coerce1(p0, float32_t *), p1)))
 
 #define __arm_vld2q(p0) ( \
   _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \
-  int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld2q_s8 (__ARM_mve_coerce(p0, 
int8_t const *)), \
-  int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld2q_s16 (__ARM_mve_coerce(p0, 
int16_t const *)), \
-  int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld2q_s32 

Re: [Patch] contrib/gcc-changelog: Check that PR in subject in in changelog

2021-06-10 Thread Jonathan Wakely via Gcc-patches
On Thu, 10 Jun 2021 at 15:08, Tobias Burnus wrote:
>
> (Moved to gcc-patches, missed this when I replied to the initial email)
>
> Regarding patch at: https://gcc.gnu.org/pipermail/gcc/2021-June/236357.html
>
> On 10.06.21 14:45, Jonathan Wakely wrote:
>
> > As well as the "contrig" typo that Florian noticed, the subject says
> > "in in" which should be "is in". And it should be CC'd to gcc-patches.
> >
> > I like this more than my attempt, however ...
> >> --- a/contrib/gcc-changelog/git_repository.py
> >> +++ b/contrib/gcc-changelog/git_repository.py
> >> @@ -59,8 +59,9 @@ def parse_git_revisions(repo_path, revisions, 
> >> ref_name=None):
> >>
> >>  date = datetime.utcfromtimestamp(c.committed_date)
> >>  author = '%s  <%s>' % (c.author.name, c.author.email)
> >> -git_info = GitInfo(c.hexsha, date, author,
> >> -   c.message.split('\n'), modified_files)
> >> +message = c.message.split('\n')
> >> +git_info = GitInfo(c.hexsha, date, author, message[0],
> >> +   message[1:], modified_files)
> > Doesn't using message[1:] here mean that other checks which currently
> > look at all of self.info.lines will no longer check the subject line?
> ...
> > For example, we have:
> >  # Skip Update copyright years commits
> >  if self.info.lines and self.info.lines[0] == 'Update copyright 
> > years.':
> >  return
> > This will never match now, because you've extracted that into the
> > 'subject' instead.
>
> Well, it never matched before for git_email.py, it only did match for
> git_repository.py. I think the difference between your work and mine was
> that I started with git_email.py – and you started with git_repository.py.

Yes, because my interest was in making the git gcc-verify alias and
the server hook do the checks, and that works using GitCommit not
GitEmail.

>
> I now pass again the whole message to git_commit.py – also for emails. I
> think that's more consistent when checking for an empty line as second line.
>
> And for the copyright case, I added a testcase :-)

Even better! :-)

> > Aside: We should also have a check that the second line is blank, i.e.
> > the commit message is a single line subject, followed by blank,
> > followed by the body. And if we enforced that, then message[2:] would
> > be better than message[1:].
> Added as check – but I pass now all (also subject + '\n' + body) for the
> email, which I think it easier to grasp.

Nice, thanks.



Re: [PATCH] rs6000: Add new __builtin_vsx_build_pair and __builtin_mma_build_acc built-ins

2021-06-10 Thread Peter Bergner via Gcc-patches
On 6/9/21 4:38 PM, Segher Boessenkool wrote:
> It is better if you *do* document the old names, but say "use the new
> stuff", I think?  Or is there so little material with the old names
> out there that no one will notice?

The latter.  There is only one user, but we want all new uses to use the
new built-in.  Plus, LLVM will be removing their documentation for that
built-in too, so we want to be consistent.



>> +  /* The ASSEMBLE builtin source operands are reversed in little-endian
>> + mode, so reorder them.  */
>> +  if (fcode == VSX_BUILTIN_ASSEMBLE_PAIR_INTERNAL && !WORDS_BIG_ENDIAN)
>> +pat = GEN_FCN (icode) (op[0], op[2], op[1]);
>> +  else
>> +pat = GEN_FCN (icode) (op[0], op[1], op[2]);
> 
> I think this reads simpler as
>   /* The ASSEMBLE builtin source operands are reversed in little-endian
>mode, so reorder them.  */
>   if (fcode == VSX_BUILTIN_ASSEMBLE_PAIR_INTERNAL && !WORDS_BIG_ENDIAN)
>   std::swap (op[1], op[2]);
>   pat = GEN_FCN (icode) (op[0], op[1], op[2]);
> do you agree?

Do I think C++ is simpler than plain C?  Is this a trick question? ;-)
If this is what you want, I'm fine with it.



> And
>   /* The ASSEMBLE builtin source operands are reversed in little-endian
>mode, so reorder them.  */
>   if (fcode == MMA_BUILTIN_AS> +SEMBLE_ACC_INTERNAL && !WORDS_BIG_ENDIAN)
>   {
> std::swap (op[1], [op[4]);
> std::swap (op[2], [op[3]);
>   }
>   pat = GEN_FCN (icode) (op> +[0], op[1], op[2], op[3], op[4]);
> for that then of course.

Ok.


>> @@ -14151,7 +14161,8 @@ mma_init_builtins (void)
>>if (gimple_func && mode == XOmode)
>>  op[nopnds++] = build_pointer_type (vector_quad_type_node);
>>else if (gimple_func && mode == OOmode
> 
> Pleae write the
>&& mode == OOmode
> on a new line as well then?

Will do.


>> +  int index = WORDS_BIG_ENDIAN ? i: nvecs - 1 - i;
> 
> Space before colon.

Ah, thanks for catching that!



> Okay for trunk and 11 with at least that space fixed.  Thanks!

Ok, I'll retest with the above (but still removing the assemble
built-in documentation) and push it if it's clean.  Thanks!

Peter




Re: [Patch] contrib/gcc-changelog: Check that PR in subject in in changelog

2021-06-10 Thread Tobias Burnus

On 10.06.21 16:46, Martin Liška wrote:

Note that flake8 has "plugins". At openSUSE, I install:


... None of those are available on Ubuntu – I probably should nag doko
or start using my private computer for the tests ...

Updated as suggested and with you flake8-fix patch applied on top.

Tobias


-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
 contrib/gcc-changelog/git_commit.py| 32 --
 contrib/gcc-changelog/git_email.py | 22 +++--
 contrib/gcc-changelog/test_email.py| 13 
 contrib/gcc-changelog/test_patches.txt | 60 +-
 gcc/c/c-parser.c   |  4 +--
 5 files changed, 123 insertions(+), 8 deletions(-)
diff --git a/contrib/gcc-changelog/git_commit.py b/contrib/gcc-changelog/git_commit.py
index bd8c1ff7af2..6f33ad9b420 100755
--- a/contrib/gcc-changelog/git_commit.py
+++ b/contrib/gcc-changelog/git_commit.py
@@ -156,7 +156,9 @@ author_line_regex = \
 re.compile(r'^(?P\d{4}-\d{2}-\d{2})\ {2}(?P.*  <.*>)')
 additional_author_regex = re.compile(r'^\t(?P\ *)?(?P.*  <.*>)')
 changelog_regex = re.compile(r'^(?:[fF]or +)?([a-z0-9+-/]*)ChangeLog:?')
-pr_regex = re.compile(r'\tPR (?P[a-z+-]+\/)?([0-9]+)$')
+subject_pr_regex = re.compile(r'(^|\W)PR\s+(?P[a-zA-Z+-]+)/(?P\d{4,7})')
+subject_pr2_regex = re.compile(r'[(\[]PR\s*(?P\d{4,7})[)\]]')
+pr_regex = re.compile(r'\tPR (?P[a-z+-]+\/)?(?P[0-9]+)$')
 dr_regex = re.compile(r'\tDR ([0-9]+)$')
 star_prefix_regex = re.compile(r'\t\*(?P\ *)(?P.*)')
 end_of_location_regex = re.compile(r'[\[<(:]')
@@ -298,6 +300,7 @@ class GitCommit:
 self.top_level_authors = []
 self.co_authors = []
 self.top_level_prs = []
+self.subject_prs = set()
 self.cherry_pick_commit = None
 self.revert_commit = None
 self.commit_to_info_hook = commit_to_info_hook
@@ -307,6 +310,10 @@ class GitCommit:
 if self.info.lines and self.info.lines[0] == 'Update copyright years.':
 return
 
+if self.info.lines and len(self.info.lines) > 1 and self.info.lines[1]:
+self.errors.append(Error('Expected empty second line in commit '
+ 'message', info.lines[0]))
+
 # Identify first if the commit is a Revert commit
 for line in self.info.lines:
 m = revert_regex.match(line)
@@ -316,6 +323,19 @@ class GitCommit:
 if self.revert_commit:
 self.info = self.commit_to_info_hook(self.revert_commit)
 
+# The following happens for get_email.py:
+if not self.info:
+return
+
+# Extract PR numbers form the subject line
+# Match either [PR] / (PR) or PR component/
+if self.info.lines and not self.revert_commit:
+self.subject_prs = {m.group('pr') for m in subject_pr2_regex.finditer(info.lines[0])}
+for m in subject_pr_regex.finditer(info.lines[0]):
+if not m.group('component') in bug_components:
+self.errors.append(Error('invalid PR component in subject', info.lines[0]))
+self.subject_prs.add(m.group('pr'))
+
 # Allow complete deletion of ChangeLog files in a commit
 project_files = [f for f in self.info.modified_files
  if (self.is_changelog_filename(f[0], allow_suffix=True) and f[1] != 'D')
@@ -346,6 +366,10 @@ class GitCommit:
 if not self.errors:
 self.check_mentioned_files()
 self.check_for_correct_changelog()
+if self.subject_prs:
+self.errors.append(Error('PR %s in subject but not in changelog' %
+ ', '.join(self.subject_prs),
+ self.info.lines[0]))
 
 @property
 def success(self):
@@ -460,7 +484,9 @@ class GitCommit:
 else:
 author_tuple = (m.group('name'), None)
 elif pr_regex.match(line):
-component = pr_regex.match(line).group('component')
+m = pr_regex.match(line)
+component = m.group('component')
+pr = m.group('pr')
 if not component:
 self.errors.append(Error('missing PR component', line))
 continue
@@ -469,6 +495,8 @@ class GitCommit:
 continue
 else:
 pr_line = line.lstrip()
+if pr in self.subject_prs:
+self.subject_prs.remove(pr)
 elif dr_regex.match(line):
 pr_line = line.lstrip()
 
diff --git a/contrib/gcc-changelog/git_email.py b/contrib/gcc-changelog/git_email.py
index fa62e3ad2f7..87b419cae5d 100755
--- 

[PATCH] rs6000: Fix *TItype_ppc

2021-06-10 Thread Segher Boessenkool
The *TItype_ppc definitions are guarded by _ARCH_PPC64, so all
declarations using it should do so as well.

This fixes it.  Committed to trunk.


Segher


2021-06-10  Segher Boessenkool  
libgcc/
* config/rs6000/quad-float128.h: Guard all uses of [U]TItype_ppc by
_ARCH_PPC64 .

---
 libgcc/config/rs6000/quad-float128.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/libgcc/config/rs6000/quad-float128.h 
b/libgcc/config/rs6000/quad-float128.h
index c4d775b4ad3f..c7f2b77ed357 100644
--- a/libgcc/config/rs6000/quad-float128.h
+++ b/libgcc/config/rs6000/quad-float128.h
@@ -88,12 +88,16 @@ extern USItype_ppc __fixunskfsi_sw (TFtype);
 extern UDItype_ppc __fixunskfdi_sw (TFtype);
 extern TFtype __floatsikf_sw (SItype_ppc);
 extern TFtype __floatdikf_sw (DItype_ppc);
+#ifdef _ARCH_PPC64
 extern TFtype __floattikf_sw (TItype_ppc);
+#endif
 extern TFtype __floatunsikf_sw (USItype_ppc);
 extern TFtype __floatundikf_sw (UDItype_ppc);
+#ifdef _ARCH_PPC64
 extern TFtype __floatuntikf_sw (UTItype_ppc);
 extern TItype_ppc __fixkfti_sw (TFtype);
 extern UTItype_ppc __fixunskfti_sw (TFtype);
+#endif
 extern IBM128_TYPE __extendkftf2_sw (TFtype);
 extern TFtype __trunctfkf2_sw (IBM128_TYPE);
 extern TCtype __mulkc3_sw (TFtype, TFtype, TFtype, TFtype);
@@ -130,12 +134,16 @@ extern USItype_ppc __fixunskfsi_hw (TFtype);
 extern UDItype_ppc __fixunskfdi_hw (TFtype);
 extern TFtype __floatsikf_hw (SItype_ppc);
 extern TFtype __floatdikf_hw (DItype_ppc);
+#ifdef _ARCH_PPC64
 extern TFtype __floattikf_hw (TItype_ppc);
+#endif
 extern TFtype __floatunsikf_hw (USItype_ppc);
 extern TFtype __floatundikf_hw (UDItype_ppc);
+#ifdef _ARCH_PPC64
 extern TFtype __floatuntikf_hw (UTItype_ppc);
 extern TItype_ppc __fixkfti_hw (TFtype);
 extern UTItype_ppc __fixunskfti_hw (TFtype);
+#endif
 extern IBM128_TYPE __extendkftf2_hw (TFtype);
 extern TFtype __trunctfkf2_hw (IBM128_TYPE);
 extern TCtype __mulkc3_hw (TFtype, TFtype, TFtype, TFtype);
@@ -166,12 +174,16 @@ extern USItype_ppc __fixunskfsi (TFtype);
 extern UDItype_ppc __fixunskfdi (TFtype);
 extern TFtype __floatsikf (SItype_ppc);
 extern TFtype __floatdikf (DItype_ppc);
+#ifdef _ARCH_PPC64
 extern TFtype __floattikf (TItype_ppc);
+#endif
 extern TFtype __floatunsikf (USItype_ppc);
 extern TFtype __floatundikf (UDItype_ppc);
+#ifdef _ARCH_PPC64
 extern TFtype __floatuntikf (UTItype_ppc);
 extern TItype_ppc __fixkfti (TFtype);
 extern UTItype_ppc __fixunskfti (TFtype);
+#endif
 extern IBM128_TYPE __extendkftf2 (TFtype);
 extern TFtype __trunctfkf2 (IBM128_TYPE);
 
-- 
1.8.3.1



Re: [PATCH] Modula-2 into the GCC tree on master

2021-06-10 Thread Gaius Mulley via Gcc-patches
Matthias Klose  writes:

> On 1/18/21 2:55 PM, Gaius Mulley via Gcc-patches wrote:
>> Richard Biener  writes:
>>> I've just done ./configure --enable-languages=m2; make -j24
>>>
>>> I would suggest to not rush this in now during stage4
>>> but instead take the opportunity of this "quiet" phase
>>> to prepare an integration branch with all the issues above
>>> sorted out which we can merge at the beginning of stage1
>>> for GCC 12 (or later during stage4 if everyone is happy
>>> and/or backport for GCC 11.2 when it landed in trunk).
>>
>> ok sure - this sounds a good plan
>
> Gaius, now with the 1.1 relase out of the door, please could you clarify about
> your plans getting this into trunk, and do you plan to get this into 11.2 as 
> well?
>
> Thanks, Matthias

Hello Matthias and Richard,

just a small update to say that I think all the code changes are done -
I've a tiny amount of documentation texinfo file moving / reorganising
then testing and then the patches will be posted.


regards,
Gaius


Re: [PATCH] Use auto_vec in ssa_equiv_stack.

2021-06-10 Thread Jeff Law via Gcc-patches




On 6/10/2021 2:46 AM, Aldy Hernandez via Gcc-patches wrote:

There is a mismatch between the new and the delete for the
ssa_equiv_stack class.  The correct idiom should have been delete[].
It has been pointed out that perhaps a better alternative is to use
an auto_vec which does everything automatically.  Plus, it is more
consistent with m_stack which is already an auto_vec.

This patch fixes the issue in PR100984.

Tested on x86-64 Linux.

OK?

gcc/ChangeLog:

 PR tree-optimization/100984
* gimple-ssa-evrp.c (ssa_equiv_stack::~ssa_equiv_stack):

ChangeLog entry got truncated.

Otherwise, LGTM.  Getting rid of manual memory management is a win in my 
book.


jeff



Re: [Patch] contrib/gcc-changelog: Check that PR in subject in in changelog

2021-06-10 Thread Martin Liška

On 6/10/21 4:42 PM, Tobias Burnus wrote:

On 10.06.21 16:24, Martin Liška wrote:


I'm sending a small update that handles some flake8 issues and as
defined in setup.cfg,
line limit for the file is 120 characters.

Aha, the known issue that Ubuntu 20.04 has a too old flake8 such that I
only see a subset of the errors ...


Note that flake8 has "plugins". At openSUSE, I install:

python3-flake8
python3-flake8-builtins
python3-flake8-bugbear
python3-flake8-import-order
python3-flake8-quotes
python3-flake8-comprehensions


I have one question: Do we really need the revert regex? What about
using GitCommit::revert_commit?


I think it would be fine – glancing at recent commits, I think only the
following would be rejected:


Good, I would use it then.

Martin



* https://gcc.gnu.org/g:0886426f5f543e813c1a61e18da6616caf377dfc

And one can argue about whether it should or shouldn't be rejected. The
other commits I found either have the 'This reverts commit' line –
and/or have the PR both in the subject and in the changelog part.

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf




Re: [PATCH] c++: Add C++23 consteval if support - P1938R3 [PR100974]

2021-06-10 Thread Jakub Jelinek via Gcc-patches
On Thu, Jun 10, 2021 at 10:09:26AM -0400, Jason Merrill wrote:
> > --- gcc/cp/parser.c.jj  2021-06-09 21:54:39.482193853 +0200
> > +++ gcc/cp/parser.c 2021-06-10 10:09:23.753052980 +0200
> > @@ -10902,6 +10902,11 @@ cp_parser_lambda_expression (cp_parser*
> >   bool discarded = in_discarded_stmt;
> >   in_discarded_stmt = 0;
> > +/* Similarly the body of a lambda in immediate function context is not
> > +   in immediate function context.  */
> > +bool immediate_fn_ctx_p = in_immediate_fn_ctx_p;
> 
> It's hard to distinguish between these two names when reading the code;
> let's give the local variable a name including "saved".

Will do.

> > +   if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
> > + error ("% requires compound statement");
> > +
> > +   in_immediate_fn_ctx_p |= ce > 0;
> > +   cp_parser_implicitly_scoped_statement (parser, NULL, guard_tinfo);
> 
> Maybe use cp_parser_compound_statement directly instead of this and checking
> CPP_OPEN_BRACE above?  Either way is fine.

I thought doing it this way will provide better diagnostics for what I think
can be a common bug - people so used to normal if not requiring compound
statements forgetting those {}s from time to time.

> > +  if (TREE_CODE (t) == IF_STMT && IF_STMT_CONSTEVAL_P (t))
> > +{
> > +  /* Evaluate the condition as if it was
> > +if (__builtin_is_constant_evaluated ()).  */
> > +  if (ctx->manifestly_const_eval)
> > +   val = boolean_true_node;
> > +  else
> > +   {
> > + *non_constant_p = true;
> > + return t;
> > +   }
> 
> Why set *non_constant_p?  Shouldn't this just be
> 
> val = boolean_false_node;
> 
> so we constant-evaluate the else clause when we are trying to
> constant-evaluate in a non-manifestly-constant-evaluated context?

It matches what we do for CP_BUILT_IN_IS_CONSTANT_EVALUATED calls:
  /* For __builtin_is_constant_evaluated, defer it if not
 ctx->manifestly_const_eval, otherwise fold it to true.  */
  if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
 BUILT_IN_FRONTEND))
{
  if (!ctx->manifestly_const_eval)
{
  *non_constant_p = true;
  return t;
}
  return boolean_true_node;
}
I believe we sometimes try to constexpr evaluate something without
having manifestly_const_eval = true even on expressions that
are in manifestly constant evaluated contexts and am worried if
we just folded it to boolean_false_node we could get a constant expression
and replace the expression with that, even before we actually try to
constant evaluate it with manifestly_const_eval = true.

If I do (for the CP_BUILT_IN_IS_CONSTANT_EVALUATED):
--- gcc/cp/constexpr.c.jj   2021-06-10 15:27:31.123353594 +0200
+++ gcc/cp/constexpr.c  2021-06-10 16:26:38.368168281 +0200
@@ -1320,10 +1320,7 @@ cxx_eval_builtin_function_call (const co
 BUILT_IN_FRONTEND))
 {
   if (!ctx->manifestly_const_eval)
-   {
- *non_constant_p = true;
- return t;
-   }
+   return boolean_false_node;
   return boolean_true_node;
 }
 
then
FAIL: g++.dg/cpp2a/is-constant-evaluated1.C  -std=c++14 execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated1.C  -std=c++17 execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated1.C  -std=c++2a execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated1.C  -std=c++17 -fconcepts execution 
test
FAIL: g++.dg/cpp2a/is-constant-evaluated2.C  -std=c++14 execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated2.C  -std=c++17 execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated2.C  -std=c++2a execution test
FAIL: g++.dg/cpp2a/is-constant-evaluated2.C  -std=c++17 -fconcepts execution 
test
FAIL: g++.dg/cpp2a/is-constant-evaluated9.C  -std=gnu++2a (test for excess 
errors)
at least regresses.

> > +  if (TREE_CODE (t) != IF_STMT || !IF_STMT_CONSTEVAL_P (t))
> > +   {
> > + if (integer_zerop (tmp))
> > +   return RECUR (TREE_OPERAND (t, 2), want_rval);
> > + else if (TREE_CODE (tmp) == INTEGER_CST)
> > +   return RECUR (TREE_OPERAND (t, 1), want_rval);
> > +   }
> 
> Don't we still want to shortcut consideration of one of the arms for if
> consteval?

potential_constant_expression_p{,_1} doesn't get passed whether it is
manifestly_const_eval or not.

> > --- gcc/cp/cp-gimplify.c.jj 2021-06-09 21:54:39.473193977 +0200
> > +++ gcc/cp/cp-gimplify.c2021-06-10 09:49:35.898557178 +0200
> > @@ -161,7 +161,9 @@ genericize_if_stmt (tree *stmt_p)
> > if (!else_)
> >   else_ = build_empty_stmt (locus);
> > -  if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
> > +  if (IF_STMT_CONSTEVAL_P (stmt))
> > +stmt = else_;
> 
> This seems redundant, since you're using boolean_false_node for the
> condition.

It is only when !TREE_SIDE_EFFECTS (else_).
I think that is about having labels in the then_/else_ blocks and
gotos jumping into those from outside.
But IF_STMT_CONSTEVAL_P 

Re: [Patch] contrib/gcc-changelog: Check that PR in subject in in changelog

2021-06-10 Thread Tobias Burnus

On 10.06.21 16:24, Martin Liška wrote:


I'm sending a small update that handles some flake8 issues and as
defined in setup.cfg,
line limit for the file is 120 characters.

Aha, the known issue that Ubuntu 20.04 has a too old flake8 such that I
only see a subset of the errors ...

I have one question: Do we really need the revert regex? What about
using GitCommit::revert_commit?


I think it would be fine – glancing at recent commits, I think only the
following would be rejected:

* https://gcc.gnu.org/g:0886426f5f543e813c1a61e18da6616caf377dfc

And one can argue about whether it should or shouldn't be rejected. The
other commits I found either have the 'This reverts commit' line –
and/or have the PR both in the subject and in the changelog part.

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf


Re: [PATCH] libstdc++: Skip atomic instructions in _Sp_counted_base::_M_release when both counts are 1

2021-06-10 Thread Maged Michael via Gcc-patches
Would appreciate any comments on this proposed patch.

Thanks,
Maged


On Thu, Dec 17, 2020 at 3:49 PM Maged Michael 
wrote:

> Please find a proposed patch for _Sp_counted_base::_M_release to skip the
> two atomic instructions that decrement each of the use count and the weak
> count when both are 1. I proposed the general idea in an earlier thread (
> https://gcc.gnu.org/pipermail/libstdc++/2020-December/051642.html) and
> got useful feedback on a draft patch and responses to related questions
> about multi-granular atomicity and alignment. This patch is based on that
> feedback.
>
>
> I added a check for thread sanitizer to use the current algorithm in that
> case because TSAN does not support multi-granular atomicity. I'd like to
> add a check of __has_feature(thread_sanitizer) for building using LLVM. I
> found examples of __has_feature in libstdc++ but it doesn't seem to be
> recognized in shared_ptr_base.h. Any guidance on how to check
> __has_feature(thread_sanitizer) in this patch?
>
>
> GCC generates code for _M_release that is larger and more complex than
> that generated by LLVM. I'd like to file a bug report about that. Jonathan,
> would you please create a bugzilla account for me (
> https://gcc.gnu.org/bugzilla/) using my gmail address. Thank you.
>
>
> Information about the patch:
>
> - Benefits of the patch: Save the cost of the last atomic decrements of
> each of the use count and the weak count in _Sp_counted_base. Atomic
> instructions are significantly slower than regular loads and stores across
> major architectures.
>
> - How current code works: _M_release() atomically decrements the use
> count, checks if it was 1, if so calls _M_dispose(), atomically decrements
> the weak count, checks if it was 1, and if so calls _M_destroy().
>
> - How the proposed patch works: _M_release() loads both use count and weak
> count together atomically (when properly aligned), checks if the value is
> equal to the value of both counts equal to 1 (e.g., 0x10001), and if so
> calls _M_dispose() and _M_destroy(). Otherwise, it follows the original
> algorithm.
>
> - Why it works: When the current thread executing _M_release() finds each
> of the counts is equal to 1, then (when _lock_policy is _S_atomic) no other
> threads could possibly hold use or weak references to this control block.
> That is, no other threads could possibly access the counts or the protected
> object.
>
> - The proposed patch is intended to interact correctly with current code
> (under certain conditions: _Lock_policy is _S_atomic, proper alignment, and
> native lock-free support for atomic operations). That is, multiple threads
> using different versions of the code with and without the patch operating
> on the same objects should always interact correctly. The intent for the
> patch is to be ABI compatible with the current implementation.
>
> - The proposed patch involves a performance trade-off between saving the
> costs of two atomic instructions when the counts are both 1 vs adding the
> cost of loading the combined counts and comparison with two ones (e.g.,
> 0x10001).
>
> - The patch has been in use (built using LLVM) in a large environment for
> many months. The performance gains outweigh the losses (roughly 10 to 1)
> across a large variety of workloads.
>
>
> I'd appreciate feedback on the patch and any suggestions for checking
> __has_feature(thread_sanitizer).
>
>
> Maged
>
>
>
> diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h
> b/libstdc++-v3/include/bits/shared_ptr_base.h
>
> index 368b2d7379a..a8fc944af5f 100644
>
> --- a/libstdc++-v3/include/bits/shared_ptr_base.h
>
> +++ b/libstdc++-v3/include/bits/shared_ptr_base.h
>
> @@ -153,20 +153,78 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> if (!_M_add_ref_lock_nothrow())
>
>   __throw_bad_weak_ptr();
>
>}
>
>
>bool
>
>_M_add_ref_lock_nothrow() noexcept;
>
>
>void
>
>_M_release() noexcept
>
>{
>
> +#if __SANITIZE_THREAD__
>
> +_M_release_orig();
>
> +return;
>
> +#endif
>
> +if (!__atomic_always_lock_free(sizeof(long long), 0) ||
>
> +!__atomic_always_lock_free(sizeof(_Atomic_word), 0) ||
>
> +sizeof(long long) < (2 * sizeof(_Atomic_word)) ||
>
> +sizeof(long long) > (sizeof(void*)))
>
> +  {
>
> +_M_release_orig();
>
> +return;
>
> +  }
>
> +_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
>
> +_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
>
> +if (__atomic_load_n((long long*)(&_M_use_count),
> __ATOMIC_ACQUIRE)
>
> +== (1LL + (1LL << (8 * sizeof(_Atomic_word)
>
> +  {
>
> +// Both counts are 1, so there are no weak references and
>
> +// we are releasing the last strong reference. No other
>
> +// threads can observe the effects of this _M_release()
>
> +// call (e.g. calling 

Re: [PATCH] c++: Extend std::is_constant_evaluated in if warning [PR100995]

2021-06-10 Thread Jason Merrill via Gcc-patches

On 6/9/21 9:46 PM, Marek Polacek wrote:

Jakub pointed me at

which shows that our existing warning could be extended to handle more
cases.  This patch implements that.

A minor annoyance was handling macros, in libstdc++ we have

   reference operator[](size_type __pos) {
   __glibcxx_assert(__pos <= size());
   ...
   }

wherein __glibcxx_assert expands to

   if (__builtin_is_constant_evaluated() && !bool(__pos <= size())
 ...

but I'm of a mind to not warn on that.

Possible tweaks: merge the "always true" warnings and say something
about a manifestly evaluated context, and perhaps add an early exit
for TREE_CONSTANT trees because for constexpr if we are going to call
maybe_warn_for_constant_evaluated twice.

Once consteval if makes it in, we should tweak this warning one more
time.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

PR c++/100995

gcc/cp/ChangeLog:

* semantics.c (find_std_constant_evaluated_r): New.
(maybe_warn_for_constant_evaluated): New.
(finish_if_stmt_cond): Call it.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/is-constant-evaluated9.C: Add dg-warning.
* g++.dg/cpp2a/is-constant-evaluated12.C: New test.
---
  gcc/cp/semantics.c| 85 ---
  .../g++.dg/cpp2a/is-constant-evaluated12.C| 79 +
  .../g++.dg/cpp2a/is-constant-evaluated9.C |  4 +-
  3 files changed, 152 insertions(+), 16 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated12.C

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index f506a239864..07459a357e2 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -927,6 +927,75 @@ is_std_constant_evaluated_p (tree fn)
return name && id_equal (name, "is_constant_evaluated");
  }
  
+/* Callback function for maybe_warn_for_constant_evaluated that looks

+   for calls to std::is_constant_evaluated in TP.  */
+
+static tree
+find_std_constant_evaluated_r (tree *tp, int *walk_subtrees, void *)
+{
+  tree t = *tp;
+
+  if (TYPE_P (t) || TREE_CONSTANT (t))
+{
+  *walk_subtrees = false;
+  return NULL_TREE;
+}
+
+  switch (TREE_CODE (t))
+{
+case CALL_EXPR:
+  if (is_std_constant_evaluated_p (t))
+   return t;
+  break;
+case EXPR_STMT:
+  /* Don't warn in statement expressions.  */
+  *walk_subtrees = false;
+  return NULL_TREE;
+default:
+  break;
+}
+
+  return NULL_TREE;
+}
+
+/* In certain contexts, std::is_constant_evaluated() is always true (for
+   instance, in a consteval function or in a constexpr if), or always false
+   (e.g., in a non-constexpr non-consteval function) so give the user a clue.  
*/
+
+static void
+maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if)
+{
+  if (!warn_tautological_compare)
+return;
+
+  /* Suppress warning for std::is_constant_evaluated if the conditional
+ comes from a macro.  */
+  if (from_macro_expansion_at (EXPR_LOCATION (cond)))
+return;
+
+  cond = cp_walk_tree_without_duplicates (, find_std_constant_evaluated_r,
+ NULL);
+  if (cond)
+{
+  if (constexpr_if)
+   warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
+   "% always evaluates to "
+   "true in %");
+  else if (!DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+  /* C++17 lambda op() is implicitly constexpr but finish_function
+ may not have marked it as such.  */
+  && !(cxx_dialect >= cxx17
+   && LAMBDA_TYPE_P (CP_DECL_CONTEXT (current_function_decl


Let's factor a new maybe_constexpr_fn out of var_in_maybe_constexpr_fn.


+   warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
+   "% always evaluates to "
+   "false in a non-% function");
+  else if (DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
+   warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
+   "% always evaluates to "
+   "true in a % function");
+}
+}
+
  /* Process the COND of an if-statement, which may be given by
 IF_STMT.  */
  
@@ -942,23 +1011,11 @@ finish_if_stmt_cond (tree cond, tree if_stmt)

 converted to bool.  */
&& TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
  {
-  /* if constexpr (std::is_constant_evaluated()) is always true,
-so give the user a clue.  */
-  if (warn_tautological_compare)
-   {
- tree t = cond;
- if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
-   t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == CALL_EXPR
- && is_std_constant_evaluated_p (t))
-   warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
-   "%qs always evaluates to true in %",
-

Re: [Patch] contrib/gcc-changelog: Check that PR in subject in in changelog

2021-06-10 Thread Martin Liška

On 6/10/21 4:07 PM, Tobias Burnus wrote:

(Moved to gcc-patches, missed this when I replied to the initial email)

Regarding patch at: https://gcc.gnu.org/pipermail/gcc/2021-June/236357.html

On 10.06.21 14:45, Jonathan Wakely wrote:


As well as the "contrig" typo that Florian noticed, the subject says
"in in" which should be "is in". And it should be CC'd to gcc-patches.

I like this more than my attempt, however ...

--- a/contrib/gcc-changelog/git_repository.py
+++ b/contrib/gcc-changelog/git_repository.py
@@ -59,8 +59,9 @@ def parse_git_revisions(repo_path, revisions, ref_name=None):

 date = datetime.utcfromtimestamp(c.committed_date)
 author = '%s  <%s>' % (c.author.name, c.author.email)
-    git_info = GitInfo(c.hexsha, date, author,
-   c.message.split('\n'), modified_files)
+    message = c.message.split('\n')
+    git_info = GitInfo(c.hexsha, date, author, message[0],
+   message[1:], modified_files)

Doesn't using message[1:] here mean that other checks which currently
look at all of self.info.lines will no longer check the subject line?

...

For example, we have:
 # Skip Update copyright years commits
 if self.info.lines and self.info.lines[0] == 'Update copyright years.':
 return
This will never match now, because you've extracted that into the
'subject' instead.


Well, it never matched before for git_email.py, it only did match for
git_repository.py. I think the difference between your work and mine was
that I started with git_email.py – and you started with git_repository.py.

I now pass again the whole message to git_commit.py – also for emails. I
think that's more consistent when checking for an empty line as second line.


I see this approach better.



And for the copyright case, I added a testcase :-)


Aside: We should also have a check that the second line is blank, i.e.
the commit message is a single line subject, followed by blank,
followed by the body. And if we enforced that, then message[2:] would
be better than message[1:].

Added as check – but I pass now all (also subject + '\n' + body) for the
email, which I think it easier to grasp. But as three is always an empty
line for emails (to separate header and body), I cannot add a testcase
for it, unfortunately.

Updated patch enclosed.


I'm sending a small update that handles some flake8 issues and as defined in 
setup.cfg,
line limit for the file is 120 characters.

I have one question: Do we really need the revert regex? What about using 
GitCommit::revert_commit?

Cheers,
Martin



Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf


diff --git a/contrib/gcc-changelog/git_commit.py b/contrib/gcc-changelog/git_commit.py
index 6752ca8..cdafb17968c 100755
--- a/contrib/gcc-changelog/git_commit.py
+++ b/contrib/gcc-changelog/git_commit.py
@@ -157,8 +157,7 @@ author_line_regex = \
 additional_author_regex = re.compile(r'^\t(?P\ *)?(?P.*  <.*>)')
 changelog_regex = re.compile(r'^(?:[fF]or +)?([a-z0-9+-/]*)ChangeLog:?')
 subject_pr_skip_regex = re.compile(r'[Rr]evert')
-subject_pr_regex = \
-re.compile(r'(^|\W)PR\s+(?P[a-zA-Z+-]+)/(?P\d{4,7})')
+subject_pr_regex = re.compile(r'(^|\W)PR\s+(?P[a-zA-Z+-]+)/(?P\d{4,7})')
 subject_pr2_regex = re.compile(r'[(\[]PR\s*(?P\d{4,7})[)\]]')
 pr_regex = re.compile(r'\tPR (?P[a-z+-]+\/)?(?P[0-9]+)$')
 dr_regex = re.compile(r'\tDR ([0-9]+)$')
@@ -312,20 +311,16 @@ class GitCommit:
 if self.info.lines and self.info.lines[0] == 'Update copyright years.':
 return
 
-if len(self.info.lines) > 1 and self.info.lines[1] != '':
-self.errors.append(Error('Expected empty second line in commit message',
- info.lines[0]))
+if len(self.info.lines) > 1 and self.info.lines[1]:
+self.errors.append(Error('Expected empty second line in commit message', info.lines[0]))
 
 # Extract PR numbers form the subject line
 # Match either [PR] / (PR) or PR component/
 if self.info.lines and not subject_pr_skip_regex.search(info.lines[0]):
-self.subject_prs = \
- set([m.group('pr')
-  for m in subject_pr2_regex.finditer(info.lines[0])])
+self.subject_prs = {m.group('pr') for m in subject_pr2_regex.finditer(info.lines[0])}
 for m in subject_pr_regex.finditer(info.lines[0]):
 if not m.group('component') in bug_components:
-self.errors.append(Error('invalid PR component in subject',
- info.lines[0]))
+self.errors.append(Error('invalid PR component in subject', info.lines[0]))
 self.subject_prs.add(m.group('pr'))
 
 # Identify first if 

Re: [PATCH] c++: Add C++23 consteval if support - P1938R3 [PR100974]

2021-06-10 Thread Jason Merrill via Gcc-patches

On 6/10/21 4:34 AM, Jakub Jelinek wrote:

Hi!

The following patch implements consteval if support.


Great!


There is a new IF_STMT_CONSTEVAL_P flag on IF_STMT and IF_COND is
boolean_false_node to match the non-manifestly constant evaluation
behavior, while constexpr evaluation special-cases it.  Perhaps cleaner
would be to set the condition to __builtin_is_constant_evaluated () call
but we need the IF_STMT_CONSTEVAL_P flag anyway and the IL would be larger.

I'm not 100% sure whether lambda body is enclosed by the surrounding
statement, I'm assuming it is not - see consteval-if10.C testcase.


Correct.


Also, the paper doesn't contain the exact __cpp_if_consteval value,
but https://github.com/cplusplus/draft/pull/4660/files mentions 202106L
which this patch uses.

And I'm not changing the libstdc++ side, where perhaps we could change
std::is_constant_evaluated definition for
#ifdef __cpp_if_consteval
case to if consteval { return true; } else { return false; }
but we need to keep it defined to __builtin_is_constant_evaluated ()
for C++20 or older.

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

2021-06-10  Jakub Jelinek  

PR c++/100974 - P1938R3 - if consteval
gcc/c-family/
* c-cppbuiltin.c (c_cpp_builtins): Predefine __cpp_if_consteval for
-std=c++2b.
gcc/cp/
* cp-tree.h (struct saved_scope): Add immediate_fn_ctx_p
member.
(in_immediate_fn_ctx_p, IF_STMT_CONSTEVAL_P): Define.
* parser.c (cp_parser_lambda_expression): Temporarily disable
in_immediate_fn_ctx_p when parsing lambda body.
(cp_parser_selection_statement): Parse consteval if.
* decl.c (struct named_label_entry): Add in_consteval_if member.
(level_for_consteval_if): New function.
(poplevel_named_label_1, check_previous_goto_1, check_goto): Handle
consteval if.
* constexpr.c (cxx_eval_conditional_expression): For
IF_STMT_CONSTEVAL_P evaluate condition as if it was
__builtin_is_constant_evaluated call.
(potential_constant_expression_1): For IF_STMT_CONSTEVAL_P always
recurse on both branches.
* cp-gimplify.c (genericize_if_stmt): Genericize IF_STMT_CONSTEVAL_P
as the else branch.
* pt.c (tsubst_expr) : Copy IF_STMT_CONSTEVAL_P.
Temporarily set in_immediate_fn_ctx_p when recursing on
IF_STMT_CONSTEVAL_P then branch.
(tsubst_lambda_expr): Temporarily disable
in_immediate_fn_ctx_p when instantiating lambda body.
* call.c (immediate_invocation_p): Return false when
in_immediate_fn_ctx_p.
gcc/testsuite/
* g++.dg/cpp23/consteval-if1.C: New test.
* g++.dg/cpp23/consteval-if2.C: New test.
* g++.dg/cpp23/consteval-if3.C: New test.
* g++.dg/cpp23/consteval-if4.C: New test.
* g++.dg/cpp23/consteval-if5.C: New test.
* g++.dg/cpp23/consteval-if6.C: New test.
* g++.dg/cpp23/consteval-if7.C: New test.
* g++.dg/cpp23/consteval-if8.C: New test.
* g++.dg/cpp23/consteval-if9.C: New test.
* g++.dg/cpp23/consteval-if10.C: New test.
* g++.dg/cpp23/feat-cxx2b.C: Add __cpp_if_consteval tests.

--- gcc/c-family/c-cppbuiltin.c.jj  2021-06-09 21:54:39.433194531 +0200
+++ gcc/c-family/c-cppbuiltin.c 2021-06-10 09:49:35.776558874 +0200
@@ -1029,6 +1029,7 @@ c_cpp_builtins (cpp_reader *pfile)
{
  /* Set feature test macros for C++23.  */
  cpp_define (pfile, "__cpp_size_t_suffix=202011L");
+ cpp_define (pfile, "__cpp_if_consteval=202106L");
}
if (flag_concepts)
  {
--- gcc/cp/cp-tree.h.jj 2021-06-09 21:54:39.474193964 +0200
+++ gcc/cp/cp-tree.h2021-06-10 09:49:35.795558610 +0200
@@ -478,6 +478,7 @@ extern GTY(()) tree cp_global_trees[CPTI
AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR)
CONSTRUCTOR_MUTABLE_POISON (in CONSTRUCTOR)
OVL_HIDDEN_P (in OVERLOAD)
+  IF_STMT_CONSTEVAL_P (in IF_STMT)
SWITCH_STMT_NO_BREAK_P (in SWITCH_STMT)
LAMBDA_EXPR_CAPTURE_OPTIMIZED (in LAMBDA_EXPR)
IMPLICIT_CONV_EXPR_BRACED_INIT (in IMPLICIT_CONV_EXPR)
@@ -1816,6 +1817,7 @@ struct GTY(()) saved_scope {
  /* Nonzero if we are parsing the discarded statement of a constexpr
 if-statement.  */
BOOL_BITFIELD discarded_stmt : 1;
+  BOOL_BITFIELD immediate_fn_ctx_p : 1;
  
int unevaluated_operand;

int inhibit_evaluation_warnings;
@@ -1879,6 +1881,7 @@ extern GTY(()) struct saved_scope *scope
  #define processing_explicit_instantiation 
scope_chain->x_processing_explicit_instantiation
  
  #define in_discarded_stmt scope_chain->discarded_stmt

+#define in_immediate_fn_ctx_p scope_chain->immediate_fn_ctx_p
  
  #define current_ref_temp_count scope_chain->ref_temp_count
  
@@ -5211,6 +5214,7 @@ more_aggr_init_expr_args_p (const aggr_i

  #define ELSE_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 2)
  #define IF_SCOPE(NODE)TREE_OPERAND 

Re: [Patch] contrib/gcc-changelog: Check that PR in subject in in changelog

2021-06-10 Thread Tobias Burnus

(Moved to gcc-patches, missed this when I replied to the initial email)

Regarding patch at: https://gcc.gnu.org/pipermail/gcc/2021-June/236357.html

On 10.06.21 14:45, Jonathan Wakely wrote:


As well as the "contrig" typo that Florian noticed, the subject says
"in in" which should be "is in". And it should be CC'd to gcc-patches.

I like this more than my attempt, however ...

--- a/contrib/gcc-changelog/git_repository.py
+++ b/contrib/gcc-changelog/git_repository.py
@@ -59,8 +59,9 @@ def parse_git_revisions(repo_path, revisions, ref_name=None):

 date = datetime.utcfromtimestamp(c.committed_date)
 author = '%s  <%s>' % (c.author.name, c.author.email)
-git_info = GitInfo(c.hexsha, date, author,
-   c.message.split('\n'), modified_files)
+message = c.message.split('\n')
+git_info = GitInfo(c.hexsha, date, author, message[0],
+   message[1:], modified_files)

Doesn't using message[1:] here mean that other checks which currently
look at all of self.info.lines will no longer check the subject line?

...

For example, we have:
 # Skip Update copyright years commits
 if self.info.lines and self.info.lines[0] == 'Update copyright years.':
 return
This will never match now, because you've extracted that into the
'subject' instead.


Well, it never matched before for git_email.py, it only did match for
git_repository.py. I think the difference between your work and mine was
that I started with git_email.py – and you started with git_repository.py.

I now pass again the whole message to git_commit.py – also for emails. I
think that's more consistent when checking for an empty line as second line.

And for the copyright case, I added a testcase :-)


Aside: We should also have a check that the second line is blank, i.e.
the commit message is a single line subject, followed by blank,
followed by the body. And if we enforced that, then message[2:] would
be better than message[1:].

Added as check – but I pass now all (also subject + '\n' + body) for the
email, which I think it easier to grasp. But as three is always an empty
line for emails (to separate header and body), I cannot add a testcase
for it, unfortunately.

Updated patch enclosed.

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
contrib/gcc-changelog: Check that PR in subject is in changelog

This patch checks that a '[PR]' and '(PR)' also appears as PR in the
changelog part of the commit message.  And it does likewise for 'PR comp/'
except that then also the component name is checked.  (Note that the reverse
is permitted, i.e. PR(s) only appearing in the changelog.)
To avoid false positives, PR numbers in the subject line are ignored,
if 'revert' appears.
Additionally, reject commits with a nonempty second line.

contrib/ChangeLog:

	* gcc-changelog/git_commit.py (pr_regex): Add ?P for group('pr').
	(subject_pr_skip_regex, subject_pr_regex, subject_pr2_regex): New.
	(GitInfo.__init__, GitCommit.parse_changelog): Check subject PRs.
	* gcc-changelog/git_email.py (SUBJECT_PREFIX, subject_patch_regex): New.
	(GitEmail.__init__): Parse 'Subject:' and pass it to GitInfo.
	* gcc-changelog/test_email.py (test_pr_only_in_subject,
	test_wrong_pr_comp_in_subject, test_copyright_years): New.
	* gcc-changelog/test_patches.txt (0030-PR-c-92746, pr-check1.patch):
	Update to avoid triggering the new check.
	(0001-rs6000-Support-doubleword, pr-wrong-comp.patch,
	copyright-years.patch): New.

diff --git a/contrib/gcc-changelog/git_commit.py b/contrib/gcc-changelog/git_commit.py
index bd8c1ff7af2..6752ca8 100755
--- a/contrib/gcc-changelog/git_commit.py
+++ b/contrib/gcc-changelog/git_commit.py
@@ -156,7 +156,11 @@ author_line_regex = \
 re.compile(r'^(?P\d{4}-\d{2}-\d{2})\ {2}(?P.*  <.*>)')
 additional_author_regex = re.compile(r'^\t(?P\ *)?(?P.*  <.*>)')
 changelog_regex = re.compile(r'^(?:[fF]or +)?([a-z0-9+-/]*)ChangeLog:?')
-pr_regex = re.compile(r'\tPR (?P[a-z+-]+\/)?([0-9]+)$')
+subject_pr_skip_regex = re.compile(r'[Rr]evert')
+subject_pr_regex = \
+re.compile(r'(^|\W)PR\s+(?P[a-zA-Z+-]+)/(?P\d{4,7})')
+subject_pr2_regex = re.compile(r'[(\[]PR\s*(?P\d{4,7})[)\]]')
+pr_regex = re.compile(r'\tPR (?P[a-z+-]+\/)?(?P[0-9]+)$')
 dr_regex = re.compile(r'\tDR ([0-9]+)$')
 star_prefix_regex = re.compile(r'\t\*(?P\ *)(?P.*)')
 end_of_location_regex = re.compile(r'[\[<(:]')
@@ -298,6 +302,7 @@ class GitCommit:
 self.top_level_authors = []
 self.co_authors = []
 self.top_level_prs = []
+self.subject_prs = set()
 self.cherry_pick_commit = None
 self.revert_commit = None
 self.commit_to_info_hook = commit_to_info_hook
@@ -307,6 +312,22 @@ class GitCommit:
 if self.info.lines and self.info.lines[0] == 'Update 

Re: GCC documentation: porting to Sphinx

2021-06-10 Thread Martin Liška

On 6/2/21 7:27 PM, Joseph Myers wrote:

On Mon, 31 May 2021, Martin Liška wrote:


https://splichal.eu/scripts/sphinx/


Looking at some examples there:

https://splichal.eu/scripts/sphinx/gcc/_build/html/c-implementation-defined-behavior/preprocessing-directives.html
has some conversion problems:

* "See Implementation-defined behavior, for details of these aspects of
implementation-defined behavior." is missing the link to the relevant
section of the cpp manual that's present in the Texinfo source.


Yes, I'm aware of various cross-manual links that are currently not working.
It will likely require an extension called Intersphinx:
https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html



* "` character before the :samp:`" is a misconversion (whether from
Texinfo to RST or from RST to HTML) of the Texinfo source

   @samp{\} character before the @samp{\}

which will need to be fixed.


Yes, I fixed various :samp:, :option: leftovers all over the documentation.



* The corresponding PDF has the same issues as above (so probably they are
issues with the conversion to RST, not with Sphinx itself).  In addition,
the PDF manual ought to be using fixed-width fonts for literal code,
command-line options, etc., just like the HTML manual, and the
Texinfo-generated PDF manual, are.


Hm, I think the generated PDF properly uses a fixed-width font for option names,
commands and so one. Moreover, option directives are bold, while links to them
use normal font. I see the default font selection made by Sphinx readable.



https://splichal.eu/scripts/sphinx/gcc/_build/html/gcc-command-options/passing-options-to-the-assembler.html
shows headings such as "-Wa,option, -Wa".  The ", -Wa" doesn't make sense,
this option is just "-Wa,option".


I fixed various these issues.



https://splichal.eu/scripts/sphinx/gcc/_build/html/gcov-a-test-coverage-program.html
has a hyphen between "gcov" and "a Test Coverage Program" in the heading.
It should be an em dash, as in Texinfo.


Oh yeah. Apparently, we can use "smart quotes" (-- and ---) for dashes:
https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-smartquotes

Fixed that in the current version.



https://splichal.eu/scripts/sphinx/gcc/_build/html/language-standards-supported-by-gcc/c%2B%2B-language.html
has doubled slashes in various URLs where the Texinfo source has /@/
(Texinfo @/ means "allow line break", it should not be translated to /).


Good point, also fixed.



https://splichal.eu/scripts/sphinx/gcc/_build/html/gcc-command-options/machine-dependent-options/aarch64-options.html
shows different formatting for the headings for "-mlow-precision-div,
-mno-low-precision-div" and "-mtrack-speculation -mno-track-speculation".
The formatting should be identical.  The only difference in the Texinfo
source seems to be that the latter is missing @opindex directives.  And
while it's a bug in the Texinfo source that those directives are missing,
the presence or absence of index entries should not affect the formatting
of the documentation for those options.


As discussed with Martin Sebor, I emitted non-default option directive.



On that same page, the output for -march=name is broken, containing a
literal :samp:{feature} (in general, checking for any places where RST
directives such as :samp: appear in the HTML output might be a good idea
to look for broken conversions).  The Texinfo source here has

@option{-march=@var{arch}@r{@{}+@r{[}no@r{]}@var{feature}@r{@}*}}

(where the use of @r{...} is to put the {}[]* characters in a
variable-width font, since they are not literally part of the option,
while the other characters that are literally part of the option should be
in a variable-width font).


Also fixed.



https://splichal.eu/scripts/sphinx/gcc/_build/html/language-standards-supported-by-gcc/references-for-other-languages.html
has literal unconverted "@c man" and "@include" and other Texinfo
directives.  Searching for such things in the HTML output (or the RST
sources) is a good idea, just like searching for literal RST directives in
the HTML output, to find other such conversion bugs.


Clean up these.



https://splichal.eu/scripts/sphinx/gcc/_build/html/gcc-command-options.html
says "See option-index", another case with a link that didn't get
converted properly.  It also has raw :samp: uses indicating a
misconversion.

I'm not sure how you're determining languages for code-block, but
https://splichal.eu/scripts/sphinx/gcc/_build/html/gcc-command-options/options-to-control-diagnostic-messages-formatting.html
certainly shows some cases where they have been misidentified (e.g. random
C++ keywords highlighted in the default GCC_COLORS, some JSON being
highlighted as such but other JSON not).


I fixed all code-block warnings. Some of JSON syntax highlighting was not 
working because
the JSON syntax was invalid. Should be fine:

[committed] Use memory loads and extensions for cmp/test elimination on H8

2021-06-10 Thread Jeff Law via Gcc-patches
In today's episode of optimizing a dead architecture we're using memory 
loads and extensions to eliminate redundant test/compare instructions.  
Memory loads are very straightforward, they set ZN in the expected way, 
but weren't recognized by h8300_select_cc_mode and were thus not used. 
Trivially fixed.


Extensions are simple as well.  Sign extension works exactly how you 
would expect, setting ZN.  Zero extension sets Z and clears N, which if 
you think about it makes perfect sense too and matches GCC's semantics, 
so we can pretend zero extensions set ZN.


I'm seeing a little bouncing on the H8 testsuite, but it's a case where 
the stack and the code segments clash.  When this happens its not 
unusual for a test's state to bounce around when the code changes.


Note that we can do better still for testing if a memory object is >= 0 
or < 0.  We have the ability to copy the sign bit from a memory location 
into C without loading the memory into a register.  We're not supporting 
this *yet*, but I do expect to start exposing the C bit at some point 
and handling that case should naturally fall out.


Committed to the trunk,
Jeff

commit 6fcba9ef23e4261a6279a76890b2c1488cc14d12
Author: Jeff Law 
Date:   Thu Jun 10 09:57:51 2021 -0400

Use memory loads and extensions to eliminate redundant test/compare insns

gcc/

* config/h8300/h8300.c (select_cc_mode): Handle MEM.  Use
REG_P.
* config/h8300/extensions.md: Replace _clobber_flags patterns
with .

diff --git a/gcc/config/h8300/extensions.md b/gcc/config/h8300/extensions.md
index bc10179dac5..74647c79cd8 100644
--- a/gcc/config/h8300/extensions.md
+++ b/gcc/config/h8300/extensions.md
@@ -20,7 +20,7 @@
   [(parallel [(set (match_dup 0) (zero_extend:HI (match_dup 1)))
  (clobber (reg:CC CC_REG))])])
 
-(define_insn "*zero_extendqihi2_clobber_flags"
+(define_insn "*zero_extendqihi2"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))
(clobber (reg:CC CC_REG))]
@@ -95,7 +95,7 @@
   [(parallel [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
  (clobber (reg:CC CC_REG))])])
 
-(define_insn "*zero_extendqisi2_h8sx_clobber_flags"
+(define_insn "*zero_extendqisi2_h8sx"
   [(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:QI 1 "register_operand" "0")))
(clobber (reg:CC CC_REG))]
@@ -118,7 +118,7 @@
   [(parallel [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
  (clobber (reg:CC CC_REG))])])
 
-(define_insn "*zero_extendhisi2_clobber_flags"
+(define_insn "*zero_extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
(clobber (reg:CC CC_REG))]
@@ -141,7 +141,7 @@
   [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1)))
  (clobber (reg:CC CC_REG))])])
 
-(define_insn "*extendqihi2_clobber_flags"
+(define_insn "*extendqihi2"
   [(set (match_operand:HI 0 "register_operand" "=r")
(sign_extend:HI (match_operand:QI 1 "register_operand" "0")))
(clobber (reg:CC CC_REG))]
@@ -176,7 +176,7 @@
   [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
  (clobber (reg:CC CC_REG))])])
 
-(define_insn "*extendqisi2_h8sx_clobber_flags"
+(define_insn "*extendqisi2_h8sx"
   [(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))
(clobber (reg:CC CC_REG))]
@@ -199,7 +199,7 @@
   [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
  (clobber (reg:CC CC_REG))])])
 
-(define_insn "*extendhisi2_clobber_flags"
+(define_insn "*extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:HI 1 "register_operand" "0")))
(clobber (reg:CC CC_REG))]
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index ef947aa468a..1077a2b6ae0 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -1950,7 +1950,9 @@ h8300_select_cc_mode (enum rtx_code cond, rtx op0, rtx 
op1)
   || GET_CODE (op0) == NEG || GET_CODE (op0) == AND
   || GET_CODE (op0) == IOR || GET_CODE (op0) == XOR
   || GET_CODE (op0) == NOT || GET_CODE (op0) == ASHIFT
- || GET_CODE (op0) == REG || GET_CODE (op0) == MULT))
+ || GET_CODE (op0) == MULT
+ || GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND
+ || REG_P (op0) || MEM_P (op0)))
 return CCZNmode;
 
   return CCmode;


Re: [PATCH 2/2] arm: Auto-vectorization for MVE: add pack/unpack patterns

2021-06-10 Thread Christophe Lyon via Gcc-patches
On Thu, 10 Jun 2021 at 11:50, Christophe Lyon
 wrote:
>
> On Tue, 8 Jun 2021 at 14:10, Richard Sandiford
>  wrote:
> >
> > Christophe Lyon  writes:
> > > This patch adds vec_unpack_hi_, vec_unpack_lo_,
> > > vec_pack_trunc_ patterns for MVE.
> > >
> > > It does so by moving the unpack patterns from neon.md to
> > > vec-common.md, while adding them support for MVE. The pack expander is
> > > derived from the Neon one (which in turn is renamed into
> > > neon_quad_vec_pack_trunc_).
> > >
> > > The patch introduces mve_vec_pack_trunc_ to avoid the need for a
> > > zero-initialized temporary, which is needed if the
> > > vec_pack_trunc_ expander calls @mve_vmovn[bt]q_
> > > instead.
> > >
> > > With this patch, we can now vectorize the 16 and 8-bit versions of
> > > vclz and vshl, although the generated code could still be improved.
> > > For test_clz_s16, we now generate
> > > vldrh.16q3, [r1]
> > > vmovlb.s16   q2, q3
> > > vmovlt.s16   q3, q3
> > > vclz.i32  q2, q2
> > > vclz.i32  q3, q3
> > > vmovnb.i32  q1, q2
> > > vmovnt.i32  q1, q3
> > > vstrh.16q1, [r0]
> > > which could be improved to
> > > vldrh.16q3, [r1]
> > >   vclz.i16q1, q3
> > > vstrh.16q1, [r0]
> > > if we could avoid the need for unpack/pack steps.
> >
> > Yeah, there was a PR about fixing this for popcount.  I guess the same
> > approach would apply here too.
> >
> > > For reference, clang-12 generates:
> > >   vldrh.s32   q0, [r1]
> > >   vldrh.s32   q1, [r1, #8]
> > >   vclz.i32q0, q0
> > >   vstrh.32q0, [r0]
> > >   vclz.i32q0, q1
> > >   vstrh.32q0, [r0, #8]
> > >
> > > 2021-06-03  Christophe Lyon  
> > >
> > >   gcc/
> > >   * config/arm/mve.md (mve_vmovltq_): Prefix with '@'.
> > >   (mve_vmovlbq_): Likewise.
> > >   (mve_vmovnbq_): Likewise.
> > >   (mve_vmovntq_): Likewise.
> > >   (@mve_vec_pack_trunc_): New pattern.
> > >   * config/arm/neon.md (vec_unpack_hi_): Move to
> > >   vec-common.md.
> > >   (vec_unpack_lo_): Likewise.
> > >   (vec_pack_trunc_): Rename to
> > >   neon_quad_vec_pack_trunc_.
> > >   * config/arm/vec-common.md (vec_unpack_hi_): New
> > >   pattern.
> > >   (vec_unpack_lo_): New.
> > >   (vec_pack_trunc_): New.
> > >
> > >   gcc/testsuite/
> > >   * gcc.target/arm/simd/mve-vclz.c: Update expected results.
> > >   * gcc.target/arm/simd/mve-vshl.c: Likewise.
> > > ---
> > >  gcc/config/arm/mve.md| 20 -
> > >  gcc/config/arm/neon.md   | 39 +
> > >  gcc/config/arm/vec-common.md | 89 
> > >  gcc/testsuite/gcc.target/arm/simd/mve-vclz.c |  7 +-
> > >  gcc/testsuite/gcc.target/arm/simd/mve-vshl.c |  5 +-
> > >  5 files changed, 114 insertions(+), 46 deletions(-)
> > >
> > > diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
> > > index 99e46d0bc69..b18292c07d3 100644
> > > --- a/gcc/config/arm/mve.md
> > > +++ b/gcc/config/arm/mve.md
> > > @@ -510,7 +510,7 @@ (define_insn "mve_vrev32q_"
> > >  ;;
> > >  ;; [vmovltq_u, vmovltq_s])
> > >  ;;
> > > -(define_insn "mve_vmovltq_"
> > > +(define_insn "@mve_vmovltq_"
> > >[
> > > (set (match_operand: 0 "s_register_operand" "=w")
> > >   (unspec: [(match_operand:MVE_3 1 
> > > "s_register_operand" "w")]
> > > @@ -524,7 +524,7 @@ (define_insn "mve_vmovltq_"
> > >  ;;
> > >  ;; [vmovlbq_s, vmovlbq_u])
> > >  ;;
> > > -(define_insn "mve_vmovlbq_"
> > > +(define_insn "@mve_vmovlbq_"
> > >[
> > > (set (match_operand: 0 "s_register_operand" "=w")
> > >   (unspec: [(match_operand:MVE_3 1 
> > > "s_register_operand" "w")]
> > > @@ -2187,7 +2187,7 @@ (define_insn "mve_vmlsldavxq_s"
> > >  ;;
> > >  ;; [vmovnbq_u, vmovnbq_s])
> > >  ;;
> > > -(define_insn "mve_vmovnbq_"
> > > +(define_insn "@mve_vmovnbq_"
> > >[
> > > (set (match_operand: 0 "s_register_operand" "=w")
> > >   (unspec: [(match_operand: 1 
> > > "s_register_operand" "0")
> > > @@ -2202,7 +2202,7 @@ (define_insn "mve_vmovnbq_"
> > >  ;;
> > >  ;; [vmovntq_s, vmovntq_u])
> > >  ;;
> > > -(define_insn "mve_vmovntq_"
> > > +(define_insn "@mve_vmovntq_"
> > >[
> > > (set (match_operand: 0 "s_register_operand" "=w")
> > >   (unspec: [(match_operand: 1 
> > > "s_register_operand" "0")
> > > @@ -2214,6 +2214,18 @@ (define_insn "mve_vmovntq_"
> > >[(set_attr "type" "mve_move")
> > >  ])
> > >
> > > +(define_insn "@mve_vec_pack_trunc_"
> > > + [(set (match_operand: 0 "register_operand" "=")
> > > +   (vec_concat:
> > > + (truncate:
> > > + (match_operand:MVE_5 1 "register_operand" "w"))
> > > + (truncate:
> > > + (match_operand:MVE_5 2 "register_operand" "w"]
> > > + "TARGET_HAVE_MVE"
> > > + "vmovnb.i%q0, %q1\;vmovnt.i   %q0, %q2"
> > > + 

Re: GCC documentation: porting to Sphinx

2021-06-10 Thread Martin Liška

On 6/10/21 11:07 AM, Martin Liška wrote:

Doing that, one has 2 unique links, that would be needed for get_option_url 
function.
Plus, both :option:`-Wfoo` and :option:`-Wno-foo` references are going to work.


And I've actually did the transformation and one can see it e.g. here:
https://splichal.eu/scripts/sphinx/gcc/_build/html/gcc-command-options/options-to-request-or-suppress-warnings.html#cmdoption-Wprio-ctor-dtor

Martin


Re: [PATCH, v3, OpenMP 5.0, libgomp] Structure element mapping for OpenMP 5.0

2021-06-10 Thread Jakub Jelinek via Gcc-patches
On Mon, May 31, 2021 at 09:36:41PM +0800, Chung-Lin Tang wrote:
> this is a v3 version of my OpenMP 5.0 structure element mapping patch,
> v2 was here: 
> https://gcc.gnu.org/pipermail/gcc-patches/2020-December/561139.html
> 
> This v3 adds a small bug fix, where the initialization of the refcount didn't
> handle all cases, fixed by using gomp_refcount_increment here (more 
> consistent).

Sorry for the delay.

Ok for trunk, but see some nits in the testsuite.

> I know you had performance concerns in the last round, compared with your 
> sorting
> approach. I'll try to research on that later. Getting the v3 patch posted 
> before
> backporting to devel/omp/gcc-11.

But please have a look at this incrementally.
I think the common case is just a couple of mappings (say < 10 or < 20 in
90%+ of cases) and a htab might be too expensive for that.

> 
>   libgomp/
>   * hashtab.h (htab_clear): New function with initialization code
>   factored out from...
>   (htab_create): ...here, adjust to use htab_clear function.
> 
>   * libgomp.h (REFCOUNT_SPECIAL): New symbol to denote range of
>   special refcount values, add comments.
>   (REFCOUNT_INFINITY): Adjust definition to use REFCOUNT_SPECIAL.
>   (REFCOUNT_LINK): Likewise.
>   (REFCOUNT_STRUCTELEM): New special refcount range for structure
>   element siblings.
>   (REFCOUNT_STRUCTELEM_P): Macro for testing for structure element
>   sibling maps.
>   (REFCOUNT_STRUCTELEM_FLAG_FIRST): Flag to indicate first sibling.
>   (REFCOUNT_STRUCTELEM_FLAG_LAST):  Flag to indicate last sibling.
>   (REFCOUNT_STRUCTELEM_FIRST_P): Macro to test _FIRST flag.
>   (REFCOUNT_STRUCTELEM_LAST_P): Macro to test _LAST flag.
>   (struct splay_tree_key_s): Add structelem_refcount and
>   structelem_refcount_ptr fields into a union with dynamic_refcount.
>   Add comments.
>   (gomp_map_vars): Delete declaration.
>   (gomp_map_vars_async): Likewise.
>   (gomp_unmap_vars): Likewise.
>   (gomp_unmap_vars_async): Likewise.
>   (goacc_map_vars): New declaration.
>   (goacc_unmap_vars): Likewise.
> 
>   * oacc-mem.c (acc_map_data): Adjust to use goacc_map_vars.
>   (goacc_enter_datum): Likewise.
>   (goacc_enter_data_internal): Likewise.
>   * oacc-parallel.c (GOACC_parallel_keyed): Adjust to use goacc_map_vars
>   and goacc_unmap_vars.
>   (GOACC_data_start): Adjust to use goacc_map_vars.
>   (GOACC_data_end): Adjust to use goacc_unmap_vars.
> 
>   * target.c (hash_entry_type): New typedef.
>   (htab_alloc): New function hook for hashtab.h.
>   (htab_free): Likewise.
>   (htab_hash): Likewise.
>   (htab_eq): Likewise.
>   (hashtab.h): Add file include.
>   (gomp_increment_refcount): New function.
>   (gomp_decrement_refcount): Likewise.
>   (gomp_map_vars_existing): Add refcount_set parameter, adjust to use
>   gomp_increment_refcount.
>   (gomp_map_fields_existing): Add refcount_set parameter, adjust calls
>   to gomp_map_vars_existing.
> 
>   (gomp_map_vars_internal): Add refcount_set parameter, add local openmp_p
>   variable to guard OpenMP specific paths, adjust calls to
>   gomp_map_vars_existing, add structure element sibling splay_tree_key
>   sequence creation code, adjust Fortran map case to avoid increment
>   under OpenMP.
>   (gomp_map_vars): Adjust to static, add refcount_set parameter, manage
>   local refcount_set if caller passed in NULL, adjust call to
>   gomp_map_vars_internal.
>   (gomp_map_vars_async): Adjust and rename into...
>   (goacc_map_vars): ...this new function, adjust call to
>   gomp_map_vars_internal.
> 
>   (gomp_remove_splay_tree_key): New function with code factored out from
>   gomp_remove_var_internal.
>   (gomp_remove_var_internal): Add code to handle removing multiple
>   splay_tree_key sequence for structure elements, adjust code to use
>   gomp_remove_splay_tree_key for splay-tree key removal.
>   (gomp_unmap_vars_internal): Add refcount_set parameter, adjust to use
>   gomp_decrement_refcount.
>   (gomp_unmap_vars): Adjust to static, add refcount_set parameter, manage
>   local refcount_set if caller passed in NULL, adjust call to
>   gomp_unmap_vars_internal.
>   (gomp_unmap_vars_async): Adjust and rename into...
>   (goacc_unmap_vars): ...this new function, adjust call to
>   gomp_unmap_vars_internal.
>   (GOMP_target): Manage refcount_set and adjust calls to gomp_map_vars and
>   gomp_unmap_vars.
>   (GOMP_target_ext): Likewise.
>   (gomp_target_data_fallback): Adjust call to gomp_map_vars.
>   (GOMP_target_data): Likewise.
>   (GOMP_target_data_ext): Likewise.
>   (GOMP_target_end_data): Adjust call to gomp_unmap_vars.
>   (gomp_exit_data): Add refcount_set parameter, adjust to use
>   gomp_decrement_refcount, adjust to queue splay-tree 

Re: [PATCH] PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514

2021-06-10 Thread Bernhard Reutner-Fischer via Gcc-patches
On Thu, 10 Jun 2021 12:24:35 +0200
Bernhard Reutner-Fischer  wrote:

> On Wed, 9 Jun 2021 23:39:45 +0200
> Harald Anlauf via Gcc-patches  wrote:

> > +/* Check for constant length of a substring.  */
> > +
> > +static bool
> > +substring_has_constant_len (gfc_expr *e)
> > +{
> > +  ptrdiff_t istart, iend;
> > +  size_t length;
> > +  bool equal_length = false;
> > +
> > +  if (e->ts.type != BT_CHARACTER
> > +  || !(e->ref && e->ref->type == REF_SUBSTRING)  
> 
> iff we ever can get here with e->ref == NULL then the below will not
> work too well. If so then maybe
>   if (e->ts.type != BT_CHARACTER
>   || ! e->ref
>   || e->ref->type != REF_SUBSTRING
> 
> ?

Not sure what i was reading, maybe i read || instead of && in the
braced condition. Your initial version works equally well of course
although it's obviously harder to parse for at least some :)
thanks,


Re: [PATCH] OpenACC: Separate enter/exit data APIs

2021-06-10 Thread Thomas Schwinge
Hi!

On 2020-09-25T16:22:47+0100, Andrew Stubbs  wrote:
> On 30/07/2020 12:10, Andrew Stubbs wrote:
>> On 29/07/2020 15:05, Andrew Stubbs wrote:
>>> This patch does not implement anything new, but simply separates
>>> OpenACC 'enter data' and 'exit data' into two libgomp API functions.
>>> The original API name is kept for backward compatibility, but no
>>> longer referenced by the compiler.

(ABI, not API.)

>>> The previous implementation assumed that it would always be possible
>>> to infer which kind of pragma it was dealing with from the context,
>>> but there are a few exceptions, and I want to add one more:
>>> zero-length arrays.
>>>
>>> By cleaning this up I will be free to add the new feature without the
>>> reference counting getting broken.

ACK, that's a good cleanup already for its own sake.


> This update [...] updates the patterns in a number of
> testcases that were affected.

... just that you missed all the Fortran testcases, had me do the "dirty
Fortran work", tsk...  ;-P


A few comments, hope that's useful:


> --- a/gcc/gimple.h
> +++ b/gcc/gimple.h
> @@ -171,9 +171,10 @@ enum gf_mask {
>  GF_OMP_TARGET_KIND_OACC_SERIAL = 7,
>  GF_OMP_TARGET_KIND_OACC_DATA = 8,
>  GF_OMP_TARGET_KIND_OACC_UPDATE = 9,
> -GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA = 10,
> +GF_OMP_TARGET_KIND_OACC_ENTER_DATA = 10,
>  GF_OMP_TARGET_KIND_OACC_DECLARE = 11,
>  GF_OMP_TARGET_KIND_OACC_HOST_DATA = 12,
> +GF_OMP_TARGET_KIND_OACC_EXIT_DATA = 13,
>  GF_OMP_TEAMS_HOST= 1 << 0,

We shall re-number, so that 'GF_OMP_TARGET_KIND_OACC_ENTER_DATA' and
'GF_OMP_TARGET_KIND_OACC_EXIT_DATA' stay in proximity.


> --- a/libgomp/libgomp.map
> +++ b/libgomp/libgomp.map
> @@ -517,6 +517,8 @@ GOACC_2.0 {
>global:
>   GOACC_data_end;
>   GOACC_data_start;
> + GOACC_enter_data;
> + GOACC_exit_data;
>   GOACC_enter_exit_data;
>   GOACC_parallel;
>   GOACC_update;

As we've been told, new symbols need a new symbol version if 'GOACC_2.0'
(here) has already been part of a GCC release.


> --- a/libgomp/libgomp_g.h
> +++ b/libgomp/libgomp_g.h
> @@ -363,8 +363,10 @@ extern void GOACC_wait (int, int, ...);
>
>  /* oacc-mem.c */
>
> -extern void GOACC_enter_exit_data (int, size_t, void **, size_t *,
> -unsigned short *, int, int, ...);

Don't remove: "This file contains prototypes of functions in the external
ABI" -- and 'GOACC_enter_exit_data' remains part of that.

> +extern void GOACC_enter_data (int, size_t, void **, size_t *,
> +   unsigned short *, int, int, ...);
> +extern void GOACC_exit_data (int, size_t, void **, size_t *,
> +  unsigned short *, int, int, ...);


> --- a/libgomp/oacc-mem.c
> +++ b/libgomp/oacc-mem.c

> +static void
> +GOACC_enter_exit_data_internal (int flags_m, size_t mapnum, void **hostaddrs,
> + size_t *sizes, unsigned short *kinds,
> + int async, bool data_enter, int num_waits,
> + va_list *ap)

The order 'async', 'data_enter', 'num_waits' seemed a bit awkward to me,
so I changed that to 'data_enter', 'async', 'num_waits'.


> --- a/libgomp/oacc-parallel.c
> +++ b/libgomp/oacc-parallel.c
> @@ -745,12 +745,15 @@ GOACC_declare (int flags_m, size_t mapnum,
>switch (kind)
>   {
> case GOMP_MAP_FORCE_ALLOC:
> -   case GOMP_MAP_FORCE_FROM:
> case GOMP_MAP_FORCE_TO:
> -   case GOMP_MAP_POINTER:

I've separately pushed "Clean up 'GOMP_MAP_POINTER' handling in
'libgomp/oacc-parallel.c:GOACC_declare'".


> + GOACC_enter_data (flags_m, 1, [i], [i],
> +[i], GOMP_ASYNC_SYNC, 0);
> + break;
> +
> +   case GOMP_MAP_FORCE_FROM:
> case GOMP_MAP_RELEASE:
> case GOMP_MAP_DELETE:
> - GOACC_enter_exit_data (flags_m, 1, [i], [i],
> + GOACC_exit_data (flags_m, 1, [i], [i],
>  [i], GOMP_ASYNC_SYNC, 0);
>   break;
> [...]

And, after separately pushed "Move
'libgomp/oacc-parallel.c:GOACC_declare' into 'libgomp/oacc-mem.c'", we
can then directly call the internal 'goacc_enter_exit_data_internal'
here, instead of the external 'GOACC_enter_data'/'GOACC_exit_data', which
is benefitial for certain reasons.


> --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-26.c
> +++ /dev/null

> --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-36.c
> +++ /dev/null

> --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-40.c
> +++ /dev/null

No reason to remove these as part of this patch.


Fixed these items, plus some minor additional clean-up.


I've then first pushed "Extract 'goacc_enter_exit_data_internal' from
'libgomp/oacc-mem.c:GOACC_enter_exit_data'" to master branch in
commit 7999363961dc6feeb0976cc6d85ea91a120d0e1d, see attached.  Doing
that as a separate step makes sure that we don't break anything for
'GOACC_enter_exit_data'.



[RFC][ivopts] Generate better code for IVs with uses outside the loop

2021-06-10 Thread Andre Vieira (lists) via Gcc-patches



On 08/06/2021 16:00, Andre Simoes Dias Vieira via Gcc-patches wrote:

Hi Bin,

Thank you for the reply, I have some questions, see below.

On 07/06/2021 12:28, Bin.Cheng wrote:

On Fri, Jun 4, 2021 at 12:35 AM Andre Vieira (lists) via Gcc-patches
 wrote:

Hi Andre,
I didn't look into the details of the IV sharing RFC.  It seems to me
costing outside uses is trying to generate better code for later code
(epilogue loop here).  The only problem is IVOPTs doesn't know that
the outside use is not in the final form - which will be transformed
by IVOPTs again.

I think this example is not good at describing your problem because it
shows exactly that considering outside use results in better code,
compared to the other two approaches.
I don't quite understand what you are saying here :( What do you mean 
by final form? It seems to me that costing uses inside and outside 
loop the same way is wrong because calculating the IV inside the loop 
has to be done every iteration, whereas if you can resolve it to a 
single update (without an IV) then you can sink it outside the loop. 
This is why I think this example shows why we need to cost these uses 
differently.

2) Is there a cleaner way to generate the optimal 'post-increment' use
for the outside-use variable? I first thought the position in the
candidate might be something I could use or even the var_at_stmt
functionality, but the outside IV has the actual increment of the
variable as it's use, rather than the outside uses. This is this RFC's
main weakness I find.

To answer why IVOPTs behaves like this w/o your two patches. The main
problem is the point IVOPTs rewrites outside use IV - I don't remember
the exact point - but looks like at the end of loop while before
incrementing instruction of main IV.  It's a known issue that outside
use should be costed/re-written on the exit edge along which its value
flows out of loop.  I had a patch a long time ago but discarded it,
because it didn't bring obvious improvement and is complicated in case
of multi-exit edges.
Yeah I haven't looked at multi-exit edges and I understand that 
complicates things. But for now we could disable the special casing of 
outside uses when dealing with multi-exit loops and keep the current 
behavior.


But in general, I am less convinced that any of the two patches is the
right direction solving IV sharing issue between vectorized loop and
epilogue loop.  I would need to read the previous RFC before giving
further comments though.


The previous RFC still has a lot of unanswered questions too, but 
regardless of that, take the following (non-vectorizer) example:


#include 
#include 

void bar (char  * __restrict__ a, char * __restrict__ b, char * 
__restrict__ c, unsigned long long n)

{
    svbool_t all_true = svptrue_b8 ();
  unsigned long long i = 0;
    for (; i < (n & ~(svcntb() - 1)); i += svcntb()) {
  svuint8_t va = svld1 (all_true, (uint8_t*)a);
  svuint8_t vb = svld1 (all_true, (uint8_t*)b);
  svst1 (all_true, (uint8_t *)c, svadd_z (all_true, va,vb));
  a += svcntb();
  b += svcntb();
  c += svcntb();
  }
  svbool_t pred;
  for (; i < (n); i += svcntb()) {
  pred = svwhilelt_b8 (i, n);
  svuint8_t va = svld1 (pred, (uint8_t*)a);
  svuint8_t vb = svld1 (pred, (uint8_t*)b);
  svst1 (pred, (uint8_t *)c, svadd_z (pred, va,vb));
  a += svcntb();
  b += svcntb();
  c += svcntb();
  }


Current IVOPTs will use 4 iterators for the first loop, when it could 
do with just 1. In fact, if you use my patches it will create just a 
single IV and sink the uses and it is then able to merge them with 
loads & stores of the next loop.
I mixed things up here, I think an earlier version of my patch (with 
even more hacks) managed to rewrite these properly, but it looks like 
the current ones are messing things up.
I'll continue to try to understand how this works as I do still think 
IVOPTs should be able to do better.


You mentioned you had a patch you thought might help earlier, but you 
dropped it. Do you still have it lying around anywhere?


I am not saying setting outside costs to 0 is the right thing to do by 
the way. It is absolutely not! It will break cost considerations for 
other cases. Like I said above I've been playing around with using 
'!use->outside' as a multiplier for the cost. Unfortunately it won't 
help with the case above, because this seems to choose 'infinite_cost' 
because the candidate IV has a lower precision than the use IV. I 
don't quite understand yet how candidates are created, but something 
I'm going to try to look at. Just wanted to show this as an example of 
how IVOPTs would not improve code with multiple loops that don't 
involve the vectorizer.


BR,
Andre




Thanks,
bin


Re: [OpenACC] declare directive

2021-06-10 Thread Thomas Schwinge
Hi!

While working on something else...  ;-)

On 2015-10-27T15:18:00-0500, James Norris  wrote:
> --- a/libgomp/oacc-parallel.c
> +++ b/libgomp/oacc-parallel.c

> +GOACC_declare (int device, size_t mapnum,
> +void **hostaddrs, size_t *sizes, unsigned short *kinds)
> +{
> +  int i;
> +
> +  for (i = 0; i < mapnum; i++)
> +{
> +  unsigned char kind = kinds[i] & 0xff;
> +
> +  if (kind == GOMP_MAP_POINTER || kind == GOMP_MAP_TO_PSET)
> + continue;
> +
> +  switch (kind)
> + {
> +   case GOMP_MAP_FORCE_ALLOC:
> +   case GOMP_MAP_FORCE_DEALLOC:
> +   case GOMP_MAP_FORCE_FROM:
> +   case GOMP_MAP_FORCE_TO:
> +   case GOMP_MAP_POINTER:
> +[...]

... Andrew had noticed that given that we 'continue' for
'GOMP_MAP_POINTER', we cannot possibly encounter it afterwards.

I've pushed "Clean up 'GOMP_MAP_POINTER' handling in
'libgomp/oacc-parallel.c:GOACC_declare'" to master branch in
commit ae33c6deb158911548a5f1d383b683abb799be4a, see attached.


Also, to facilitate later changes I've pushed "Move
'libgomp/oacc-parallel.c:GOACC_declare' into 'libgomp/oacc-mem.c'" to
master branch in commit 0a77c7033ae4ed05a2f7e78600522610a8d82225, see
attached.


Grüße
 Thomas


-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
>From ae33c6deb158911548a5f1d383b683abb799be4a Mon Sep 17 00:00:00 2001
From: Andrew Stubbs 
Date: Wed, 29 Jul 2020 15:05:45 +0100
Subject: [PATCH 1/2] Clean up 'GOMP_MAP_POINTER' handling in
 'libgomp/oacc-parallel.c:GOACC_declare'

Given that we 'continue' for 'GOMP_MAP_POINTER', we cannot possibly encounter
it afterwards.

Small fix-up for r230275 (commit 6e232ba4246ca324a663ec5ddf0ba4db5cf3fbad)
"[OpenACC] declare directive".

	libgomp/
	* oacc-parallel.c (GOACC_declare): Clean up 'GOMP_MAP_POINTER'
	handling.

Co-Authored-By: Thomas Schwinge 
---
 libgomp/oacc-parallel.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libgomp/oacc-parallel.c b/libgomp/oacc-parallel.c
index cf1baf6291d..d05b3d87097 100644
--- a/libgomp/oacc-parallel.c
+++ b/libgomp/oacc-parallel.c
@@ -747,7 +747,6 @@ GOACC_declare (int flags_m, size_t mapnum,
 	  case GOMP_MAP_FORCE_ALLOC:
 	  case GOMP_MAP_FORCE_FROM:
 	  case GOMP_MAP_FORCE_TO:
-	  case GOMP_MAP_POINTER:
 	  case GOMP_MAP_RELEASE:
 	  case GOMP_MAP_DELETE:
 	GOACC_enter_exit_data (flags_m, 1, [i], [i],
-- 
2.30.2

>From 0a77c7033ae4ed05a2f7e78600522610a8d82225 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge 
Date: Tue, 8 Jun 2021 17:15:19 +0200
Subject: [PATCH 2/2] Move 'libgomp/oacc-parallel.c:GOACC_declare' into
 'libgomp/oacc-mem.c'

This deals with data management, after all.

Small fix-up for r230275 (commit 6e232ba4246ca324a663ec5ddf0ba4db5cf3fbad)
"[OpenACC] declare directive".

	libgomp/
	* oacc-parallel.c (GOACC_declare): Move...
	* oacc-mem.c: ... here.
	* libgomp_g.h: Adjust.
---
 libgomp/libgomp_g.h |  2 +-
 libgomp/oacc-mem.c  | 54 ++
 libgomp/oacc-parallel.c | 57 -
 3 files changed, 55 insertions(+), 58 deletions(-)

diff --git a/libgomp/libgomp_g.h b/libgomp/libgomp_g.h
index 3cbe0a4ca89..b66b6978202 100644
--- a/libgomp/libgomp_g.h
+++ b/libgomp/libgomp_g.h
@@ -370,6 +370,7 @@ extern void GOACC_wait (int, int, ...);
 
 extern void GOACC_enter_exit_data (int, size_t, void **, size_t *,
    unsigned short *, int, int, ...);
+extern void GOACC_declare (int, size_t, void **, size_t *, unsigned short *);
 
 /* oacc-parallel.c */
 
@@ -384,6 +385,5 @@ extern void GOACC_update (int, size_t, void **, size_t *,
 			  unsigned short *, int, int, ...);
 extern int GOACC_get_num_threads (void);
 extern int GOACC_get_thread_num (void);
-extern void GOACC_declare (int, size_t, void **, size_t *, unsigned short *);
 
 #endif /* LIBGOMP_G_H */
diff --git a/libgomp/oacc-mem.c b/libgomp/oacc-mem.c
index 405574dfa2b..056600aca52 100644
--- a/libgomp/oacc-mem.c
+++ b/libgomp/oacc-mem.c
@@ -1461,3 +1461,57 @@ GOACC_enter_exit_data (int flags_m, size_t mapnum, void **hostaddrs,
   thr->api_info = NULL;
 }
 }
+
+void
+GOACC_declare (int flags_m, size_t mapnum,
+	   void **hostaddrs, size_t *sizes, unsigned short *kinds)
+{
+  for (size_t i = 0; i < mapnum; i++)
+{
+  unsigned char kind = kinds[i] & 0xff;
+
+  if (kind == GOMP_MAP_POINTER || kind == GOMP_MAP_TO_PSET)
+	continue;
+
+  switch (kind)
+	{
+	case GOMP_MAP_FORCE_ALLOC:
+	case GOMP_MAP_FORCE_FROM:
+	case GOMP_MAP_FORCE_TO:
+	case GOMP_MAP_RELEASE:
+	case GOMP_MAP_DELETE:
+	  GOACC_enter_exit_data (flags_m, 1, [i], [i],
+ [i], GOMP_ASYNC_SYNC, 0);
+	  break;
+
+	case GOMP_MAP_FORCE_DEVICEPTR:
+	  break;
+
+	case GOMP_MAP_ALLOC:
+	  if (!acc_is_present (hostaddrs[i], sizes[i]))
+	GOACC_enter_exit_data (flags_m, 1, [i], [i],
+   [i], GOMP_ASYNC_SYNC, 0);
+	  break;
+
+	case GOMP_MAP_TO:
+	  GOACC_enter_exit_data 

[PUSHED] Adjust variable names and comments in value-query.*

2021-06-10 Thread Aldy Hernandez via Gcc-patches
Now that range_of_expr can take arbitrary tree expressions, not just
SSA names or constants, the method names and comments are slightly out
of date.  This patch adjusts them to reflect reality.

Pushed.

gcc/ChangeLog:

* value-query.cc (value_query::value_on_edge): Rename name to
expr.
(range_query::range_on_edge): Same.
(range_query::value_of_expr): Same.
(range_query::value_on_edge): Same.
* value-query.h (class value_query): Same.
(class range_query): Same.
---
 gcc/value-query.cc | 24 
 gcc/value-query.h  | 18 +-
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 821f224d4ab..9047e271b5b 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -36,9 +36,9 @@ along with GCC; see the file COPYING3.  If not see
 // value_query default methods.
 
 tree
-value_query::value_on_edge (edge, tree name)
+value_query::value_on_edge (edge, tree expr)
 {
-  return value_of_expr (name);
+  return value_of_expr (expr);
 }
 
 tree
@@ -57,9 +57,9 @@ value_query::value_of_stmt (gimple *stmt, tree name)
 // range_query default methods.
 
 bool
-range_query::range_on_edge (irange , edge, tree name)
+range_query::range_on_edge (irange , edge, tree expr)
 {
-  return range_of_expr (r, name);
+  return range_of_expr (r, expr);
 }
 
 bool
@@ -76,20 +76,20 @@ range_query::range_of_stmt (irange , gimple *stmt, tree 
name)
 }
 
 tree
-range_query::value_of_expr (tree name, gimple *stmt)
+range_query::value_of_expr (tree expr, gimple *stmt)
 {
   tree t;
   int_range_max r;
 
-  if (!irange::supports_type_p (TREE_TYPE (name)))
+  if (!irange::supports_type_p (TREE_TYPE (expr)))
 return NULL_TREE;
 
-  if (range_of_expr (r, name, stmt))
+  if (range_of_expr (r, expr, stmt))
 {
   // A constant used in an unreachable block oftens returns as UNDEFINED.
   // If the result is undefined, check the global value for a constant.
   if (r.undefined_p ())
-   range_of_expr (r, name);
+   range_of_expr (r, expr);
   if (r.singleton_p ())
return t;
 }
@@ -97,19 +97,19 @@ range_query::value_of_expr (tree name, gimple *stmt)
 }
 
 tree
-range_query::value_on_edge (edge e, tree name)
+range_query::value_on_edge (edge e, tree expr)
 {
   tree t;
   int_range_max r;
 
-  if (!irange::supports_type_p (TREE_TYPE (name)))
+  if (!irange::supports_type_p (TREE_TYPE (expr)))
 return NULL_TREE;
-  if (range_on_edge (r, e, name))
+  if (range_on_edge (r, e, expr))
 {
   // A constant used in an unreachable block oftens returns as UNDEFINED.
   // If the result is undefined, check the global value for a constant.
   if (r.undefined_p ())
-   range_of_expr (r, name);
+   range_of_expr (r, expr);
   if (r.singleton_p ())
return t;
 }
diff --git a/gcc/value-query.h b/gcc/value-query.h
index 77e49e9a906..54af031ea42 100644
--- a/gcc/value-query.h
+++ b/gcc/value-query.h
@@ -39,12 +39,12 @@ class value_query
 {
 public:
   value_query () { }
-  // Return the singleton expression for NAME at a gimple statement,
+  // Return the singleton expression for EXPR at a gimple statement,
   // or NULL if none found.
-  virtual tree value_of_expr (tree name, gimple * = NULL) = 0;
-  // Return the singleton expression for NAME at an edge, or NULL if
+  virtual tree value_of_expr (tree expr, gimple * = NULL) = 0;
+  // Return the singleton expression for EXPR at an edge, or NULL if
   // none found.
-  virtual tree value_on_edge (edge, tree name);
+  virtual tree value_on_edge (edge, tree expr);
   // Return the singleton expression for the LHS of a gimple
   // statement, assuming an (optional) initial value of NAME.  Returns
   // NULL if none found.
@@ -77,8 +77,8 @@ public:
   range_query ();
   virtual ~range_query ();
 
-  virtual tree value_of_expr (tree name, gimple * = NULL) OVERRIDE;
-  virtual tree value_on_edge (edge, tree name) OVERRIDE;
+  virtual tree value_of_expr (tree expr, gimple * = NULL) OVERRIDE;
+  virtual tree value_on_edge (edge, tree expr) OVERRIDE;
   virtual tree value_of_stmt (gimple *, tree name = NULL) OVERRIDE;
 
   // These are the range equivalents of the value_* methods.  Instead
@@ -86,9 +86,9 @@ public:
   // R.  TRUE is returned on success or FALSE if no range was found.
   //
   // Note that range_of_expr must always return TRUE unless ranges are
-  // unsupported for NAME's type (supports_type_p is false).
-  virtual bool range_of_expr (irange , tree name, gimple * = NULL) = 0;
-  virtual bool range_on_edge (irange , edge, tree name);
+  // unsupported for EXPR's type (supports_type_p is false).
+  virtual bool range_of_expr (irange , tree expr, gimple * = NULL) = 0;
+  virtual bool range_on_edge (irange , edge, tree expr);
   virtual bool range_of_stmt (irange , gimple *, tree name = NULL);
 
   // DEPRECATED: This method is used from vr-values.  The plan is to
-- 
2.31.1



Re: [PATCH 09/13] OpenACC 2.6 deep copy: C and C++ front-end parts

2021-06-10 Thread Thomas Schwinge
Hi!

While working on something else...  ;-)

On 2019-12-17T22:03:49-0800, Julian Brown  wrote:
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/goacc/mdc-1.c
> @@ -0,0 +1,55 @@
> +[...]
> +#pragma acc acc enter data attach(s.e)
> +[...]

... I noticed 'acc acc'.

> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/goacc/mdc-2.c

Similar.

> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/goacc/mdc.C

Similar.

Pushed "Fix '#pragma acc acc [...]' typos" to master branch in
commit 05c4dabb71476ddea8d409fd41f1e97d62d0b5f4, see attached.


Grüße
 Thomas


-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
>From 05c4dabb71476ddea8d409fd41f1e97d62d0b5f4 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge 
Date: Wed, 9 Jun 2021 10:11:23 +0200
Subject: [PATCH] Fix '#pragma acc acc [...]' typos

Small fix-up for r279627 (commit 519d7496beac32c26448c1d0eea176c90f543702)
"OpenACC 2.6 deep copy: C and C++ front-end parts".

	gcc/testsuite/
	* c-c++-common/goacc/mdc-1.c: Fix '#pragma acc acc [...]' typo.
	* c-c++-common/goacc/mdc-2.c: Likewise.
	* g++.dg/goacc/mdc.C: Likewise.
---
 gcc/testsuite/c-c++-common/goacc/mdc-1.c | 3 ++-
 gcc/testsuite/c-c++-common/goacc/mdc-2.c | 2 +-
 gcc/testsuite/g++.dg/goacc/mdc.C | 2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/c-c++-common/goacc/mdc-1.c b/gcc/testsuite/c-c++-common/goacc/mdc-1.c
index 337c1f7cc77..c9ab7c24074 100644
--- a/gcc/testsuite/c-c++-common/goacc/mdc-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/mdc-1.c
@@ -30,7 +30,7 @@ t1 ()
 }
 
 #pragma acc enter data copyin(a)
-#pragma acc acc enter data attach(s.e)
+#pragma acc enter data attach(s.e)
 #pragma acc exit data detach(s.e)
 
 #pragma acc data attach(s.e)
@@ -49,6 +49,7 @@ t1 ()
 /* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.attach:a .bias: 0.." 1 "omplower" } } */
 /* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.detach:a .bias: 0.." 1 "omplower" } } */
 /* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.to:a .len: 8.." 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.attach:s.e .bias: 0.." 1 "omplower" } } */
 /* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.detach:s.e .bias: 0.." 1 "omplower" } } */
 /* { dg-final { scan-tree-dump-times "pragma omp target oacc_data map.attach:s.e .bias: 0.." 1 "omplower" } } */
 /* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.release:a .len: 8.." 1 "omplower" } } */
diff --git a/gcc/testsuite/c-c++-common/goacc/mdc-2.c b/gcc/testsuite/c-c++-common/goacc/mdc-2.c
index fae86671fc9..df3ce543d30 100644
--- a/gcc/testsuite/c-c++-common/goacc/mdc-2.c
+++ b/gcc/testsuite/c-c++-common/goacc/mdc-2.c
@@ -39,7 +39,7 @@ t1 ()
 #pragma acc enter data attach(z[3]) /* { dg-error "expected pointer in .attach. clause" } */
 #pragma acc exit data detach(z[3]) /* { dg-error "expected pointer in .detach. clause" } */
 
-#pragma acc acc enter data attach(s.e)
+#pragma acc enter data attach(s.e)
 #pragma acc exit data detach(s.e) attach(z) /* { dg-error ".attach. is not valid for" } */
 
 #pragma acc data attach(s.e)
diff --git a/gcc/testsuite/g++.dg/goacc/mdc.C b/gcc/testsuite/g++.dg/goacc/mdc.C
index b3abab30423..e8ba1cceba2 100644
--- a/gcc/testsuite/g++.dg/goacc/mdc.C
+++ b/gcc/testsuite/g++.dg/goacc/mdc.C
@@ -45,7 +45,7 @@ t1 ()
 #pragma acc enter data attach(rz[3]) /* { dg-error "expected pointer in .attach. clause" } */
 #pragma acc exit data detach(rz[3]) /* { dg-error "expected pointer in .detach. clause" } */
 
-#pragma acc acc enter data attach(rs.e)
+#pragma acc enter data attach(rs.e)
 #pragma acc exit data detach(rs.e) attach(rz) /* { dg-error ".attach. is not valid for" } */
 
 #pragma acc data attach(rs.e)
-- 
2.30.2



Re: [PATCH] Expose stable sort algorithm to gcc_sort_r and add vec::stablesort

2021-06-10 Thread Alexander Monakov via Gcc-patches
On Thu, 10 Jun 2021, Richard Biener wrote:

> This makes it possible to apply GCCs stable sort algorithm to vec<>
> and also use it with the qsort_r compatible interface.
> 
> Alex, any comments?

I'm afraid the patch is not correct, see below; (I'll also point out
errors in comments while at it).

> Bootstrapped & tested on x86_64-unknown-linux-gnu (with some
> not here included changes to actually use stablesort)
> 
> 2021-06-10  Richard Biener  
> 
>   * system.h (gcc_stablesort_r): Declare.
>   * sort.cc (gcc_sort_r): Support stable sort.
>   (gcc_stablesort_r): Define.
>   * vec.h (vec<>::stablesort): Add.
> ---
>  gcc/sort.cc  | 14 +-
>  gcc/system.h |  1 +
>  gcc/vec.h| 24 
>  3 files changed, 38 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/sort.cc b/gcc/sort.cc
> index fe499b5ec73..e27b90ebbdd 100644
> --- a/gcc/sort.cc
> +++ b/gcc/sort.cc
> @@ -277,8 +277,12 @@ gcc_sort_r (void *vbase, size_t n, size_t size, 
> sort_r_cmp_fn *cmp, void *data)
>  {
>if (n < 2)
>  return;
> +  size_t nlim = 5;
> +  bool stable = (ssize_t) size < 0;
> +  if (stable)
> +nlim = 3, size = ~size;
>char *base = (char *)vbase;
> -  sort_r_ctx c = {data, cmp, base, n, size, 5};
> +  sort_r_ctx c = {data, cmp, base, n, size, nlim};
>long long scratch[32];
>size_t bufsz = (n / 2) * size;
>void *buf = bufsz <= sizeof scratch ? scratch : xmalloc (bufsz);
> @@ -296,3 +300,11 @@ gcc_stablesort (void *vbase, size_t n, size_t size, 
> cmp_fn *cmp)
>  {
>gcc_qsort (vbase, n, ~size, cmp);
>  }
> +
> +/* Stable sort, signature-compatible to C qsort_r.  */

"Glibc qsort_r" (no _r variant in C, and BSD signature differs).

> +void
> +gcc_stablesort_r (void *vbase, size_t n, size_t size, sort_r_cmp_fn *cmp,
> +   void *data)
> +{
> +  gcc_sort_r (vbase, n, ~size, cmp, data);
> +}
> diff --git a/gcc/system.h b/gcc/system.h
> index 3c856266cc2..adde3e264b6 100644
> --- a/gcc/system.h
> +++ b/gcc/system.h
> @@ -1250,6 +1250,7 @@ void gcc_sort_r (void *, size_t, size_t, sort_r_cmp_fn 
> *, void *);
>  void gcc_qsort (void *, size_t, size_t, int (*)(const void *, const void *));
>  void gcc_stablesort (void *, size_t, size_t,
>int (*)(const void *, const void *));
> +void gcc_stablesort_r (void *, size_t, size_t, sort_r_cmp_fn *, void *data);
>  /* Redirect four-argument qsort calls to gcc_qsort; one-argument invocations
> correspond to vec::qsort, and use C qsort internally.  */
>  #define PP_5th(a1, a2, a3, a4, a5, ...) a5
> diff --git a/gcc/vec.h b/gcc/vec.h
> index 24df2db0eeb..c02a834c171 100644
> --- a/gcc/vec.h
> +++ b/gcc/vec.h
> @@ -612,6 +612,7 @@ public:
>void block_remove (unsigned, unsigned);
>void qsort (int (*) (const void *, const void *));
>void sort (int (*) (const void *, const void *, void *), void *);
> +  void stablesort (int (*) (const void *, const void *, void *), void *);
>T *bsearch (const void *key, int (*compar)(const void *, const void *));
>T *bsearch (const void *key,
> int (*compar)(const void *, const void *, void *), void *);
> @@ -1160,6 +1161,17 @@ vec::sort (int (*cmp) (const void *, 
> const void *, void *),
>  gcc_sort_r (address (), length (), sizeof (T), cmp, data);
>  }
>  
> +/* Sort the contents of this vector with qsort.  CMP is the comparison
> +   function to pass to qsort.  */

Not with 'qsort', but gcc_stablesort_r.

> +
> +template
> +inline void
> +vec::stablesort (int (*cmp) (const void *, const void *,
> +  void *), void *data)
> +{
> +  if (length () > 1)
> +gcc_stablesort_r (address (), length (), ~sizeof (T), cmp, data);
> +}

I think this is wrong. You're passing inverted size to gcc_stablesort_r, which
will invert it again, and you end up with normal non-stable sorting function.

With that fixed, I think the patch would be correct.

>  
>  /* Search the contents of the sorted vector with a binary search.
> CMP is the comparison function to pass to bsearch.  */
> @@ -1488,6 +1500,7 @@ public:
>void block_remove (unsigned, unsigned);
>void qsort (int (*) (const void *, const void *));
>void sort (int (*) (const void *, const void *, void *), void *);
> +  void stablesort (int (*) (const void *, const void *, void *), void *);
>T *bsearch (const void *key, int (*compar)(const void *, const void *));
>T *bsearch (const void *key,
> int (*compar)(const void *, const void *, void *), void *);
> @@ -2053,6 +2066,17 @@ vec::sort (int (*cmp) (const void 
> *, const void *,
>  m_vec->sort (cmp, data);
>  }
>  
> +/* Sort the contents of this vector with qsort.  CMP is the comparison
> +   function to pass to qsort.  */

Like above, copy-paste issue in comment.

> +
> +template
> +inline void
> +vec::stablesort (int (*cmp) (const void *, const void *,
> +  void *), void *data)
> +{
> +  if (m_vec)
> +

Re: [PATCH] rs6000: Support more short/char to float conversion

2021-06-10 Thread Segher Boessenkool
Hi!

On Thu, Jun 10, 2021 at 05:32:23PM +0800, Kewen.Lin wrote:
> +/* { dg-do compile { target lp64 } } */

One final thing: what requires lp64 here?  Could you try without please?

Okay for trunk with that considered.  Thanks!


Segher


Re: [PATCH] c++: Add C++23 consteval if support - P1938R3 [PR100974]

2021-06-10 Thread Jonathan Wakely via Gcc-patches
On Thu, 10 Jun 2021 at 11:34, Jakub Jelinek wrote:
>
> On Thu, Jun 10, 2021 at 11:24:43AM +0100, Jonathan Wakely wrote:
> > > And I'm not changing the libstdc++ side, where perhaps we could change
> > > std::is_constant_evaluated definition for
> > > #ifdef __cpp_if_consteval
> > > case to if consteval { return true; } else { return false; }
> > > but we need to keep it defined to __builtin_is_constant_evaluated ()
> > > for C++20 or older.
> >
> > Is there any advantage to changing that (cheaper for GCC to evaluate?)
>
> I guess compile-time lost in the noise.
>
> > or should we just continue to use the __builtin unconditionally?
> >
> > I suppose it's theoretically possible that there could be a non-GCC
> > compiler where defined(__cpp_if_consteval) is true but
> > __has_builtin(__builtin_is_constant_evaluated) is false.
>
> Up to you.  The wording says Equivalent to
> if consteval { return true; } else { return false; }
> and return __builtin_is_constant_evaluated (); is equivalent to that.
>
> Perhaps some people could appreciate to see it literally there, but we

Those people can write their own pure-C++23 library then ;-)

> can't use it for C++20 (due to the -Wpedantic warnings or -pedantic-errors

Yeah.

> errors) and for C++17 and earlier (consteval is not a keyword).

std::is_constant_evaluated isn't defined for C++17 and earlier, so in
C++14 and C++17 code we have to use the builtin directly (and for
C++11 constexpr is so limited that there are no uses for it).

I think we should just leave it as-is, and revisit if a good reason
arises in future.



Re: [PATCH] c++: Add C++23 consteval if support - P1938R3 [PR100974]

2021-06-10 Thread Jakub Jelinek via Gcc-patches
On Thu, Jun 10, 2021 at 11:24:43AM +0100, Jonathan Wakely wrote:
> > And I'm not changing the libstdc++ side, where perhaps we could change
> > std::is_constant_evaluated definition for
> > #ifdef __cpp_if_consteval
> > case to if consteval { return true; } else { return false; }
> > but we need to keep it defined to __builtin_is_constant_evaluated ()
> > for C++20 or older.
> 
> Is there any advantage to changing that (cheaper for GCC to evaluate?)

I guess compile-time lost in the noise.

> or should we just continue to use the __builtin unconditionally?
> 
> I suppose it's theoretically possible that there could be a non-GCC
> compiler where defined(__cpp_if_consteval) is true but
> __has_builtin(__builtin_is_constant_evaluated) is false.

Up to you.  The wording says Equivalent to
if consteval { return true; } else { return false; }
and return __builtin_is_constant_evaluated (); is equivalent to that.

Perhaps some people could appreciate to see it literally there, but we
can't use it for C++20 (due to the -Wpedantic warnings or -pedantic-errors
errors) and for C++17 and earlier (consteval is not a keyword).

Jakub



Re: RFC: Sphinx for GCC documentation

2021-06-10 Thread Martin Liška

On 6/7/21 4:19 PM, Tobias Burnus wrote:


On 07.06.21 15:28, Martin Liška wrote:

* I note that we write before the argument index, that those are
without -/-- prefix
   but that's not true. Something to fix after the conversation.


Can you please show me a few examples of it?


* https://splichal.eu/scripts/sphinx/gfortran/_build/html/option-index.html

* https://splichal.eu/scripts/sphinx/gcc/_build/html/option-index.html

* https://splichal.eu/scripts/sphinx/cpp/_build/html/option-index.html

Read the text on those page – and then look at the converted index,
which has all the '-' and '--' before the options.


You are right, I updated the Option Index pages.

Martin



That's not a conversion bug – a change which needs to be done as part of
or after the conversion.

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf




Re: [PATCH] c++: Add C++23 consteval if support - P1938R3 [PR100974]

2021-06-10 Thread Jonathan Wakely via Gcc-patches
On Thu, 10 Jun 2021 at 09:34, Jakub Jelinek wrote:
> Also, the paper doesn't contain the exact __cpp_if_consteval value,

Right, proposals aren't supposed to, because the value gets set when
the proposal is voted into the working draft (which the proposal
author doesn't control).

> but https://github.com/cplusplus/draft/pull/4660/files mentions 202106L
> which this patch uses.

That's the right value.

> And I'm not changing the libstdc++ side, where perhaps we could change
> std::is_constant_evaluated definition for
> #ifdef __cpp_if_consteval
> case to if consteval { return true; } else { return false; }
> but we need to keep it defined to __builtin_is_constant_evaluated ()
> for C++20 or older.

Is there any advantage to changing that (cheaper for GCC to evaluate?)
or should we just continue to use the __builtin unconditionally?

I suppose it's theoretically possible that there could be a non-GCC
compiler where defined(__cpp_if_consteval) is true but
__has_builtin(__builtin_is_constant_evaluated) is false.



Re: [PATCH] PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514

2021-06-10 Thread Bernhard Reutner-Fischer via Gcc-patches
On Wed, 9 Jun 2021 23:39:45 +0200
Harald Anlauf via Gcc-patches  wrote:

> diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
> index c27b47aa98f..016ec259518 100644
> --- a/gcc/fortran/simplify.c
> +++ b/gcc/fortran/simplify.c
> @@ -4512,6 +4512,60 @@ gfc_simplify_leadz (gfc_expr *e)
>  }
> 
> 
> +/* Check for constant length of a substring.  */
> +
> +static bool
> +substring_has_constant_len (gfc_expr *e)
> +{
> +  ptrdiff_t istart, iend;
> +  size_t length;
> +  bool equal_length = false;
> +
> +  if (e->ts.type != BT_CHARACTER
> +  || !(e->ref && e->ref->type == REF_SUBSTRING)

iff we ever can get here with e->ref == NULL then the below will not
work too well. If so then maybe
  if (e->ts.type != BT_CHARACTER
  || ! e->ref
  || e->ref->type != REF_SUBSTRING

?

> +  || !e->ref->u.ss.start
> +  || e->ref->u.ss.start->expr_type != EXPR_CONSTANT
> +  || !e->ref->u.ss.end
> +  || e->ref->u.ss.end->expr_type != EXPR_CONSTANT
> +  || !e->ref->u.ss.length
> +  || !e->ref->u.ss.length->length
> +  || e->ref->u.ss.length->length->expr_type != EXPR_CONSTANT)
> +return false;
> +
> +  /* Basic checks on substring starting and ending indices.  */
> +  if (!gfc_resolve_substring (e->ref, _length))
> +return false;
> +
> +  istart = gfc_mpz_get_hwi (e->ref->u.ss.start->value.integer);
> +  iend = gfc_mpz_get_hwi (e->ref->u.ss.end->value.integer);
> +  length = gfc_mpz_get_hwi (e->ref->u.ss.length->length->value.integer);
> +
> +  if (istart <= iend)
> +{
> +  if (istart < 1)
> + {
> +   gfc_error ("Substring start index (%ld) at %L below 1",
> +  (long) istart, >ref->u.ss.start->where);
> +   return false;
> + }
> +  if (iend > (ssize_t) length)
> + {
> +   gfc_error ("Substring end index (%ld) at %L exceeds string "
> +  "length", (long) iend, >ref->u.ss.end->where);
> +   return false;
> + }
> +  length = iend - istart + 1;
> +}
> +  else
> +length = 0;
> +
> +  /* Fix substring length.  */
> +  e->value.character.length = length;
> +
> +  return true;
> +}
> +
> +
>  gfc_expr *
>  gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
>  {
> @@ -4547,6 +4601,13 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
> of the unlimited polymorphic entity.  To get the _len component the 
> last
> _data ref needs to be stripped and a ref to the _len component added. 
>  */
>  return gfc_get_len_component (e->symtree->n.sym->assoc->target, k);
> +  else if (substring_has_constant_len (e))
> +{
> +  result = gfc_get_constant_expr (BT_INTEGER, k, >where);
> +  mpz_set_si (result->value.integer,
> +   e->value.character.length);

I think the mpz_set_si args above fit on one line.

btw.. there's a commentary typo in add_init_expr_to_sym():
s/skeep/skip/

thanks,

> +  return range_check (result, "LEN");
> +}
>else
>  return NULL;
>  }
> diff --git a/gcc/testsuite/gfortran.dg/pr100950.f90 
> b/gcc/testsuite/gfortran.dg/pr100950.f90
> new file mode 100644
> index 000..f06db45b0b4
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/pr100950.f90
> @@ -0,0 +1,18 @@
> +! { dg-do run }
> +! PR fortran/100950 - ICE in output_constructor_regular_field, at 
> varasm.c:5514
> +
> +program p
> +  character(8), parameter :: u = "123"
> +  character(8):: x = "", s
> +  character(2):: w(2) = [character(len(x(3:4))) :: 'a','b' ]
> +  character(*), parameter :: y(*) = [character(len(u(3:4))) :: 'a','b' ]
> +  character(*), parameter :: z(*) = [character(len(x(3:4))) :: 'a','b' ]
> +  if (len (y) /= 2) stop 1
> +  if (len (z) /= 2) stop 2
> +  if (any (w /= y)) stop 3
> +  if (len ([character(len(u(3:4))) :: 'a','b' ]) /= 2)  stop 4
> +  if (len ([character(len(x(3:4))) :: 'a','b' ]) /= 2)  stop 5
> +  if (any ([character(len(x(3:4))) :: 'a','b' ]  /= y)) stop 6
> +  write(s,*) [character(len(x(3:4))) :: 'a','b' ]
> +  if (s /= " a b") stop 7
> +end



Re: [PATCH 2/2] arm: Auto-vectorization for MVE: add pack/unpack patterns

2021-06-10 Thread Christophe Lyon via Gcc-patches
On Tue, 8 Jun 2021 at 14:10, Richard Sandiford
 wrote:
>
> Christophe Lyon  writes:
> > This patch adds vec_unpack_hi_, vec_unpack_lo_,
> > vec_pack_trunc_ patterns for MVE.
> >
> > It does so by moving the unpack patterns from neon.md to
> > vec-common.md, while adding them support for MVE. The pack expander is
> > derived from the Neon one (which in turn is renamed into
> > neon_quad_vec_pack_trunc_).
> >
> > The patch introduces mve_vec_pack_trunc_ to avoid the need for a
> > zero-initialized temporary, which is needed if the
> > vec_pack_trunc_ expander calls @mve_vmovn[bt]q_
> > instead.
> >
> > With this patch, we can now vectorize the 16 and 8-bit versions of
> > vclz and vshl, although the generated code could still be improved.
> > For test_clz_s16, we now generate
> > vldrh.16q3, [r1]
> > vmovlb.s16   q2, q3
> > vmovlt.s16   q3, q3
> > vclz.i32  q2, q2
> > vclz.i32  q3, q3
> > vmovnb.i32  q1, q2
> > vmovnt.i32  q1, q3
> > vstrh.16q1, [r0]
> > which could be improved to
> > vldrh.16q3, [r1]
> >   vclz.i16q1, q3
> > vstrh.16q1, [r0]
> > if we could avoid the need for unpack/pack steps.
>
> Yeah, there was a PR about fixing this for popcount.  I guess the same
> approach would apply here too.
>
> > For reference, clang-12 generates:
> >   vldrh.s32   q0, [r1]
> >   vldrh.s32   q1, [r1, #8]
> >   vclz.i32q0, q0
> >   vstrh.32q0, [r0]
> >   vclz.i32q0, q1
> >   vstrh.32q0, [r0, #8]
> >
> > 2021-06-03  Christophe Lyon  
> >
> >   gcc/
> >   * config/arm/mve.md (mve_vmovltq_): Prefix with '@'.
> >   (mve_vmovlbq_): Likewise.
> >   (mve_vmovnbq_): Likewise.
> >   (mve_vmovntq_): Likewise.
> >   (@mve_vec_pack_trunc_): New pattern.
> >   * config/arm/neon.md (vec_unpack_hi_): Move to
> >   vec-common.md.
> >   (vec_unpack_lo_): Likewise.
> >   (vec_pack_trunc_): Rename to
> >   neon_quad_vec_pack_trunc_.
> >   * config/arm/vec-common.md (vec_unpack_hi_): New
> >   pattern.
> >   (vec_unpack_lo_): New.
> >   (vec_pack_trunc_): New.
> >
> >   gcc/testsuite/
> >   * gcc.target/arm/simd/mve-vclz.c: Update expected results.
> >   * gcc.target/arm/simd/mve-vshl.c: Likewise.
> > ---
> >  gcc/config/arm/mve.md| 20 -
> >  gcc/config/arm/neon.md   | 39 +
> >  gcc/config/arm/vec-common.md | 89 
> >  gcc/testsuite/gcc.target/arm/simd/mve-vclz.c |  7 +-
> >  gcc/testsuite/gcc.target/arm/simd/mve-vshl.c |  5 +-
> >  5 files changed, 114 insertions(+), 46 deletions(-)
> >
> > diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
> > index 99e46d0bc69..b18292c07d3 100644
> > --- a/gcc/config/arm/mve.md
> > +++ b/gcc/config/arm/mve.md
> > @@ -510,7 +510,7 @@ (define_insn "mve_vrev32q_"
> >  ;;
> >  ;; [vmovltq_u, vmovltq_s])
> >  ;;
> > -(define_insn "mve_vmovltq_"
> > +(define_insn "@mve_vmovltq_"
> >[
> > (set (match_operand: 0 "s_register_operand" "=w")
> >   (unspec: [(match_operand:MVE_3 1 "s_register_operand" 
> > "w")]
> > @@ -524,7 +524,7 @@ (define_insn "mve_vmovltq_"
> >  ;;
> >  ;; [vmovlbq_s, vmovlbq_u])
> >  ;;
> > -(define_insn "mve_vmovlbq_"
> > +(define_insn "@mve_vmovlbq_"
> >[
> > (set (match_operand: 0 "s_register_operand" "=w")
> >   (unspec: [(match_operand:MVE_3 1 "s_register_operand" 
> > "w")]
> > @@ -2187,7 +2187,7 @@ (define_insn "mve_vmlsldavxq_s"
> >  ;;
> >  ;; [vmovnbq_u, vmovnbq_s])
> >  ;;
> > -(define_insn "mve_vmovnbq_"
> > +(define_insn "@mve_vmovnbq_"
> >[
> > (set (match_operand: 0 "s_register_operand" "=w")
> >   (unspec: [(match_operand: 1 
> > "s_register_operand" "0")
> > @@ -2202,7 +2202,7 @@ (define_insn "mve_vmovnbq_"
> >  ;;
> >  ;; [vmovntq_s, vmovntq_u])
> >  ;;
> > -(define_insn "mve_vmovntq_"
> > +(define_insn "@mve_vmovntq_"
> >[
> > (set (match_operand: 0 "s_register_operand" "=w")
> >   (unspec: [(match_operand: 1 
> > "s_register_operand" "0")
> > @@ -2214,6 +2214,18 @@ (define_insn "mve_vmovntq_"
> >[(set_attr "type" "mve_move")
> >  ])
> >
> > +(define_insn "@mve_vec_pack_trunc_"
> > + [(set (match_operand: 0 "register_operand" "=")
> > +   (vec_concat:
> > + (truncate:
> > + (match_operand:MVE_5 1 "register_operand" "w"))
> > + (truncate:
> > + (match_operand:MVE_5 2 "register_operand" "w"]
> > + "TARGET_HAVE_MVE"
> > + "vmovnb.i%q0, %q1\;vmovnt.i   %q0, %q2"
> > +  [(set_attr "type" "mve_move")]
> > +)
> > +
>
> I realise this is (like you say) based on the neon.md pattern,
> but we should use separate vmovnb and vmovnt instructions instead
> of putting two instructions into a single pattern.
>
> One specific advantage to using separate patterns is that it would
> avoid the 

[PATCH] Expose stable sort algorithm to gcc_sort_r and add vec::stablesort

2021-06-10 Thread Richard Biener
This makes it possible to apply GCCs stable sort algorithm to vec<>
and also use it with the qsort_r compatible interface.

Alex, any comments?

Bootstrapped & tested on x86_64-unknown-linux-gnu (with some
not here included changes to actually use stablesort)

2021-06-10  Richard Biener  

* system.h (gcc_stablesort_r): Declare.
* sort.cc (gcc_sort_r): Support stable sort.
(gcc_stablesort_r): Define.
* vec.h (vec<>::stablesort): Add.
---
 gcc/sort.cc  | 14 +-
 gcc/system.h |  1 +
 gcc/vec.h| 24 
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/gcc/sort.cc b/gcc/sort.cc
index fe499b5ec73..e27b90ebbdd 100644
--- a/gcc/sort.cc
+++ b/gcc/sort.cc
@@ -277,8 +277,12 @@ gcc_sort_r (void *vbase, size_t n, size_t size, 
sort_r_cmp_fn *cmp, void *data)
 {
   if (n < 2)
 return;
+  size_t nlim = 5;
+  bool stable = (ssize_t) size < 0;
+  if (stable)
+nlim = 3, size = ~size;
   char *base = (char *)vbase;
-  sort_r_ctx c = {data, cmp, base, n, size, 5};
+  sort_r_ctx c = {data, cmp, base, n, size, nlim};
   long long scratch[32];
   size_t bufsz = (n / 2) * size;
   void *buf = bufsz <= sizeof scratch ? scratch : xmalloc (bufsz);
@@ -296,3 +300,11 @@ gcc_stablesort (void *vbase, size_t n, size_t size, cmp_fn 
*cmp)
 {
   gcc_qsort (vbase, n, ~size, cmp);
 }
+
+/* Stable sort, signature-compatible to C qsort_r.  */
+void
+gcc_stablesort_r (void *vbase, size_t n, size_t size, sort_r_cmp_fn *cmp,
+ void *data)
+{
+  gcc_sort_r (vbase, n, ~size, cmp, data);
+}
diff --git a/gcc/system.h b/gcc/system.h
index 3c856266cc2..adde3e264b6 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1250,6 +1250,7 @@ void gcc_sort_r (void *, size_t, size_t, sort_r_cmp_fn *, 
void *);
 void gcc_qsort (void *, size_t, size_t, int (*)(const void *, const void *));
 void gcc_stablesort (void *, size_t, size_t,
 int (*)(const void *, const void *));
+void gcc_stablesort_r (void *, size_t, size_t, sort_r_cmp_fn *, void *data);
 /* Redirect four-argument qsort calls to gcc_qsort; one-argument invocations
correspond to vec::qsort, and use C qsort internally.  */
 #define PP_5th(a1, a2, a3, a4, a5, ...) a5
diff --git a/gcc/vec.h b/gcc/vec.h
index 24df2db0eeb..c02a834c171 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -612,6 +612,7 @@ public:
   void block_remove (unsigned, unsigned);
   void qsort (int (*) (const void *, const void *));
   void sort (int (*) (const void *, const void *, void *), void *);
+  void stablesort (int (*) (const void *, const void *, void *), void *);
   T *bsearch (const void *key, int (*compar)(const void *, const void *));
   T *bsearch (const void *key,
  int (*compar)(const void *, const void *, void *), void *);
@@ -1160,6 +1161,17 @@ vec::sort (int (*cmp) (const void *, 
const void *, void *),
 gcc_sort_r (address (), length (), sizeof (T), cmp, data);
 }
 
+/* Sort the contents of this vector with qsort.  CMP is the comparison
+   function to pass to qsort.  */
+
+template
+inline void
+vec::stablesort (int (*cmp) (const void *, const void *,
+void *), void *data)
+{
+  if (length () > 1)
+gcc_stablesort_r (address (), length (), ~sizeof (T), cmp, data);
+}
 
 /* Search the contents of the sorted vector with a binary search.
CMP is the comparison function to pass to bsearch.  */
@@ -1488,6 +1500,7 @@ public:
   void block_remove (unsigned, unsigned);
   void qsort (int (*) (const void *, const void *));
   void sort (int (*) (const void *, const void *, void *), void *);
+  void stablesort (int (*) (const void *, const void *, void *), void *);
   T *bsearch (const void *key, int (*compar)(const void *, const void *));
   T *bsearch (const void *key,
  int (*compar)(const void *, const void *, void *), void *);
@@ -2053,6 +2066,17 @@ vec::sort (int (*cmp) (const void *, 
const void *,
 m_vec->sort (cmp, data);
 }
 
+/* Sort the contents of this vector with qsort.  CMP is the comparison
+   function to pass to qsort.  */
+
+template
+inline void
+vec::stablesort (int (*cmp) (const void *, const void *,
+void *), void *data)
+{
+  if (m_vec)
+m_vec->stablesort (cmp, data);
+}
 
 /* Search the contents of the sorted vector with a binary search.
CMP is the comparison function to pass to bsearch.  */
-- 
2.26.2


Re: [PATCH] rs6000: Support more short/char to float conversion

2021-06-10 Thread Kewen.Lin via Gcc-patches
Hi Segher,

Thanks for the review!

on 2021/6/10 上午7:23, Segher Boessenkool wrote:
> Hi!
> 
> On Fri, May 07, 2021 at 10:30:38AM +0800, Kewen.Lin wrote:
>> For some cases that when we load unsigned char/short values from
>> the appropriate unsigned char/short memories and convert them to
>> double/single precision floating point value, there would be
>> implicit conversions to int first.  It makes GCC not leverage the
>> P9 instructions lxsibzx/lxsihzx.  This patch is to add the related
>> define_insn_and_split to support this kind of scenario.
> 
>> +/* { dg-final { scan-assembler "lxsibzx"  } } */
>> +/* { dg-final { scan-assembler "lxsihzx"  } } */
>> +/* { dg-final { scan-assembler "vextsb2d" } } */
>> +/* { dg-final { scan-assembler "vextsh2d" } } */
> 
> On my unpatched compiler all these already work, but you say they don't?
> 

Sorry for the confusion, the patch is to handle the unsigned char and short
but the test case also has the test coverage on signed char and short, which
follows the existing cases p9-fpcvt-{1,2}.c.  As you stated, the signed part
of cases are fine.

> For the first two I get
> lxsibzx 33,0,3
> vextsb2d 0,1
> xscvsxddp 0,32
> fadd 1,0,1
> blr
> and
> lbz 9,0(3)
> mtvsrwa 0,9
> fcfid 0,0
> fadd 1,0,1
> blr
> is that different for you?
> 

I got the same output without the patch, applying the patch the second one
becomes into:

lxsibzx 0,0,3
fcfid 0,0
fadd 1,0,1
blr

> In either case, use \m and \M please.
> 

Fixed.

>> +/* { dg-final { scan-assembler-not "mfvsrd"   } } */
>> +/* { dg-final { scan-assembler-not "mfvsrwz"  } } */
>> +/* { dg-final { scan-assembler-not "mtvsrd"   } } */
>> +/* { dg-final { scan-assembler-not "mtvsrwa"  } } */
>> +/* { dg-final { scan-assembler-not "mtvsrwz"  } } */
> 
> Here as well, or you could just do
> 
> /* { dg-final { scan-assembler-not "\mm[tf]vsr"  } } */
> 
> in this case, since no VSR<->GPR moves should happen at all.
> 
Thanks, updated accordingly.

The patch v2 is attached, does it look better?

BR,
Kewen
--
gcc/ChangeLog:

* config/rs6000/rs6000.md
(floatsi2_lfiwax__mem_zext): New
define_insn_and_split.

gcc/testsuite/ChangeLog:

* gcc.target/powerpc/p9-fpcvt-3.c: New test.
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 3f59b544f6a..0574e10f923 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -5524,6 +5524,27 @@ (define_insn_and_split "floatsi2_lfiwax_mem"
   [(set_attr "length" "8")
(set_attr "type" "fpload")])
 
+(define_insn_and_split "floatsi2_lfiwax__mem_zext"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,")
+   (float:SFDF
+(zero_extend:SI
+ (match_operand:QHI 1 "indexed_or_indirect_operand" "Z,Z"
+   (clobber (match_scratch:DI 2 "=d,wa"))]
+  "TARGET_HARD_FLOAT &&  && TARGET_P9_VECTOR
+   && TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
+  "#"
+  "&& 1"
+  [(pc)]
+{
+  if (GET_CODE (operands[2]) == SCRATCH)
+operands[2] = gen_reg_rtx (DImode);
+  emit_insn (gen_zero_extendhidi2 (operands[2], operands[1]));
+  emit_insn (gen_floatdi2 (operands[0], operands[2]));
+  DONE;
+}
+  [(set_attr "length" "8")
+   (set_attr "type" "fpload")])
+
 (define_insn "lfiwzx"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-fpcvt-3.c 
b/gcc/testsuite/gcc.target/powerpc/p9-fpcvt-3.c
new file mode 100644
index 000..19701c84add
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-fpcvt-3.c
@@ -0,0 +1,23 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -O2" } */
+
+/* Note that for unsigned cases, the differences from those ones in
+   p9-fpcvt-2.c is that they will be converted to int implicitly first
+   and then to floating point.  */
+
+double sc_df (signed char*p, double df) { return *p + df; }
+double uc_df (unsigned char  *p, double df) { return *p + df; }
+double ss_df (signed short   *p, double df) { return *p + df; }
+double us_df (unsigned short *p, double df) { return *p + df; }
+
+float sc_sf (signed char*p, float sf) { return *p + sf; }
+float uc_sf (unsigned char  *p, float sf) { return *p + sf; }
+float ss_sf (signed short   *p, float sf) { return *p + sf; }
+float us_sf (unsigned short *p, float sf) { return *p + sf; }
+
+/* { dg-final { scan-assembler {\mlxsibzx\M}  } } */
+/* { dg-final { scan-assembler {\mlxsihzx\M}  } } */
+/* { dg-final { scan-assembler {\mvextsb2d\M} } } */
+/* { dg-final { scan-assembler {\mvextsh2d\M} } } */
+/* { dg-final { scan-assembler-not {\mm[tf]vsr}   } } */


Re: GCC documentation: porting to Sphinx

2021-06-10 Thread Martin Liška

On 6/4/21 5:10 PM, Martin Sebor wrote:

On 6/3/21 4:56 AM, Martin Liška wrote:

On 6/2/21 10:41 PM, Martin Sebor wrote:

On 5/31/21 7:25 AM, Martin Liška wrote:

Hello.

I've made quite some progress with the porting of the documentation and
I would like to present it to the community now:
https://splichal.eu/scripts/sphinx/




Hello.

Thank you for the review.


Just a few issues I noticed in the warnings section:

The headings of some warnings mention the same option twice (e.g.,
-Wabi, -Wabi, -Wno-abi;  -Wdouble-promotion, -Wdouble-promotion,
-Wno-double-promotion;  -Winit-self, -Winit-self, -Wno-init-self).
This looks like a pretty pervasive problem.


You are right, I fixed that.


Looks good.





Mentioning the -Wno-xxx option is redundant in a heading for -Wxxx.


Yes. Good reason for that is that Sphinx can then generated properly links
to the current non-documented version of the option. Hope it's improvement
over the current situation?


Hello.

Back to this after some thinking.



I think the linking is helpful.  But for warnings, the documented
convention is to only mention the one that's not the default:

   This manual lists only one of the two forms, whichever is not
   the default.

so including both blurs this (IMO rather subtle) distinction.
In addition, in options whose description says something like
"This warning is enabled by -Wall." it's now less clear which
one is the one the "this" refers to (see for example
-Wchar-subscripts).


Yes, that's really confusing and we should likely explicitly document
both options as shown here (-Wno-shift-overflow3):

https://splichal.eu/scripts/sphinx/demo/_build/html/#cmdoption-Wno-shift-overflow3

Doing that, one has 2 unique links, that would be needed for get_option_url 
function.
Plus, both :option:`-Wfoo` and :option:`-Wno-foo` references are going to work.



If the heading can't be changed at a minimum we'll need to update
the convention above, e.g., by saying that the first option mentions
is the default. But again, I think this is too subtle for the casual
reader to pick up on.  The fact that the sentence quoted above appears
under -Wfatal-errors doesn't help.  We should also work on updating
the "This option is in -Wall." either to name the specific option
it refers to, or consider moving that into a Note box like the one
listing the languages the option applies to.)


Yes, we should explicitly mark one of them as default value,
something like "Default option value for -Wshift-overflow3."?
And the corresponding counter-part should have "Enabled by -Wall.". I'm not 
fully
convinced about usage of note as it's quite big visual component.







The headings of some other warnings also mention options that are
only remotely related to them.  E.g., -Wformat has all these:

   -Wformat, -Wno-format, -ffreestanding, -fno-builtin, -Wformat=

(I see the same problem in the attributes section where the headings
for some attributes include option names).

That seems quite puzzling.  I assume it's a consequence of having
index entries for the related options, but I don't think making
them visible in the headings is helfpful.


Oh, you are right. It was consequence of wrong parsing of index entries.
It should be fixed now.


Looks good.





Headings that in the manual today include a level like

   -Wformat-overflow
   -Wformat-overflow=level

don't mention the level in the Spinx manual:

   -Wformat-overflow, -Wno-format-overflow

When the /level/ is then discussed in the rest of the text it's
not clear what it refers to.


Should be also fixed now.


Also looks good.



Can you please take a look at the current output and give me a feedback?


I noticed another minor issue that may already have been pointed
out by someone else.  Under -Wall (and -Wextra), some option names
are prefixed by :option: (e.g., (only with :option:-O2``).  Looks
like some sort of a transcription bug?


Yes, that should be fixed now. Most comment root cause is that some inline
roles are wrapped (that's not supported).



And a couple of questions:

References to options with an argument like -Warray-bounds=1 are
rendered in a way that makes it look like there's a space before
the equals: -Warray-bounds =1, with  the =1 being in a different
color and not part of the hyperlink. Is there a way to make it look
like there is no space?


Likely not. That's the best I was able to come up with. Reason why the '=1'
argument is in :samp: is that :option:`-Wfoo=123` does not properly generate 
link
to the option directive. And there's actually no space in HTML, it's only 
slightly
visually separated and PDF version is fine for me.



I like how options are automatically linked, and I'd like to see
the same for other references like to attributes.  Can that be
automated as part of the migration or should we/I try to tackle
it in a followup?


Right now, I abuse a bit .. option:: my_attribute directive for them.
For the future, yes, one can make a link to them with 

[PATCH] Use auto_vec in ssa_equiv_stack.

2021-06-10 Thread Aldy Hernandez via Gcc-patches
There is a mismatch between the new and the delete for the
ssa_equiv_stack class.  The correct idiom should have been delete[].
It has been pointed out that perhaps a better alternative is to use
an auto_vec which does everything automatically.  Plus, it is more
consistent with m_stack which is already an auto_vec.

This patch fixes the issue in PR100984.

Tested on x86-64 Linux.

OK?

gcc/ChangeLog:

PR tree-optimization/100984
* gimple-ssa-evrp.c (ssa_equiv_stack::~ssa_equiv_stack):
---
 gcc/gimple-ssa-evrp.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c
index 7e1cf51239a..eb8320ae9d8 100644
--- a/gcc/gimple-ssa-evrp.c
+++ b/gcc/gimple-ssa-evrp.c
@@ -53,7 +53,6 @@ class ssa_equiv_stack
 {
 public:
   ssa_equiv_stack ();
-  ~ssa_equiv_stack ();
   void enter (basic_block);
   void leave (basic_block);
   void push_replacement (tree name, tree replacement);
@@ -61,19 +60,13 @@ public:
 
 private:
   auto_vec> m_stack;
-  tree *m_replacements;
+  auto_vec m_replacements;
   const std::pair  m_marker = std::make_pair (NULL, NULL);
 };
 
 ssa_equiv_stack::ssa_equiv_stack ()
 {
-  m_replacements = new tree[num_ssa_names] ();
-}
-
-ssa_equiv_stack::~ssa_equiv_stack ()
-{
-  m_stack.release ();
-  delete m_replacements;
+  m_replacements.safe_grow_cleared (num_ssa_names);
 }
 
 // Pushes a marker at the given point.
-- 
2.31.1



[PATCH] tree-optimization/101003 - use pattern defs when linearizing

2021-06-10 Thread Richard Biener
We of course have to use pattern stmt defs for the linearized
chain operands which is what I failed to ensure.

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

2021-06-10  Richard Biener  

PR tree-optimization/101003
* tree-vect-slp.c (vect_build_slp_tree_2): Appropriately
use the pattern stmt defs when linearizing a chain.
---
 gcc/tree-vect-slp.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 1915d74070b..c4f8f38012f 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -1806,6 +1806,11 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
  stmt_vec_info def_stmt_info;
  bool res = vect_is_simple_use (op, vinfo, , 
_stmt_info);
  gcc_assert (res);
+ if (dt == vect_internal_def)
+   {
+ def_stmt_info = vect_stmt_to_vectorize (def_stmt_info);
+ op = gimple_get_lhs (def_stmt_info->stmt);
+   }
  gimple *use_stmt;
  use_operand_p use_p;
  if (dt == vect_internal_def
-- 
2.26.2


[PATCH] c++: Add C++23 consteval if support - P1938R3 [PR100974]

2021-06-10 Thread Jakub Jelinek via Gcc-patches
Hi!

The following patch implements consteval if support.
There is a new IF_STMT_CONSTEVAL_P flag on IF_STMT and IF_COND is
boolean_false_node to match the non-manifestly constant evaluation
behavior, while constexpr evaluation special-cases it.  Perhaps cleaner
would be to set the condition to __builtin_is_constant_evaluated () call
but we need the IF_STMT_CONSTEVAL_P flag anyway and the IL would be larger.

I'm not 100% sure whether lambda body is enclosed by the surrounding
statement, I'm assuming it is not - see consteval-if10.C testcase.

Also, the paper doesn't contain the exact __cpp_if_consteval value,
but https://github.com/cplusplus/draft/pull/4660/files mentions 202106L
which this patch uses.

And I'm not changing the libstdc++ side, where perhaps we could change
std::is_constant_evaluated definition for
#ifdef __cpp_if_consteval
case to if consteval { return true; } else { return false; }
but we need to keep it defined to __builtin_is_constant_evaluated ()
for C++20 or older.

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

2021-06-10  Jakub Jelinek  

PR c++/100974 - P1938R3 - if consteval
gcc/c-family/
* c-cppbuiltin.c (c_cpp_builtins): Predefine __cpp_if_consteval for
-std=c++2b.
gcc/cp/
* cp-tree.h (struct saved_scope): Add immediate_fn_ctx_p
member.
(in_immediate_fn_ctx_p, IF_STMT_CONSTEVAL_P): Define.
* parser.c (cp_parser_lambda_expression): Temporarily disable
in_immediate_fn_ctx_p when parsing lambda body.
(cp_parser_selection_statement): Parse consteval if.
* decl.c (struct named_label_entry): Add in_consteval_if member.
(level_for_consteval_if): New function.
(poplevel_named_label_1, check_previous_goto_1, check_goto): Handle
consteval if.
* constexpr.c (cxx_eval_conditional_expression): For
IF_STMT_CONSTEVAL_P evaluate condition as if it was
__builtin_is_constant_evaluated call.
(potential_constant_expression_1): For IF_STMT_CONSTEVAL_P always
recurse on both branches.
* cp-gimplify.c (genericize_if_stmt): Genericize IF_STMT_CONSTEVAL_P
as the else branch.
* pt.c (tsubst_expr) : Copy IF_STMT_CONSTEVAL_P.
Temporarily set in_immediate_fn_ctx_p when recursing on
IF_STMT_CONSTEVAL_P then branch.
(tsubst_lambda_expr): Temporarily disable
in_immediate_fn_ctx_p when instantiating lambda body.
* call.c (immediate_invocation_p): Return false when
in_immediate_fn_ctx_p.
gcc/testsuite/
* g++.dg/cpp23/consteval-if1.C: New test.
* g++.dg/cpp23/consteval-if2.C: New test.
* g++.dg/cpp23/consteval-if3.C: New test.
* g++.dg/cpp23/consteval-if4.C: New test.
* g++.dg/cpp23/consteval-if5.C: New test.
* g++.dg/cpp23/consteval-if6.C: New test.
* g++.dg/cpp23/consteval-if7.C: New test.
* g++.dg/cpp23/consteval-if8.C: New test.
* g++.dg/cpp23/consteval-if9.C: New test.
* g++.dg/cpp23/consteval-if10.C: New test.
* g++.dg/cpp23/feat-cxx2b.C: Add __cpp_if_consteval tests.

--- gcc/c-family/c-cppbuiltin.c.jj  2021-06-09 21:54:39.433194531 +0200
+++ gcc/c-family/c-cppbuiltin.c 2021-06-10 09:49:35.776558874 +0200
@@ -1029,6 +1029,7 @@ c_cpp_builtins (cpp_reader *pfile)
{
  /* Set feature test macros for C++23.  */
  cpp_define (pfile, "__cpp_size_t_suffix=202011L");
+ cpp_define (pfile, "__cpp_if_consteval=202106L");
}
   if (flag_concepts)
 {
--- gcc/cp/cp-tree.h.jj 2021-06-09 21:54:39.474193964 +0200
+++ gcc/cp/cp-tree.h2021-06-10 09:49:35.795558610 +0200
@@ -478,6 +478,7 @@ extern GTY(()) tree cp_global_trees[CPTI
   AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR)
   CONSTRUCTOR_MUTABLE_POISON (in CONSTRUCTOR)
   OVL_HIDDEN_P (in OVERLOAD)
+  IF_STMT_CONSTEVAL_P (in IF_STMT)
   SWITCH_STMT_NO_BREAK_P (in SWITCH_STMT)
   LAMBDA_EXPR_CAPTURE_OPTIMIZED (in LAMBDA_EXPR)
   IMPLICIT_CONV_EXPR_BRACED_INIT (in IMPLICIT_CONV_EXPR)
@@ -1816,6 +1817,7 @@ struct GTY(()) saved_scope {
 /* Nonzero if we are parsing the discarded statement of a constexpr
if-statement.  */
   BOOL_BITFIELD discarded_stmt : 1;
+  BOOL_BITFIELD immediate_fn_ctx_p : 1;
 
   int unevaluated_operand;
   int inhibit_evaluation_warnings;
@@ -1879,6 +1881,7 @@ extern GTY(()) struct saved_scope *scope
 #define processing_explicit_instantiation 
scope_chain->x_processing_explicit_instantiation
 
 #define in_discarded_stmt scope_chain->discarded_stmt
+#define in_immediate_fn_ctx_p scope_chain->immediate_fn_ctx_p
 
 #define current_ref_temp_count scope_chain->ref_temp_count
 
@@ -5211,6 +5214,7 @@ more_aggr_init_expr_args_p (const aggr_i
 #define ELSE_CLAUSE(NODE)  TREE_OPERAND (IF_STMT_CHECK (NODE), 2)
 #define IF_SCOPE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 3)
 #define IF_STMT_CONSTEXPR_P(NODE) TREE_LANG_FLAG_0 (IF_STMT_CHECK 

[committed] testsuite: Uncomment __cpp_consteval test

2021-06-10 Thread Jakub Jelinek via Gcc-patches
Hi!

The __cpp_consteval macro and corresponding test have been initially
commented out because the consteval support didn't have virtual consteval
method support.  The r11-1789-ge6321c4508b2a85c21246c1c06a8208e2a151e48
change enabled the macro but didn't enable the corresponding test.

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

2021-06-10  Jakub Jelinek  

* g++.dg/cpp2a/feat-cxx2a.C: Uncomment __cpp_consteval test.
* g++.dg/cpp23/feat-cxx2b.C: Likewise.

--- gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C.jj  2020-11-14 10:40:11.257409305 
+0100
+++ gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C 2021-06-09 15:52:00.827892897 
+0200
@@ -520,13 +520,11 @@
 #  error "__cpp_constexpr_in_decltype != 201711"
 #endif
 
-/* Not supported fully yet:
 #ifndef __cpp_consteval
 #  error "__cpp_consteval"
 #elif __cpp_consteval != 201811
 #  error "__cpp_consteval != 201811"
 #endif
-*/
 
 #ifndef __cpp_concepts
 #  error "__cpp_concepts"
--- gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C.jj  2020-11-14 10:40:11.257409305 
+0100
+++ gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C 2021-06-09 15:52:00.827892897 
+0200
@@ -520,13 +520,11 @@
 #  error "__cpp_constexpr_in_decltype != 201711"
 #endif
 
-/* Not supported fully yet:
 #ifndef __cpp_consteval
 #  error "__cpp_consteval"
 #elif __cpp_consteval != 201811
 #  error "__cpp_consteval != 201811"
 #endif
-*/
 
 #ifndef __cpp_concepts
 #  error "__cpp_concepts"

Jakub



Re: [PATCH] rs6000: Support doubleword swaps removal in rot64 load store [PR100085]

2021-06-10 Thread Xionghu Luo via Gcc-patches



On 2021/6/10 00:24, Segher Boessenkool wrote:
> On Wed, Jun 09, 2021 at 11:20:20AM +0800, Xionghu Luo wrote:
>> On 2021/6/9 04:11, Segher Boessenkool wrote:
>>> On Fri, Jun 04, 2021 at 09:40:58AM +0800, Xionghu Luo wrote:
>> rejecting combination of insns 6 and 7
>> original costs 4 + 4 = 8
>> replacement cost 12
>
> So what instructions were these?  Why did the store cost 4 but the new
> one costs 12?
>>>
>>> The *vsx_le_perm_store_ instruction has the *preferred*
>>> alternative with cost 12, while the other alternative has cost 8.  Why
>>> is that?  That looks like a bug.
>>>  (set_attr "length" "12,8")
>>
>> 12 was introduced by Mike's commit c477a6674364(r6-2577), and all the 5
>> vsx_le_perm_store_ are set to 12 for modes VSX_D/VSX_W/V8HI/V16QI
>> /VSX_LE_128, I guess it is split to two rs6000_emit_le_vsx_permute before
>> reload, but 3 rs6000_emit_le_vsx_permute after reload, so the length is
>> 12, then it seems also not reasonable to change it from 12 to 8?  And I am
>> not sure when the alternative 1 will be chosen?
> 
> This is the instruction *length*, not the cost directly.  The length
> has to be correct, not lower than it will turn out to be that is, or on
> some big testcases you will get branches that cannot reach their target,
> and the resulting ICEs.
> 
> Alternatives are chosen by register allocation.  Before register
> allocation attributes are taken as if alternative 0 is selected (well,
> the first enabled alternative is selected, same thing here).
> 
> Which alternative is the expected (or wanted) one?  Either put that one
> first, or if it is the longer one, give it an explicit cost.
> 
>> ;; The post-reload split requires that we re-permute the source
>> ;; register in case it is still live.
>> (define_split
>>[(set (match_operand:VSX_LE_128 0 "memory_operand")
>>  (match_operand:VSX_LE_128 1 "vsx_register_operand"))]
>>"!BYTES_BIG_ENDIAN && TARGET_VSX && reload_completed && !TARGET_P9_VECTOR
>> && !altivec_indexed_or_indirect_operand (operands[0], mode)"
>>[(const_int 0)]
>> {
>>rs6000_emit_le_vsx_permute (operands[1], operands[1], mode);
>>rs6000_emit_le_vsx_permute (operands[0], operands[1], mode);
>>rs6000_emit_le_vsx_permute (operands[1], operands[1], mode);
>>DONE;
>> })
> 
> So it seems like it is only 3 insns in the very unlucky case?  Normally
> it will end up as just one simple store?

I am afraid there is not "simple store" for *TImode on P8LE*.  There is only
stxvd2x that rotates the element(stvx requires memory to be aligned, not
suitable pattern), so every vsx_le_perm_store_v1ti must be split to 3
instructions for alternative 0, it seems incorrect to force the cost to be 4.


  So you want an explicit cost
> here then:
> 
>;; What is the insn_cost for this insn?  The target hook can still override
>;; this.  For optimizing for size the "length" attribute is used instead.
>(define_attr "cost" "" (const_int 0))
> 
> So you would use something like
> 
>   (set_attr "cost" "4,*")
> 
> here (if I got that right, please check :-) )
> 
> HtH,
> 
> 
> Segher
> 

-- 
Thanks,
Xionghu


Re: [r12-1330 Regression] FAIL: libgomp.fortran/pr100981-2.f90 -Os execution test on Linux/x86_64

2021-06-10 Thread Richard Biener
On Thu, 10 Jun 2021, Jakub Jelinek wrote:

> On Wed, Jun 09, 2021 at 12:08:39PM -0700, sunil.k.pandey via Gcc-patches 
> wrote:
> > On Linux/x86_64,
> > 
> > 374f93da97fb0378453d503f3cfea4d7a923a89c is the first bad commit
> > commit 374f93da97fb0378453d503f3cfea4d7a923a89c
> > Author: Richard Biener 
> > Date:   Wed Jun 9 14:48:35 2021 +0200
> > 
> > tree-optimization/100981 - fix SLP patterns involving reductions
> > 
> > caused
> > 
> > FAIL: libgomp.fortran/pr100981-2.f90   -O0  execution test
> > FAIL: libgomp.fortran/pr100981-2.f90   -O1  execution test
> > FAIL: libgomp.fortran/pr100981-2.f90   -O2  execution test
> > FAIL: libgomp.fortran/pr100981-2.f90   -O3 -g  execution test
> > FAIL: libgomp.fortran/pr100981-2.f90   -Os  execution test
> 
> Aren't the dsdotr and dsdoti variables uninitialized?
> Shouldn't they be initialized to zero?
> 
> Following fixes it for me on i686-linux, but I haven't checked if it
> fails with the patch reverted.

whoops yes.  Strange my testing didn't trip (and in a just built
tree the testcases do not fail for me - "bad" luck I guess).

Thanks for fixing.
Richard.

> 2021-06-10  Jakub Jelinek  
> 
>   * testsuite/libgomp.fortran/pr100981-2.f90 (cdcdot): Initialize
>   dsdotr and dsdoti to 0.
> 
> --- libgomp/testsuite/libgomp.fortran/pr100981-2.f90.jj   2021-06-09 
> 22:51:44.548834216 +0200
> +++ libgomp/testsuite/libgomp.fortran/pr100981-2.f90  2021-06-10 
> 01:08:18.056464950 +0200
> @@ -9,6 +9,8 @@ complex function cdcdot(n, cx)
>double precision :: dsdotr, dsdoti, dt1, dt3
>  
>kx = 1
> +  dsdotr = 0
> +  dsdoti = 0
>do i = 1, n
>   dt1 = real(cx(kx))
>   dt3 = aimag(cx(kx))
> 
> 
>   Jakub
> 
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)


Re: [patch] Reuse non-gimple_reg variable for inlining

2021-06-10 Thread Richard Biener
On Wed, 9 Jun 2021, Eric Botcazou wrote:

> > I'm afraid the inliner would need to prove the to be inlined callee doesn't
> > modify its own copy of the variable too, because if it modifies it (at least
> > in C/C++ const can be cast away), then this introduces wrong-code, see
> > PR100994 for details.
> 
> Then please remove the TREE_READONLY marker in C/C++ if this is a lie.

I agree the cases are invalid C/C++ - this isn't casting away
const qualification of a pointed to type but of an object and storing
into a readonly object at least invokes undefined behavior.  It
might even be allowed to diagnose it as error.

Richard.


Re: [PATCH] PR tree-optimization/100781 - Do not calculate new values when evaluating a debug, statement.

2021-06-10 Thread Richard Biener via Gcc-patches
On Wed, Jun 9, 2021 at 5:24 PM Andrew MacLeod  wrote:
>
> On 6/9/21 7:48 AM, Richard Biener wrote:
> > On Tue, Jun 8, 2021 at 4:48 PM Andrew MacLeod  wrote:
> >>
> >>
> >> Richard.
> >>
>  Andrew
> 
> >> OK, so this would be the simple way I'd tackle this in gcc11. This
> >> should be quite safe.  Just treat debug_stmts as if they are not stmts..
> >> and make a global query.   EVRP will still provide a contextual range as
> >> good as it ever did, but it wont trigger ranger lookups on debug uses
> >> any more.
> >>
> >> It bootstraps on x86_64-pc-linux-gnu.  Is there a process other than
> >> getting the OK to check this into the gcc 11 branch?  Does it go into
> >> releases/gcc-11 ?
> > it would go into releases/gcc-11, yes.
> >
> > Now,
> >
> > diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
> > index 6158a754dd6..fd7fa5e3dbb 100644
> > --- a/gcc/gimple-range.cc
> > +++ b/gcc/gimple-range.cc
> > @@ -945,7 +945,7 @@ gimple_ranger::range_of_expr (irange , tree
> > expr, gimple *stmt)
> >   return get_tree_range (r, expr);
> >
> > // If there is no statement, just get the global value.
> > -  if (!stmt)
> > +  if (!stmt || is_gimple_debug (stmt))
> >   {
> >
> > unfortunately the function is not documented so I'm just guessing here - why
> > do we end up passing in a debug stmt as 'stmt'?  (how should expr and stmt
> > relate?)  So isn't it better to do this check before
> >
> >if (!gimple_range_ssa_p (expr))
> >  return get_tree_range (r, expr);
> This parts just handles the non-ssa names, so constants, types , things
> for which there is no lookup involved.. At least in GCC 11.
> >
> > or even more better, assert we don't get a debug stmt here and fixup whoever
> > calls range_of_expr to not do that for debug stmts?  When I add this
> > assertion not even libgcc can configure...  backtraces look like
>
> range_of_expr is the basic API for asking for the range of EXPR as if it
> occurs as a use on STMT.  STMT provides the context for a location in
> the IL.  if STMT isn't provided, it picks up the global range. EXPR does
> not necessarily have to occur on stmt, it's just the context point for
> finding the range.   It should be documented in value-query.h where it
> is initially declared, but I see it is not.  Sorry about that.. It seems
> to have gotten lost in the myriad of moves that were made. We have a
> definite lack of documentation on everything... that is next in
> priority,  once I get the remaining relation code in.
>
> I don't think its wrong to supply a debug stmt.  stmt is simply the
> location in the IL for which we are querying the range of EXPR. So this
> is something like
>
> # DEBUG d => d_10
>
> and the query is asking for the range of d_10 at this point in the IL..
> ie, what would it be on this stmt.   There isn't anything wrong with
> that..  and we certainly make no attempt to stop it for that reason..
> This change does prevent any analytics from happening (as does the one
> on trunk).
>
> >
> > #0  fancy_abort (file=0x2a71420 
> > "../../src/gcc-11-branch/gcc/gimple-range.cc",
> >  line=944,
> >  function=0x2a71638  > tree_node*, gimple*)::__FUNCTION__> "range_of_expr")
> >  at ../../src/gcc-11-branch/gcc/diagnostic.c:1884
> > #1  0x01f28275 in gimple_ranger::range_of_expr (this=0x3274eb0, 
> > r=...,
> >  expr=, stmt=)
> >  at ../../src/gcc-11-branch/gcc/gimple-range.cc:944
> > #2  0x0151ab7c in range_query::value_of_expr (this=0x3274eb0,
> >  name=, stmt=)
> >  at ../../src/gcc-11-branch/gcc/value-query.cc:86
> > #3  0x01f36ce3 in hybrid_folder::value_of_expr (this=0x7fffd990,
> >  op=, stmt=)
> >  at ../../src/gcc-11-branch/gcc/gimple-ssa-evrp.c:235
> > #4  0x01387804 in substitute_and_fold_engine::replace_uses_in (
> >  this=0x7fffd990, stmt=)
> >  at ../../src/gcc-11-branch/gcc/tree-ssa-propagate.c:871
> >
> > so after EVRP we substitute and fold - but note we're not expecting to do
> > any more analysis in this phase but simply use the computed lattice,
> > since we don't substitute in unreachable code regions and thus SSA form
> > is temporarily broken that might otherwise cause issues.
> >
> > But yes, substitute and fold does substitute into debug stmts (but we don't
> > analyze debug stmts).  So maybe somehow arrange for the substitute_and_fold
> In which case this change is exactly what is needed. S will call
> range_of_expr asking for the range on the debug_stmt, and this change
> returns the global range instead of looking it up.
> > phase to always only use global ranges?  Maybe add the ability to
> > "lock" a ranger instance (disabling any further on-demand processing)?
>
> The change on trunk is better as it effectively makes debug stmts always
> use whatever the best value we know is without doing anything new. It
> only reverts to the global range if there is nothing better.  It depends
> on a bunch of other structural changes I wouldn't want