Re: hardcmp: split before dispatch edge

2022-03-24 Thread Richard Biener via Gcc-patches
On Thu, Mar 24, 2022 at 2:43 AM Alexandre Oliva via Gcc-patches
 wrote:
>
>
> If we harden a compare at the end of a block with an edge to the
> abnormal dispatch block, it won't have a single successor.  Arrange to
> split the block at its final stmt so as to have a single succ.
>
> Regstrapped on x86_64-linux-gnu.  Ok to install?

OK.

>
> for  gcc/ChangeLog
>
> PR middle-end/104975
> * gimple-harden-conditionals.cc
> (pass_harden_compares::execute): Force split in case of
> multiple edges.
>
> for  gcc/testsuite/ChangeLog
>
> PR middle-end/104975
> * gcc.dg/pr104975.c: New.
> ---
>  gcc/gimple-harden-conditionals.cc |   12 +---
>  gcc/testsuite/gcc.dg/pr104975.c   |   20 
>  2 files changed, 29 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/pr104975.c
>
> diff --git a/gcc/gimple-harden-conditionals.cc 
> b/gcc/gimple-harden-conditionals.cc
> index 6a5fc3fb9e1a2..be01f3ea8c44a 100644
> --- a/gcc/gimple-harden-conditionals.cc
> +++ b/gcc/gimple-harden-conditionals.cc
> @@ -509,10 +509,16 @@ pass_harden_compares::execute (function *fun)
> gsi_insert_before (&gsi_split, asgnck, GSI_SAME_STMT);
>
> /* We wish to insert a cond_expr after the compare, so arrange
> -  for it to be at the end of a block if it isn't.  */
> -   if (!gsi_end_p (gsi_split))
> +  for it to be at the end of a block if it isn't, and for it
> +  to have a single successor in case there's more than
> +  one, as in PR104975.  */
> +   if (!gsi_end_p (gsi_split)
> +   || !single_succ_p (gsi_bb (gsi_split)))
>   {
> -   gsi_prev (&gsi_split);
> +   if (!gsi_end_p (gsi_split))
> + gsi_prev (&gsi_split);
> +   else
> + gsi_split = gsi_last_bb (gsi_bb (gsi_split));
> basic_block obb = gsi_bb (gsi_split);
> basic_block nbb = split_block (obb, gsi_stmt (gsi_split))->dest;
> gsi_next (&gsi_split);
> diff --git a/gcc/testsuite/gcc.dg/pr104975.c b/gcc/testsuite/gcc.dg/pr104975.c
> new file mode 100644
> index 0..04532fc444340
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr104975.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -fharden-compares -fno-inline -fno-ipa-pure-const" } */
> +
> +__attribute__ ((pure, returns_twice)) int
> +bar (int);
> +
> +int
> +quux (void)
> +{
> +  return 0;
> +}
> +
> +int
> +foo (short int x)
> +{
> +  x = !x;
> +  bar (quux ());
> +
> +  return x;
> +}
>
>
> --
> Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
>Free Software Activist   GNU Toolchain Engineer
> Disinformation flourishes because many people care deeply about injustice
> but very few check the facts.  Ask me about 


Re: hardened conditionals: drop copied identifiers

2022-03-24 Thread Richard Biener via Gcc-patches
On Thu, Mar 24, 2022 at 5:06 AM Alexandre Oliva via Gcc-patches
 wrote:
>
>
> The copies of identifiers, indended to associate hardening SSA
> temporaries to the original variables they refer to, end up causing
> -fcompare-debug to fail, because DECL_UIDs are not identical, and the
> nouid flag used in compare-debug dumps doesn't affect the uids in
> naked identifiers, so the divergence becomes apparent.
>
> This patch drops the naked identifiers.  Though somewhat desirable,
> they're not necessary.
>
> Regstrapped on x86_64-linux-gnu.  Ok to install?

OK.

>
> for  gcc/ChangeLog
>
> PR debug/104564
> * gimple-harden-conditionals.cc (detach_value): Keep temps
> anonymous.
>
> for  gcc/testsuite/ChangeLog
>
> PR debug/104564
> * c-c++-common/torture/harden-comp.c: Adjust.
> * c-c++-common/torture/harden-cond.c: Adjust.
> ---
>  gcc/gimple-harden-conditionals.cc|   11 ---
>  gcc/testsuite/c-c++-common/torture/harden-comp.c |2 +-
>  gcc/testsuite/c-c++-common/torture/harden-cond.c |2 +-
>  3 files changed, 6 insertions(+), 9 deletions(-)
>
> diff --git a/gcc/gimple-harden-conditionals.cc 
> b/gcc/gimple-harden-conditionals.cc
> index be01f3ea8c44a..c7e5e077a74f6 100644
> --- a/gcc/gimple-harden-conditionals.cc
> +++ b/gcc/gimple-harden-conditionals.cc
> @@ -126,14 +126,11 @@ detach_value (location_t loc, gimple_stmt_iterator 
> *gsip, tree val)
>return val;
>  }
>
> -  /* Create a SSA "copy" of VAL.  This could be an anonymous
> - temporary, but it's nice to have it named after the corresponding
> - variable.  Alas, when VAL is a DECL_BY_REFERENCE RESULT_DECL,
> - setting (a copy of) it would be flagged by checking, so we don't
> - use copy_ssa_name: we create an anonymous SSA name, and then give
> - it the same identifier (rather than decl) as VAL.  */
> +  /* Create a SSA "copy" of VAL.  It would be nice to have it named
> + after the corresponding variable, but sharing the same decl is
> + problematic when VAL is a DECL_BY_REFERENCE RESULT_DECL, and
> + copying just the identifier hits -fcompare-debug failures.  */
>tree ret = make_ssa_name (TREE_TYPE (val));
> -  SET_SSA_NAME_VAR_OR_IDENTIFIER (ret, SSA_NAME_IDENTIFIER (val));
>
>/* Some modes won't fit in general regs, so we fall back to memory
>   for them.  ??? It would be ideal to try to identify an alternate,
> diff --git a/gcc/testsuite/c-c++-common/torture/harden-comp.c 
> b/gcc/testsuite/c-c++-common/torture/harden-comp.c
> index 1ee0b3663443d..502f52e25be24 100644
> --- a/gcc/testsuite/c-c++-common/torture/harden-comp.c
> +++ b/gcc/testsuite/c-c++-common/torture/harden-comp.c
> @@ -11,4 +11,4 @@ f (int i, int j)
>  /* { dg-final { scan-tree-dump-times "Adding reversed compare" 1 "hardcmp" } 
> } */
>  /* { dg-final { scan-tree-dump-times "__builtin_trap" 1 "hardcmp" } } */
>  /* { dg-final { scan-tree-dump-times "_\[0-9\]* = i_\[0-9\]*\[(\]D\[)\] < 
> j_\[0-9\]*\[(\]D\[)\];" 1 "hardcmp" } } */
> -/* { dg-final { scan-tree-dump-times "_\[0-9\]* = i_\[0-9\]* >= j_\[0-9\]*;" 
> 1 "hardcmp" } } */
> +/* { dg-final { scan-tree-dump-times "_\[0-9\]* = _\[0-9\]* >= _\[0-9\]*;" 1 
> "hardcmp" } } */
> diff --git a/gcc/testsuite/c-c++-common/torture/harden-cond.c 
> b/gcc/testsuite/c-c++-common/torture/harden-cond.c
> index 86de8e155ed38..213b048b25af5 100644
> --- a/gcc/testsuite/c-c++-common/torture/harden-cond.c
> +++ b/gcc/testsuite/c-c++-common/torture/harden-cond.c
> @@ -15,4 +15,4 @@ f (int i, int j)
>  /* { dg-final { scan-tree-dump-times "Adding reversed compare" 2 "hardcbr" } 
> } */
>  /* { dg-final { scan-tree-dump-times "__builtin_trap" 2 "hardcbr" } } */
>  /* { dg-final { scan-tree-dump-times "if \[(\]i_\[0-9\]*\[(\]D\[)\] < 
> j_\[0-9\]*\[(\]D\[)\]\[)\]" 1 "hardcbr" } } */
> -/* { dg-final { scan-tree-dump-times "if \[(\]i_\[0-9\]* >= j_\[0-9\]*\[)\]" 
> 2 "hardcbr" } } */
> +/* { dg-final { scan-tree-dump-times "if \[(\]_\[0-9\]* >= _\[0-9\]*\[)\]" 2 
> "hardcbr" } } */
>
>
> --
> Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
>Free Software Activist   GNU Toolchain Engineer
> Disinformation flourishes because many people care deeply about injustice
> but very few check the facts.  Ask me about 


Re: [PATCH] tree-optimization/104970: Limit size computation for access attribute

2022-03-24 Thread Jakub Jelinek via Gcc-patches
On Thu, Mar 24, 2022 at 08:39:44AM +0530, Siddhesh Poyarekar wrote:
> Limit object size computation only to the simple case where access
> attribute has been explicitly specified.  The object passed to
> __builtin_dynamic_object_size could either be a pointer or a VLA whose
> size has been described only using access attribute.
> 
> Further, return a valid size only if the object is a void * pointer or
> points to (or is a VLA of) a type that has a constant size.
> 
> gcc/ChangeLog:
> 
>   PR tree-optimization/104970
>   * tree-object-size.cc (parm_object_size): Restrict size
>   computation scenarios to explicit access attributes.
> 
> gcc/testsuite/ChangeLog:
> 
>   PR tree-optimization/104970
>   * gcc.dg/builtin-dynamic-object-size-0.c (test_parmsz_simple2,
>   test_parmsz_simple3, test_parmsz_extern, test_parmsz_internal,
>   test_parmsz_internal2, test_parmsz_internal3): New tests.
>   (main): Use them.
> 
> Signed-off-by: Siddhesh Poyarekar 

Ok, thanks.

Jakub



[PATCH][libatomic] Fix return value in libat_test_and_set

2022-03-24 Thread Tom de Vries via Gcc-patches
Hi,

On nvptx (using a Quadro K2000 with driver 470.103.01) I ran into this:
...
FAIL: gcc.dg/atomic/stdatomic-flag-2.c -O1 execution test
...
which mimimized to:
...
  #include 
  atomic_flag a = ATOMIC_FLAG_INIT;
  int main () {
if ((atomic_flag_test_and_set) (&a))
  __builtin_abort ();
return 0;
  }
...

The atomic_flag_test_and_set is implemented using __atomic_test_and_set_1,
which corresponds to the "word-sized compare-and-swap loop" version of
libat_test_and_set in libatomic/tas_n.c.

The semantics of a test-and-set is that the return value is "true if and only
if the previous contents were 'set'".

But the code uses:
...
  return woldval != 0;
...
which means it doesn't look only at the byte that was either set or not set,
but at the entire word.

Fix this by using instead:
...
  return (woldval & wval) == wval;
...

Tested on nvptx.

OK for trunk?

Thanks,
- Tom

[libatomic] Fix return value in libat_test_and_set

---
 libatomic/tas_n.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libatomic/tas_n.c b/libatomic/tas_n.c
index d0d8c283b49..65eaa7753a5 100644
--- a/libatomic/tas_n.c
+++ b/libatomic/tas_n.c
@@ -73,7 +73,7 @@ SIZE(libat_test_and_set) (UTYPE *mptr, int smodel)
 __ATOMIC_RELAXED, __ATOMIC_RELAXED));
 
   post_barrier (smodel);
-  return woldval != 0;
+  return (woldval & wval) == wval;
 }
 
 #define DONE 1


Re: [PATCH][libatomic] Fix return value in libat_test_and_set

2022-03-24 Thread Jakub Jelinek via Gcc-patches
On Thu, Mar 24, 2022 at 09:28:15AM +0100, Tom de Vries via Gcc-patches wrote:
> Hi,
> 
> On nvptx (using a Quadro K2000 with driver 470.103.01) I ran into this:
> ...
> FAIL: gcc.dg/atomic/stdatomic-flag-2.c -O1 execution test
> ...
> which mimimized to:
> ...
>   #include 
>   atomic_flag a = ATOMIC_FLAG_INIT;
>   int main () {
> if ((atomic_flag_test_and_set) (&a))
>   __builtin_abort ();
> return 0;
>   }
> ...
> 
> The atomic_flag_test_and_set is implemented using __atomic_test_and_set_1,
> which corresponds to the "word-sized compare-and-swap loop" version of
> libat_test_and_set in libatomic/tas_n.c.
> 
> The semantics of a test-and-set is that the return value is "true if and only
> if the previous contents were 'set'".
> 
> But the code uses:
> ...
>   return woldval != 0;
> ...
> which means it doesn't look only at the byte that was either set or not set,
> but at the entire word.
> 
> Fix this by using instead:
> ...
>   return (woldval & wval) == wval;

Shouldn't that be instead
  return (woldval & ((UWORD) -1 << shift)) != 0;
or
  return (woldval & ((UWORD) ~(UWORD) 0 << shift)) != 0;
?
The exact __GCC_ATOMIC_TEST_AND_SET_TRUEVAL varies (the most usual
value is 1, but sparc uses 0xff and m68k/sh use 0x80), falseval is
always 0 though and (woldval & wval) == wval
is testing whether some bits of the oldval are all set rather than
whether the old byte was 0.
Say for trueval 1 it tests whether the least significant bit is set,
for 0x80 if the most significant bit of the byte is set, for
0xff whether all bits are set.

Jakub



[PATCH] fold-const: Handle C++ dependent COMPONENT_REFs in operand_equal_p [PR105035]

2022-03-24 Thread Jakub Jelinek via Gcc-patches
Hi!

As mentioned in the PR, operand_equal_p already contains some hacks so that
it can be called already on pre-instantiation C++ trees from templates,
but the recent change to compare DECL_FIELD_OFFSET in the COMPONENT_REF
case broke this.  Many such COMPONENT_REFs are already punted on earlier
because they have NULL TREE_TYPE, but in this case the code knows what
type they have but still uses an IDENTIFIER_NODE as second operand
of COMPONENT_REF (I think SCOPE_REF is something that could be used too).

The following patch looks at those DECL_FIELD_*OFFSET fields only if
both field[01] args are FIELD_DECLs and otherwise keeps it to the
earlier OP_SAME (1) check that guards this whole block.

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

2022-03-24  Jakub Jelinek  

PR c++/105035
* fold-const.cc (operand_equal_p) : If either
field0 or field1 is not a FIELD_DECL, return false.

* g++.dg/warn/Wduplicated-cond2.C: New test.

--- gcc/fold-const.cc.jj2022-03-18 18:32:36.175078948 +0100
+++ gcc/fold-const.cc   2022-03-23 13:40:49.893266570 +0100
@@ -3357,8 +3357,11 @@ operand_compare::operand_equal_p (const_
tree field0 = TREE_OPERAND (arg0, 1);
tree field1 = TREE_OPERAND (arg1, 1);
 
-   if (!operand_equal_p (DECL_FIELD_OFFSET (field0),
- DECL_FIELD_OFFSET (field1), flags)
+   /* Non-FIELD_DECL operands can appear in C++ templates.  */
+   if (TREE_CODE (field0) != FIELD_DECL
+   || TREE_CODE (field1) != FIELD_DECL
+   || !operand_equal_p (DECL_FIELD_OFFSET (field0),
+DECL_FIELD_OFFSET (field1), flags)
|| !operand_equal_p (DECL_FIELD_BIT_OFFSET (field0),
 DECL_FIELD_BIT_OFFSET (field1),
 flags))
--- gcc/testsuite/g++.dg/warn/Wduplicated-cond2.C.jj2022-03-23 
13:47:36.041577821 +0100
+++ gcc/testsuite/g++.dg/warn/Wduplicated-cond2.C   2022-03-23 
13:46:54.820155190 +0100
@@ -0,0 +1,29 @@
+// PR c++/105035
+// { dg-do compile }
+// { dg-options "-Wduplicated-cond" }
+
+class A {
+  struct B { int c; int f; } e;
+  template  void foo ();
+  void bar ();
+};
+
+template  void
+A::foo ()
+{
+  int g;
+  if (&g == &e.c)
+;
+  else if (&g == &e.f)
+;
+}
+
+void
+A::bar ()
+{
+  int g;
+  if (&g == &e.c)  // { dg-message "previously used here" }
+;
+  else if (&g == &e.c) // { dg-warning "duplicated 'if' condition" }
+;
+}

Jakub



Re: [PATCH][libatomic] Fix return value in libat_test_and_set

2022-03-24 Thread Tom de Vries via Gcc-patches

On 3/24/22 10:02, Jakub Jelinek wrote:

On Thu, Mar 24, 2022 at 09:28:15AM +0100, Tom de Vries via Gcc-patches wrote:

Hi,

On nvptx (using a Quadro K2000 with driver 470.103.01) I ran into this:
...
FAIL: gcc.dg/atomic/stdatomic-flag-2.c -O1 execution test
...
which mimimized to:
...
   #include 
   atomic_flag a = ATOMIC_FLAG_INIT;
   int main () {
 if ((atomic_flag_test_and_set) (&a))
   __builtin_abort ();
 return 0;
   }
...

The atomic_flag_test_and_set is implemented using __atomic_test_and_set_1,
which corresponds to the "word-sized compare-and-swap loop" version of
libat_test_and_set in libatomic/tas_n.c.

The semantics of a test-and-set is that the return value is "true if and only
if the previous contents were 'set'".

But the code uses:
...
   return woldval != 0;
...
which means it doesn't look only at the byte that was either set or not set,
but at the entire word.

Fix this by using instead:
...
   return (woldval & wval) == wval;


Shouldn't that be instead
   return (woldval & ((UWORD) -1 << shift)) != 0;
or
   return (woldval & ((UWORD) ~(UWORD) 0 << shift)) != 0;
?


Well, I used '(woldval & wval) == wval' based on the fact that the set 
operation uses a bitor:

...
  wval = (UWORD)__GCC_ATOMIC_TEST_AND_SET_TRUEVAL << shift;
  woldval = __atomic_load_n (wptr, __ATOMIC_RELAXED);
  do
{
  t = woldval | wval;
...
so apparently we do not care here about bits not in 
__GCC_ATOMIC_TEST_AND_SET_TRUEVAL (or alternatively, we care but assume 
that they're 0).


AFAIU, it would have been more precise to compare the entire byte with 
__GCC_ATOMIC_TEST_AND_SET_TRUEVAL, but then it would have made sense to 
set the entire byte in the set part as well.


Anyway, that doesn't seem to be what you're proposing.  During 
investigation of the failure I found that the address used is 
word-aligned, so shift becomes 0 in that case.  AFAICT, the fix you're 
proposing is a nop for shift == 0, and indeed, it doesn't fix the 
failure I'm observing.



The exact __GCC_ATOMIC_TEST_AND_SET_TRUEVAL varies (the most usual
value is 1, but sparc uses 0xff and m68k/sh use 0x80), falseval is
always 0 though and (woldval & wval) == wval
is testing whether some bits of the oldval are all set rather than
whether the old byte was 0.
Say for trueval 1 it tests whether the least significant bit is set,
for 0x80 if the most significant bit of the byte is set, for
0xff whether all bits are set.


Yes, I noticed that.

AFAIU, the proposed patch ddrt under the assumption that we don't care 
about bits not set in __GCC_ATOMIC_TEST_AND_SET_TRUEVAL.


If that's not acceptable, I can submit a patch that doesn't have that 
assumption, and tests the entire byte (but should I also fix the set 
operation then?).


Thanks,
- Tom




Re: [PATCH] fold-const: Handle C++ dependent COMPONENT_REFs in operand_equal_p [PR105035]

2022-03-24 Thread Richard Biener via Gcc-patches
On Thu, 24 Mar 2022, Jakub Jelinek wrote:

> Hi!
> 
> As mentioned in the PR, operand_equal_p already contains some hacks so that
> it can be called already on pre-instantiation C++ trees from templates,
> but the recent change to compare DECL_FIELD_OFFSET in the COMPONENT_REF
> case broke this.  Many such COMPONENT_REFs are already punted on earlier
> because they have NULL TREE_TYPE, but in this case the code knows what
> type they have but still uses an IDENTIFIER_NODE as second operand
> of COMPONENT_REF (I think SCOPE_REF is something that could be used too).
> 
> The following patch looks at those DECL_FIELD_*OFFSET fields only if
> both field[01] args are FIELD_DECLs and otherwise keeps it to the
> earlier OP_SAME (1) check that guards this whole block.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> 2022-03-24  Jakub Jelinek  
> 
>   PR c++/105035
>   * fold-const.cc (operand_equal_p) : If either
>   field0 or field1 is not a FIELD_DECL, return false.
> 
>   * g++.dg/warn/Wduplicated-cond2.C: New test.
> 
> --- gcc/fold-const.cc.jj  2022-03-18 18:32:36.175078948 +0100
> +++ gcc/fold-const.cc 2022-03-23 13:40:49.893266570 +0100
> @@ -3357,8 +3357,11 @@ operand_compare::operand_equal_p (const_
>   tree field0 = TREE_OPERAND (arg0, 1);
>   tree field1 = TREE_OPERAND (arg1, 1);
>  
> - if (!operand_equal_p (DECL_FIELD_OFFSET (field0),
> -   DECL_FIELD_OFFSET (field1), flags)
> + /* Non-FIELD_DECL operands can appear in C++ templates.  */
> + if (TREE_CODE (field0) != FIELD_DECL
> + || TREE_CODE (field1) != FIELD_DECL
> + || !operand_equal_p (DECL_FIELD_OFFSET (field0),
> +  DECL_FIELD_OFFSET (field1), flags)
>   || !operand_equal_p (DECL_FIELD_BIT_OFFSET (field0),
>DECL_FIELD_BIT_OFFSET (field1),
>flags))
> --- gcc/testsuite/g++.dg/warn/Wduplicated-cond2.C.jj  2022-03-23 
> 13:47:36.041577821 +0100
> +++ gcc/testsuite/g++.dg/warn/Wduplicated-cond2.C 2022-03-23 
> 13:46:54.820155190 +0100
> @@ -0,0 +1,29 @@
> +// PR c++/105035
> +// { dg-do compile }
> +// { dg-options "-Wduplicated-cond" }
> +
> +class A {
> +  struct B { int c; int f; } e;
> +  template  void foo ();
> +  void bar ();
> +};
> +
> +template  void
> +A::foo ()
> +{
> +  int g;
> +  if (&g == &e.c)
> +;
> +  else if (&g == &e.f)
> +;
> +}
> +
> +void
> +A::bar ()
> +{
> +  int g;
> +  if (&g == &e.c)// { dg-message "previously used here" }
> +;
> +  else if (&g == &e.c)   // { dg-warning "duplicated 'if' condition" }
> +;
> +}
> 
>   Jakub
> 
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)


[PATCH] Fix memory leaks

2022-03-24 Thread Richard Biener via Gcc-patches
When changing the predcom pass to use auto_vec leaks were introduced by
failing to replace deallocation with C++ delete.  The following does
this.  It also fixes leaks in vectorization and range folding.

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

2022-03-24  Richard Biener  

* tree-predcom.cc (chain::chain): Add CTOR.
(component::component): Likewise.
(pcom_worker::release_chain): Use delete.
(release_components): Likewise.
(pcom_worker::filter_suitable_components): Likewise.
(pcom_worker::split_data_refs_to_components): Use new.
(make_invariant_chain): Likewise.
(make_rooted_chain): Likewise.
(pcom_worker::combine_chains): Likewise.
* tree-vect-loop.cc (vect_create_epilog_for_reduction):
Make sure to release previously constructed scalar_results.
* tree-vect-stmts.cc (vectorizable_load): Use auto_vec
for vec_offsets.
* vr-values.cc (simplify_using_ranges::~simplify_using_ranges):
Release m_flag_set_edges.
---
 gcc/tree-predcom.cc| 28 +++-
 gcc/tree-vect-loop.cc  |  3 ++-
 gcc/tree-vect-stmts.cc |  2 +-
 gcc/vr-values.cc   |  1 +
 4 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/gcc/tree-predcom.cc b/gcc/tree-predcom.cc
index 1d8121c4d80..e4aea7cdcb4 100644
--- a/gcc/tree-predcom.cc
+++ b/gcc/tree-predcom.cc
@@ -297,6 +297,11 @@ enum chain_type
 
 typedef struct chain
 {
+  chain (chain_type t) : type (t), op (ERROR_MARK), rslt_type (NULL_TREE),
+ch1 (NULL), ch2 (NULL), length (0), init_seq (NULL), fini_seq (NULL),
+has_max_use_after (false), all_always_accessed (false), combined (false),
+inv_store_elimination (false) {}
+
   /* Type of the chain.  */
   enum chain_type type;
 
@@ -362,6 +367,8 @@ enum ref_step_type
 
 struct component
 {
+  component (bool es) : eliminate_store_p (es), next (NULL) {}
+
   /* The references in the component.  */
   auto_vec refs;
 
@@ -698,7 +705,7 @@ pcom_worker::release_chain (chain_p chain)
   if (chain->fini_seq)
 gimple_seq_discard (chain->fini_seq);
 
-  free (chain);
+  delete chain;
 }
 
 /* Frees CHAINS.  */
@@ -723,7 +730,7 @@ release_components (struct component *comps)
   for (act = comps; act; act = next)
 {
   next = act->next;
-  XDELETE (act);
+  delete act;
 }
 }
 
@@ -1023,9 +1030,8 @@ pcom_worker::split_data_refs_to_components ()
   comp = comps[ca];
   if (!comp)
{
- comp = XCNEW (struct component);
- comp->refs.create (comp_size[ca]);
- comp->eliminate_store_p = eliminate_store_p;
+ comp = new component (eliminate_store_p);
+ comp->refs.reserve_exact (comp_size[ca]);
  comps[ca] = comp;
}
 
@@ -1142,7 +1148,7 @@ pcom_worker::filter_suitable_components (struct component 
*comps)
  *comp = act->next;
  FOR_EACH_VEC_ELT (act->refs, i, ref)
free (ref);
- XDELETE (act);
+ delete act;
}
 }
 
@@ -1255,12 +1261,10 @@ add_ref_to_chain (chain_p chain, dref ref)
 static chain_p
 make_invariant_chain (struct component *comp)
 {
-  chain_p chain = XCNEW (struct chain);
+  chain_p chain = new struct chain (CT_INVARIANT);
   unsigned i;
   dref ref;
 
-  chain->type = CT_INVARIANT;
-
   chain->all_always_accessed = true;
 
   FOR_EACH_VEC_ELT (comp->refs, i, ref)
@@ -1280,9 +1284,8 @@ make_invariant_chain (struct component *comp)
 static chain_p
 make_rooted_chain (dref ref, enum chain_type type)
 {
-  chain_p chain = XCNEW (struct chain);
+  chain_p chain = new struct chain (type);
 
-  chain->type = type;
   chain->refs.safe_push (ref);
   chain->all_always_accessed = ref->always_accessed;
   ref->distance = 0;
@@ -2873,8 +2876,7 @@ pcom_worker::combine_chains (chain_p ch1, chain_p ch2)
   if (swap)
 std::swap (ch1, ch2);
 
-  new_chain = XCNEW (struct chain);
-  new_chain->type = CT_COMBINATION;
+  new_chain = new struct chain (CT_COMBINATION);
   new_chain->op = op;
   new_chain->ch1 = ch1;
   new_chain->ch2 = ch2;
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 7fcec12a3e9..7a74633e0b4 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -5466,7 +5466,8 @@ vect_create_epilog_for_reduction (loop_vec_info 
loop_vinfo,
   
   scalar_dest = gimple_get_lhs (orig_stmt_info->stmt);
   scalar_type = TREE_TYPE (scalar_dest);
-  scalar_results.create (group_size); 
+  scalar_results.truncate (0);
+  scalar_results.reserve_exact (group_size);
   new_scalar_dest = vect_create_destination_var (scalar_dest, NULL);
   bitsize = TYPE_SIZE (scalar_type);
 
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 5c9e8cfefa5..f7449a79d1c 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -9480,7 +9480,7 @@ vectorizable_load (vec_info *vinfo,
  memory_access_type);
 }
 
-  vec vec_offsets = vNULL;
+  auto_vec vec_offsets;
   auto_v

Re: [PATCH] Improve profile handling in switch lowering.

2022-03-24 Thread Martin Liška

PING^2

On 3/4/22 14:47, Martin Liška wrote:

PING^1

On 1/26/22 12:11, Martin Liška wrote:

Hello.

Right now, switch lowering does not update basic_block::count values
so that they are uninitiliazed. Moreover, I've updated probability scaling
when a more complex expansion happens. There are still some situations where
the profile is a bit imprecise, but the patch improves rapidly the current 
situation.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin

 PR tree-optimization/101301
 PR tree-optimization/103680

gcc/ChangeLog:

 * tree-switch-conversion.cc (bit_test_cluster::emit):
 Handle correctly remaining probability.
 (switch_decision_tree::try_switch_expansion): Fix BB's count
 where a cluster expansion happens.
 (switch_decision_tree::emit_cmp_and_jump_insns): Fill up also
 BB count.
 (switch_decision_tree::do_jump_if_equal): Likewise.
 (switch_decision_tree::emit_case_nodes): Handle special case
 for BT expansion which can also fallback to a default BB.
 * tree-switch-conversion.h (cluster::cluster): Add
 m_default_prob probability.
---
  gcc/tree-switch-conversion.cc | 51 ---
  gcc/tree-switch-conversion.h  |  8 +-
  2 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/gcc/tree-switch-conversion.cc b/gcc/tree-switch-conversion.cc
index 670397c87e4..d6679e8dee3 100644
--- a/gcc/tree-switch-conversion.cc
+++ b/gcc/tree-switch-conversion.cc
@@ -1538,10 +1538,12 @@ bit_test_cluster::emit (tree index_expr, tree 
index_type,
    test[k].target_bb = n->m_case_bb;
    test[k].label = n->m_case_label_expr;
    test[k].bits = 0;
+  test[k].prob = profile_probability::never ();
    count++;
  }

    test[k].bits += n->get_range (n->get_low (), n->get_high ());
+  test[k].prob += n->m_prob;

    lo = tree_to_uhwi (int_const_binop (MINUS_EXPR, n->get_low (), minval));
    if (n->get_high () == NULL_TREE)
@@ -1629,6 +1631,11 @@ bit_test_cluster::emit (tree index_expr, tree index_type,
    /*simple=*/true, NULL_TREE,
    /*before=*/true, GSI_SAME_STMT);

+  profile_probability subtree_prob = m_subtree_prob;
+  profile_probability default_prob = m_default_prob;
+  if (!default_prob.initialized_p ())
+    default_prob = m_subtree_prob.invert ();
+
    if (m_handles_entire_switch && entry_test_needed)
  {
    tree range = int_const_binop (MINUS_EXPR, maxval, minval);
@@ -1639,9 +1646,10 @@ bit_test_cluster::emit (tree index_expr, tree index_type,
  /*simple=*/true, NULL_TREE,
  /*before=*/true, GSI_SAME_STMT);
    tmp = fold_build2 (GT_EXPR, boolean_type_node, idx, range);
+  default_prob = default_prob.apply_scale (1, 2);
    basic_block new_bb
  = hoist_edge_and_branch_if_true (&gsi, tmp, default_bb,
- profile_probability::unlikely ());
+ default_prob);
    gsi = gsi_last_bb (new_bb);
  }

@@ -1662,14 +1670,12 @@ bit_test_cluster::emit (tree index_expr, tree 
index_type,
    else
  csui = tmp;

-  profile_probability prob = profile_probability::always ();
-
    /* for each unique set of cases:
 if (const & csui) goto target  */
    for (k = 0; k < count; k++)
  {
-  prob = profile_probability::always ().apply_scale (test[k].bits,
- bt_range);
+  profile_probability prob = test[k].prob / (subtree_prob + default_prob);
+  subtree_prob -= test[k].prob;
    bt_range -= test[k].bits;
    tmp = wide_int_to_tree (word_type_node, test[k].mask);
    tmp = fold_build2 (BIT_AND_EXPR, word_type_node, csui, tmp);
@@ -1908,9 +1914,13 @@ switch_decision_tree::try_switch_expansion (vec 
&clusters)
    /* Emit cluster-specific switch handling.  */
    for (unsigned i = 0; i < clusters.length (); i++)
  if (clusters[i]->get_type () != SIMPLE_CASE)
-  clusters[i]->emit (index_expr, index_type,
- gimple_switch_default_label (m_switch),
- m_default_bb, gimple_location (m_switch));
+  {
+    edge e = single_pred_edge (clusters[i]->m_case_bb);
+    e->dest->count = e->src->count.apply_probability (e->probability);
+    clusters[i]->emit (index_expr, index_type,
+   gimple_switch_default_label (m_switch),
+   m_default_bb, gimple_location (m_switch));
+  }
  }

    fix_phi_operands_for_edges ();
@@ -2162,6 +2172,7 @@ switch_decision_tree::emit_cmp_and_jump_insns 
(basic_block bb, tree op0,
    edge false_edge = split_block (bb, cond);
    false_edge->flags = EDGE_FALSE_VALUE;
    false_edge->probability = prob.invert ();
+  false_edge->dest->count = bb->count.apply_probability (prob.invert ());

    edge true_edge = make_edge (bb, label_bb, EDGE_TRUE_VALUE);
    true_edge->probability = prob;
@@ -2192,6 +2203,7 @@ switch_decisi

Re: [PATCH] gcov-tool: Allow merging of empty profile lists

2022-03-24 Thread Martin Liška

On 3/23/22 15:50, Sebastian Huber wrote:

The attached script reads the log file and creates the *.gcda files using 
gcov-tool. Initially, the target files do not exist.


Now I've got your use-case and I like it. It's cool one can utilize GCOV even 
without a filesystem.

Please update the patch. I basically don't see any issues with it.

Cheers,
Martin


[PATCH v2] gcov-tool: Allow merging of empty profile lists

2022-03-24 Thread Sebastian Huber
The gcov_profile_merge() already had code to deal with profile information
which had no counterpart to merge with.  For profile information from files
with no associated counterpart, the profile information is simply used as is
with the weighting transformation applied.  Make sure that gcov_profile_merge()
works with an empty target profile list.  Return the merged profile list.

gcc/
* gcov-tool.cc (gcov_profile_merge): Adjust return type.
(profile_merge): Allow merging of directories which contain no profile
files.

libgcc/
* libgcov-util.c (gcov_profile_merge): Return the list of merged
profiles.  Accept empty target and source profile lists.
---
v2:

Adjust return value description for gcov_profile_merge().

 gcc/gcov-tool.cc  | 27 ++-
 libgcc/libgcov-util.c | 19 +++
 2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index f4e42ae763c..2e4083a664d 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -40,7 +40,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #endif
 #include 
 
-extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
+struct gcov_info*, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -141,26 +142,18 @@ profile_merge (const char *d1, const char *d2, const char 
*out, int w1, int w2)
 {
   struct gcov_info *d1_profile;
   struct gcov_info *d2_profile;
-  int ret;
+  struct gcov_info *merged_profile;
 
   d1_profile = gcov_read_profile_dir (d1, 0);
-  if (!d1_profile)
-return 1;
-
-  if (d2)
-{
-  d2_profile = gcov_read_profile_dir (d2, 0);
-  if (!d2_profile)
-return 1;
+  d2_profile = gcov_read_profile_dir (d2, 0);
 
-  /* The actual merge: we overwrite to d1_profile.  */
-  ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
+  /* The actual merge: we overwrite to d1_profile.  */
+  merged_profile = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
 
-  if (ret)
-return ret;
-}
-
-  gcov_output_files (out, d1_profile);
+  if (merged_profile)
+gcov_output_files (out, merged_profile);
+  else if (verbose)
+fnotice (stdout, "no profile files were merged\n");
 
   return 0;
 }
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ba7fb924b53..100f1b19f1a 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -674,16 +674,16 @@ find_match_gcov_info (struct gcov_info **array, int size,
 }
 
 /* Merge the list of gcov_info objects from SRC_PROFILE to TGT_PROFILE.
-   Return 0 on success: without mismatch.
-   Reutrn 1 on error.  */
+   Return the list of merged gcov_info objects.  Return NULL if the list is
+   empty.  */
 
-int
+struct gcov_info *
 gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info 
*src_profile,
 int w1, int w2)
 {
   struct gcov_info *gi_ptr;
   struct gcov_info **tgt_infos;
-  struct gcov_info *tgt_tail;
+  struct gcov_info **tgt_tail;
   struct gcov_info **in_src_not_tgt;
   unsigned tgt_cnt = 0, src_cnt = 0;
   unsigned unmatch_info_cnt = 0;
@@ -703,7 +703,10 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   for (gi_ptr = tgt_profile, i = 0; gi_ptr; gi_ptr = gi_ptr->next, i++)
 tgt_infos[i] = gi_ptr;
 
-  tgt_tail = tgt_infos[tgt_cnt - 1];
+  if (tgt_cnt)
+ tgt_tail = &tgt_infos[tgt_cnt - 1]->next;
+  else
+ tgt_tail = &tgt_profile;
 
   /* First pass on tgt_profile, we multiply w1 to all counters.  */
   if (w1 > 1)
@@ -732,14 +735,14 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   gi_ptr = in_src_not_tgt[i];
   gcov_merge (gi_ptr, gi_ptr, w2 - 1);
   gi_ptr->next = NULL;
-  tgt_tail->next = gi_ptr;
-  tgt_tail = gi_ptr;
+  *tgt_tail = gi_ptr;
+  tgt_tail = &gi_ptr->next;
 }
 
   free (in_src_not_tgt);
   free (tgt_infos);
 
-  return 0;
+  return tgt_profile;
 }
 
 typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*);
-- 
2.34.1



[Ada] Fix PR ada/104767

2022-03-24 Thread Eric Botcazou via Gcc-patches
This is a regression present on mainline, 11 and 10 branches.  When the serial 
port is closed, we need to ensure that the port handle is properly reset for 
it to be detected as closed.

Tested on x86-64/Linux, applied on mainline, 11 and 10 branches.


2022-03-24  Pascal Obry  

PR ada/104767
* libgnat/g-sercom__mingw.adb (Close): Reset port handle to -1.
* libgnat/g-sercom__linux.adb (Close): Likewise.

-- 
Eric Botcazoudiff --git a/gcc/ada/libgnat/g-sercom__linux.adb b/gcc/ada/libgnat/g-sercom__linux.adb
index a2a64b1c17f..73bbb69300e 100644
--- a/gcc/ada/libgnat/g-sercom__linux.adb
+++ b/gcc/ada/libgnat/g-sercom__linux.adb
@@ -382,6 +382,7 @@ package body GNAT.Serial_Communications is
begin
   if Port.H /= -1 then
  Res := close (int (Port.H));
+ Port.H := -1;
   end if;
end Close;
 
diff --git a/gcc/ada/libgnat/g-sercom__mingw.adb b/gcc/ada/libgnat/g-sercom__mingw.adb
index aea78aead8c..d3301bd045b 100644
--- a/gcc/ada/libgnat/g-sercom__mingw.adb
+++ b/gcc/ada/libgnat/g-sercom__mingw.adb
@@ -70,6 +70,7 @@ package body GNAT.Serial_Communications is
begin
   if Port.H /= -1 then
  Success := CloseHandle (HANDLE (Port.H));
+ Port.H := -1;
 
  if Success = Win32.FALSE then
 Raise_Error ("error closing the port");


[PATCH] testsuite: Add compat.exp testcase for most common zero width bitfld ABI passing [PR102024]

2022-03-24 Thread Jakub Jelinek via Gcc-patches
On Tue, Mar 22, 2022 at 05:51:58PM +0100, Jakub Jelinek via Gcc wrote:
> I guess it would be nice to include the testcases we are talking about,
> like { float x; int : 0; float y; } and { float x; int : 0; } and
> { int : 0; float x; } into compat.exp testsuite so that we see ABI
> differences in compat testing.

Here is a patch that does that.  It uses the struct-layout-1* framework,
but isn't generated because we don't want in this case pseudo-random
structure layouts, but particular ones we know cause or could cause problems
on some targets.  If other problematic cases are discovered, we can add
further ones.

Tested on x86_64-linux with:
make check-gcc check-g++ RUNTESTFLAGS='ALT_CC_UNDER_TEST=gcc 
ALT_CXX_UNDER_TEST=g++ compat.exp=pr102*'
and with
make check-gcc check-g++ RUNTESTFLAGS='compat.exp=pr102*'
The former as expected has:
FAIL: gcc.dg/compat/pr102024 c_compat_x_tst.o-c_compat_y_alt.o execute 
FAIL: gcc.dg/compat/pr102024 c_compat_x_alt.o-c_compat_y_tst.o execute 
fails because on x86_64 we've changed the C ABI but kept the C++ ABI here.
E.g. on rs6000 it should be the g++.dg such tests to fail (all assuming
the alt gcc/g++ is GCC 4.5 through 11).

Ok for trunk?

2022-03-24  Jakub Jelinek  

PR target/102024
* gcc.dg/compat/pr102024_main.c: New test.
* gcc.dg/compat/pr102024_test.h: New test.
* gcc.dg/compat/pr102024_x.c: New test.
* gcc.dg/compat/pr102024_y.c: New test.
* g++.dg/compat/pr102024_main.C: New test.
* g++.dg/compat/pr102024_test.h: New test.
* g++.dg/compat/pr102024_x.C: New test.
* g++.dg/compat/pr102024_y.C: New test.

--- gcc/testsuite/gcc.dg/compat/pr102024_main.c.jj  2022-03-24 
10:56:13.283921666 +0100
+++ gcc/testsuite/gcc.dg/compat/pr102024_main.c 2022-03-24 11:20:36.186978012 
+0100
@@ -0,0 +1,22 @@
+/* { dg-require-effective-target int32plus } */
+/* { dg-options "-Wno-abi" } */
+/* { dg-options "-mno-mmx -Wno-abi" { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fno-common" { target hppa*-*-hpux* powerpc*-*-darwin* } } */
+/* { dg-options "-mno-mmx -fno-common -Wno-abi" { target i?86-*-darwin* 
x86_64-*-darwin* } } */
+/* { dg-options "-mno-base-addresses" { target mmix-*-* } } */
+/* { dg-options "-mlongcalls -mtext-section-literals" { target xtensa*-*-* } } 
*/
+/* { dg-prune-output ".*-Wno-abi.*" } */
+/* { dg-prune-output ".*Offset of packed bit-field.*" } */
+#include "struct-layout-1.h"
+
+#define TX(n, type, attrs, fields, ops) extern void test##n (void);
+#include "pr102024_test.h"
+#undef TX
+
+int main (void)
+{
+#define TX(n, type, attrs, fields, ops)   test##n ();
+#include "pr102024_test.h"
+#undef TX
+  exit (fails != 0);
+}
--- gcc/testsuite/gcc.dg/compat/pr102024_test.h.jj  2022-03-24 
10:56:16.137880896 +0100
+++ gcc/testsuite/gcc.dg/compat/pr102024_test.h 2022-03-24 11:12:43.616742282 
+0100
@@ -0,0 +1,6 @@
+T(0,float a;int:0;float b;,F(0,a,42.0f,43.125f)F(0,b,-17.5f,35.75f))
+T(1,float a;int:0;,F(1,a,1.0f,17.125f))
+T(2,int:0;float a;,F(2,a,2.25f,16.5f))
+T(3,double a;long long:0;double b;,F(3,a,42.0,43.125)F(3,b,-17.5,35.75))
+T(4,double a;long long:0;,F(4,a,1.0,17.125))
+T(5,long long:0;double a;,F(5,a,2.25,16.5))
--- gcc/testsuite/gcc.dg/compat/pr102024_x.c.jj 2022-03-24 10:56:18.957840614 
+0100
+++ gcc/testsuite/gcc.dg/compat/pr102024_x.c2022-03-24 11:21:09.975494401 
+0100
@@ -0,0 +1,10 @@
+/* { dg-options "-w -Wno-abi" } */
+/* { dg-options "-w -mno-mmx -Wno-abi" { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-w -fno-common" { target hppa*-*-hpux* powerpc*-*-darwin* } } 
*/
+/* { dg-options "-w -mno-mmx -fno-common -Wno-abi" { target i?86-*-darwin* 
x86_64-*-darwin* } } */
+/* { dg-options "-w -mno-base-addresses" { target mmix-*-* } } */
+/* { dg-options "-w -mlongcalls -mtext-section-literals" { target xtensa*-*-* 
} } */
+#include "struct-layout-1_x1.h"
+#include "pr102024_test.h"
+#include "struct-layout-1_x2.h"
+#include "pr102024_test.h"
--- gcc/testsuite/gcc.dg/compat/pr102024_y.c.jj 2022-03-24 10:56:21.893798677 
+0100
+++ gcc/testsuite/gcc.dg/compat/pr102024_y.c2022-03-24 11:21:17.288389732 
+0100
@@ -0,0 +1,10 @@
+/* { dg-options "-w -Wno-abi" } */
+/* { dg-options "-w -mno-mmx -Wno-abi" { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-w -fno-common" { target hppa*-*-hpux* powerpc*-*-darwin* } } 
*/
+/* { dg-options "-w -mno-mmx -fno-common -Wno-abi" { target i?86-*-darwin* 
x86_64-*-darwin* } } */
+/* { dg-options "-w -mno-base-addresses" { target mmix-*-* } } */
+/* { dg-options "-w -mlongcalls -mtext-section-literals" { target xtensa*-*-* 
} } */
+#include "struct-layout-1_y1.h"
+#include "pr102024_test.h"
+#include "struct-layout-1_y2.h"
+#include "pr102024_test.h"
--- gcc/testsuite/g++.dg/compat/pr102024_main.C.jj  2022-03-24 
10:56:13.283921666 +0100
+++ gcc/testsuite/g++.dg/compat/pr102024_main.C 2022-03-24 11:30:15.822681715 
+0100
@@ -0,0 +1,26 @@
+/* { dg-require-effective-target int32plus } */
+/* { dg-options "

Re: [PATCH] testsuite: Add compat.exp testcase for most common zero width bitfld ABI passing [PR102024]

2022-03-24 Thread Richard Biener via Gcc-patches
On Thu, 24 Mar 2022, Jakub Jelinek wrote:

> On Tue, Mar 22, 2022 at 05:51:58PM +0100, Jakub Jelinek via Gcc wrote:
> > I guess it would be nice to include the testcases we are talking about,
> > like { float x; int : 0; float y; } and { float x; int : 0; } and
> > { int : 0; float x; } into compat.exp testsuite so that we see ABI
> > differences in compat testing.
> 
> Here is a patch that does that.  It uses the struct-layout-1* framework,
> but isn't generated because we don't want in this case pseudo-random
> structure layouts, but particular ones we know cause or could cause problems
> on some targets.  If other problematic cases are discovered, we can add
> further ones.
> 
> Tested on x86_64-linux with:
> make check-gcc check-g++ RUNTESTFLAGS='ALT_CC_UNDER_TEST=gcc 
> ALT_CXX_UNDER_TEST=g++ compat.exp=pr102*'
> and with
> make check-gcc check-g++ RUNTESTFLAGS='compat.exp=pr102*'
> The former as expected has:
> FAIL: gcc.dg/compat/pr102024 c_compat_x_tst.o-c_compat_y_alt.o execute 
> FAIL: gcc.dg/compat/pr102024 c_compat_x_alt.o-c_compat_y_tst.o execute 
> fails because on x86_64 we've changed the C ABI but kept the C++ ABI here.
> E.g. on rs6000 it should be the g++.dg such tests to fail (all assuming
> the alt gcc/g++ is GCC 4.5 through 11).
> 
> Ok for trunk?

OK.

Richard.

> 2022-03-24  Jakub Jelinek  
> 
>   PR target/102024
>   * gcc.dg/compat/pr102024_main.c: New test.
>   * gcc.dg/compat/pr102024_test.h: New test.
>   * gcc.dg/compat/pr102024_x.c: New test.
>   * gcc.dg/compat/pr102024_y.c: New test.
>   * g++.dg/compat/pr102024_main.C: New test.
>   * g++.dg/compat/pr102024_test.h: New test.
>   * g++.dg/compat/pr102024_x.C: New test.
>   * g++.dg/compat/pr102024_y.C: New test.
> 
> --- gcc/testsuite/gcc.dg/compat/pr102024_main.c.jj2022-03-24 
> 10:56:13.283921666 +0100
> +++ gcc/testsuite/gcc.dg/compat/pr102024_main.c   2022-03-24 
> 11:20:36.186978012 +0100
> @@ -0,0 +1,22 @@
> +/* { dg-require-effective-target int32plus } */
> +/* { dg-options "-Wno-abi" } */
> +/* { dg-options "-mno-mmx -Wno-abi" { target i?86-*-* x86_64-*-* } } */
> +/* { dg-options "-fno-common" { target hppa*-*-hpux* powerpc*-*-darwin* } } 
> */
> +/* { dg-options "-mno-mmx -fno-common -Wno-abi" { target i?86-*-darwin* 
> x86_64-*-darwin* } } */
> +/* { dg-options "-mno-base-addresses" { target mmix-*-* } } */
> +/* { dg-options "-mlongcalls -mtext-section-literals" { target xtensa*-*-* } 
> } */
> +/* { dg-prune-output ".*-Wno-abi.*" } */
> +/* { dg-prune-output ".*Offset of packed bit-field.*" } */
> +#include "struct-layout-1.h"
> +
> +#define TX(n, type, attrs, fields, ops) extern void test##n (void);
> +#include "pr102024_test.h"
> +#undef TX
> +
> +int main (void)
> +{
> +#define TX(n, type, attrs, fields, ops)   test##n ();
> +#include "pr102024_test.h"
> +#undef TX
> +  exit (fails != 0);
> +}
> --- gcc/testsuite/gcc.dg/compat/pr102024_test.h.jj2022-03-24 
> 10:56:16.137880896 +0100
> +++ gcc/testsuite/gcc.dg/compat/pr102024_test.h   2022-03-24 
> 11:12:43.616742282 +0100
> @@ -0,0 +1,6 @@
> +T(0,float a;int:0;float b;,F(0,a,42.0f,43.125f)F(0,b,-17.5f,35.75f))
> +T(1,float a;int:0;,F(1,a,1.0f,17.125f))
> +T(2,int:0;float a;,F(2,a,2.25f,16.5f))
> +T(3,double a;long long:0;double b;,F(3,a,42.0,43.125)F(3,b,-17.5,35.75))
> +T(4,double a;long long:0;,F(4,a,1.0,17.125))
> +T(5,long long:0;double a;,F(5,a,2.25,16.5))
> --- gcc/testsuite/gcc.dg/compat/pr102024_x.c.jj   2022-03-24 
> 10:56:18.957840614 +0100
> +++ gcc/testsuite/gcc.dg/compat/pr102024_x.c  2022-03-24 11:21:09.975494401 
> +0100
> @@ -0,0 +1,10 @@
> +/* { dg-options "-w -Wno-abi" } */
> +/* { dg-options "-w -mno-mmx -Wno-abi" { target i?86-*-* x86_64-*-* } } */
> +/* { dg-options "-w -fno-common" { target hppa*-*-hpux* powerpc*-*-darwin* } 
> } */
> +/* { dg-options "-w -mno-mmx -fno-common -Wno-abi" { target i?86-*-darwin* 
> x86_64-*-darwin* } } */
> +/* { dg-options "-w -mno-base-addresses" { target mmix-*-* } } */
> +/* { dg-options "-w -mlongcalls -mtext-section-literals" { target 
> xtensa*-*-* } } */
> +#include "struct-layout-1_x1.h"
> +#include "pr102024_test.h"
> +#include "struct-layout-1_x2.h"
> +#include "pr102024_test.h"
> --- gcc/testsuite/gcc.dg/compat/pr102024_y.c.jj   2022-03-24 
> 10:56:21.893798677 +0100
> +++ gcc/testsuite/gcc.dg/compat/pr102024_y.c  2022-03-24 11:21:17.288389732 
> +0100
> @@ -0,0 +1,10 @@
> +/* { dg-options "-w -Wno-abi" } */
> +/* { dg-options "-w -mno-mmx -Wno-abi" { target i?86-*-* x86_64-*-* } } */
> +/* { dg-options "-w -fno-common" { target hppa*-*-hpux* powerpc*-*-darwin* } 
> } */
> +/* { dg-options "-w -mno-mmx -fno-common -Wno-abi" { target i?86-*-darwin* 
> x86_64-*-darwin* } } */
> +/* { dg-options "-w -mno-base-addresses" { target mmix-*-* } } */
> +/* { dg-options "-w -mlongcalls -mtext-section-literals" { target 
> xtensa*-*-* } } */
> +#include "struct-layout-1_y1.h"
> +#include "pr102024_test.h"
> +#include "struct-layout-1_y2.h"
> +#inc

Re: [PATCH] gcov-tool: Allow merging of empty profile lists

2022-03-24 Thread Sebastian Huber

On 24/03/2022 11:29, Martin Liška wrote:

On 3/23/22 15:50, Sebastian Huber wrote:
The attached script reads the log file and creates the *.gcda files 
using gcov-tool. Initially, the target files do not exist.


Now I've got your use-case and I like it. It's cool one can utilize GCOV 
even without a filesystem.


Yes, it basically works quite well. I try to make it a bit easier to 
use. What seems to be quite common is that tests for embedded systems 
report their test data through an in order character stream, for example 
through an UART device. I used this primitive encoding of the gcov 
information:


*** BEGIN OF GCOV INFO ***

/home/EB/sebastian_h/src/lwip/b-xilinx_zynq_a9_qemu/init.gcda
YWRjZ1IzMEKtLjW3AQMAAADcaps855EX05p4KUUAAKEBOgEAAQAB
AAEAAQABAAEAAQEA
AQABAAEAAQABAAEAAQAA
AAABAQABAAEA
AAEAAQABAAEBAwAAACXn3k16
TDqmuIMwpAAAoQECAgABAwAAADzkvDcfSnvcuIMwpAAAoQH+AQMA
AACnWNZaIM7GWZ9hiOIAAKEBBAEBAwAAAPkGW3YHFUOO6Old
2wAAoQECAQABAwAAAIvy4CE9FxuM6Old2wAAoQECAQAB
AwAAANyvBDZiERlQ6Old2wAAoQECAQABAwAAACKQjCp2pYlIuIMwpAAAoQEC
AQABAwAAAKSSXEjQFDluuIMwpAAAoQH+AA==

/home/EB/sebastian_h/src/lwip/b-xilinx_zynq_a9_qemu/src/netif/ethernet.gcda
YWRjZ1IzMEIwMjW3AQMAAAC+EBQuXa7stuNAYTkAAKEBCgEAAQAA
AQABAwQbGWmmhbpBJ5lR8AAAoQEmAQAA
AAEA
AAEAAAEB


...

*** END OF GCOV INFO ***

Maybe we could add the file path into the gcov information stream using 
a new tag:


#define GCOV_TAG_GCDA_FILE_NAME  ((gcov_unsigned_t)0xa500)

Then the complete gcov information can be dumped using a single base64 
encoded stream. We could add some support to the gcov-tool to read this 
stream and merge it into gcda files.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH][libatomic] Fix return value in libat_test_and_set

2022-03-24 Thread Jakub Jelinek via Gcc-patches
On Thu, Mar 24, 2022 at 11:01:30AM +0100, Tom de Vries wrote:
> > Shouldn't that be instead
> >return (woldval & ((UWORD) -1 << shift)) != 0;
> > or
> >return (woldval & ((UWORD) ~(UWORD) 0 << shift)) != 0;
> > ?
> 
> Well, I used '(woldval & wval) == wval' based on the fact that the set
> operation uses a bitor:
> ...
>   wval = (UWORD)__GCC_ATOMIC_TEST_AND_SET_TRUEVAL << shift;
>   woldval = __atomic_load_n (wptr, __ATOMIC_RELAXED);
>   do
> {
>   t = woldval | wval;
> ...
> so apparently we do not care here about bits not in
> __GCC_ATOMIC_TEST_AND_SET_TRUEVAL (or alternatively, we care but assume that
> they're 0).
> 
> AFAIU, it would have been more precise to compare the entire byte with
> __GCC_ATOMIC_TEST_AND_SET_TRUEVAL, but then it would have made sense to set
> the entire byte in the set part as well.
> 
> Anyway, that doesn't seem to be what you're proposing.  During investigation
> of the failure I found that the address used is word-aligned, so shift
> becomes 0 in that case.  AFAICT, the fix you're proposing is a nop for shift
> == 0, and indeed, it doesn't fix the failure I'm observing.

Ah, sorry, I certainly meant
  return (woldval & ((UTYPE) -1 << shift)) != 0;
or
  return (woldval & ((UTYPE) ~(UTYPE) 0 << shift)) != 0;
i.e. more portable ways of
  return (woldval & (0xff << shift)) != 0;
which don't hardcode that UTYPE is 8-bit unsigned char.

If one uses just __atomic_test_and_set and __atomic_clear, then I think
it makes no difference.
But testing whether the old byte was non-zero more matches the previous
intent in case the previous value is neither 0 nor 
__GCC_ATOMIC_TEST_AND_SET_TRUEVAL
and treats it as "set" as well.
I think we don't need to change the loop, woldval | wval even for woldval
byte containing say 42 the or will make it still non-zero.

The documentation argues against using those atomics on types other than
bool and {,{un,}signed }char but libatomic still supports those, I believe
when one doesn't have hw specific support for these, __atomic_clear will
clear the entire UTYPE.

Jakub



Re: [PATCH] gcov-tool: Allow merging of empty profile lists

2022-03-24 Thread Martin Liška

On 3/24/22 11:51, Sebastian Huber wrote:

Maybe we could add the file path into the gcov information stream using a new 
tag:

#define GCOV_TAG_GCDA_FILE_NAME  ((gcov_unsigned_t)0xa500)

Then the complete gcov information can be dumped using a single base64 encoded 
stream. We could add some support to the gcov-tool to read this stream and 
merge it into gcda files.


I would support such patch!

Thanks,
Martin


Re: [PATCH v2] gcov-tool: Allow merging of empty profile lists

2022-03-24 Thread Martin Liška

On 3/24/22 11:34, Sebastian Huber wrote:

The gcov_profile_merge() already had code to deal with profile information
which had no counterpart to merge with.  For profile information from files
with no associated counterpart, the profile information is simply used as is
with the weighting transformation applied.  Make sure that gcov_profile_merge()
works with an empty target profile list.  Return the merged profile list.


Ok once stage1 opens.

Thanks,
Martin



gcc/
* gcov-tool.cc (gcov_profile_merge): Adjust return type.
(profile_merge): Allow merging of directories which contain no profile
files.

libgcc/
* libgcov-util.c (gcov_profile_merge): Return the list of merged
profiles.  Accept empty target and source profile lists.
---
v2:

Adjust return value description for gcov_profile_merge().

  gcc/gcov-tool.cc  | 27 ++-
  libgcc/libgcov-util.c | 19 +++
  2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index f4e42ae763c..2e4083a664d 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -40,7 +40,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
  #endif
  #include 
  
-extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);

+extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
+struct gcov_info*, int, int);
  extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
  extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
  extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -141,26 +142,18 @@ profile_merge (const char *d1, const char *d2, const char 
*out, int w1, int w2)
  {
struct gcov_info *d1_profile;
struct gcov_info *d2_profile;
-  int ret;
+  struct gcov_info *merged_profile;
  
d1_profile = gcov_read_profile_dir (d1, 0);

-  if (!d1_profile)
-return 1;
-
-  if (d2)
-{
-  d2_profile = gcov_read_profile_dir (d2, 0);
-  if (!d2_profile)
-return 1;
+  d2_profile = gcov_read_profile_dir (d2, 0);
  
-  /* The actual merge: we overwrite to d1_profile.  */

-  ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
+  /* The actual merge: we overwrite to d1_profile.  */
+  merged_profile = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
  
-  if (ret)

-return ret;
-}
-
-  gcov_output_files (out, d1_profile);
+  if (merged_profile)
+gcov_output_files (out, merged_profile);
+  else if (verbose)
+fnotice (stdout, "no profile files were merged\n");
  
return 0;

  }
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ba7fb924b53..100f1b19f1a 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -674,16 +674,16 @@ find_match_gcov_info (struct gcov_info **array, int size,
  }
  
  /* Merge the list of gcov_info objects from SRC_PROFILE to TGT_PROFILE.

-   Return 0 on success: without mismatch.
-   Reutrn 1 on error.  */
+   Return the list of merged gcov_info objects.  Return NULL if the list is
+   empty.  */
  
-int

+struct gcov_info *
  gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info 
*src_profile,
  int w1, int w2)
  {
struct gcov_info *gi_ptr;
struct gcov_info **tgt_infos;
-  struct gcov_info *tgt_tail;
+  struct gcov_info **tgt_tail;
struct gcov_info **in_src_not_tgt;
unsigned tgt_cnt = 0, src_cnt = 0;
unsigned unmatch_info_cnt = 0;
@@ -703,7 +703,10 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
for (gi_ptr = tgt_profile, i = 0; gi_ptr; gi_ptr = gi_ptr->next, i++)
  tgt_infos[i] = gi_ptr;
  
-  tgt_tail = tgt_infos[tgt_cnt - 1];

+  if (tgt_cnt)
+ tgt_tail = &tgt_infos[tgt_cnt - 1]->next;
+  else
+ tgt_tail = &tgt_profile;
  
/* First pass on tgt_profile, we multiply w1 to all counters.  */

if (w1 > 1)
@@ -732,14 +735,14 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
gi_ptr = in_src_not_tgt[i];
gcov_merge (gi_ptr, gi_ptr, w2 - 1);
gi_ptr->next = NULL;
-  tgt_tail->next = gi_ptr;
-  tgt_tail = gi_ptr;
+  *tgt_tail = gi_ptr;
+  tgt_tail = &gi_ptr->next;
  }
  
free (in_src_not_tgt);

free (tgt_infos);
  
-  return 0;

+  return tgt_profile;
  }
  
  typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*);




Re: [PATCH][libatomic] Fix return value in libat_test_and_set

2022-03-24 Thread Tom de Vries via Gcc-patches

On 3/24/22 11:59, Jakub Jelinek wrote:

On Thu, Mar 24, 2022 at 11:01:30AM +0100, Tom de Vries wrote:

Shouldn't that be instead
return (woldval & ((UWORD) -1 << shift)) != 0;
or
return (woldval & ((UWORD) ~(UWORD) 0 << shift)) != 0;
?


Well, I used '(woldval & wval) == wval' based on the fact that the set
operation uses a bitor:
...
   wval = (UWORD)__GCC_ATOMIC_TEST_AND_SET_TRUEVAL << shift;
   woldval = __atomic_load_n (wptr, __ATOMIC_RELAXED);
   do
 {
   t = woldval | wval;
...
so apparently we do not care here about bits not in
__GCC_ATOMIC_TEST_AND_SET_TRUEVAL (or alternatively, we care but assume that
they're 0).

AFAIU, it would have been more precise to compare the entire byte with
__GCC_ATOMIC_TEST_AND_SET_TRUEVAL, but then it would have made sense to set
the entire byte in the set part as well.

Anyway, that doesn't seem to be what you're proposing.  During investigation
of the failure I found that the address used is word-aligned, so shift
becomes 0 in that case.  AFAICT, the fix you're proposing is a nop for shift
== 0, and indeed, it doesn't fix the failure I'm observing.


Ah, sorry, I certainly meant
   return (woldval & ((UTYPE) -1 << shift)) != 0;
or
   return (woldval & ((UTYPE) ~(UTYPE) 0 << shift)) != 0;
i.e. more portable ways of
   return (woldval & (0xff << shift)) != 0;
which don't hardcode that UTYPE is 8-bit unsigned char.



I see, that makes sense.


If one uses just __atomic_test_and_set and __atomic_clear, then I think
it makes no difference.
But testing whether the old byte was non-zero more matches the previous
intent in case the previous value is neither 0 nor 
__GCC_ATOMIC_TEST_AND_SET_TRUEVAL
and treats it as "set" as well.
I think we don't need to change the loop, woldval | wval even for woldval
byte containing say 42 the or will make it still non-zero.

The documentation argues against using those atomics on types other than
bool and {,{un,}signed }char but libatomic still supports those, I believe
when one doesn't have hw specific support for these, __atomic_clear will
clear the entire UTYPE.


Ack, updated patch, added missing changelog contribution.

OK for trunk?

Thanks,
- Tom[libatomic] Fix return value in libat_test_and_set

On nvptx (using a Quadro K2000 with driver 470.103.01) I ran into this:
...
FAIL: gcc.dg/atomic/stdatomic-flag-2.c -O1 execution test
...
which mimimized to:
...
  #include 
  atomic_flag a = ATOMIC_FLAG_INIT;
  int main () {
if ((atomic_flag_test_and_set) (&a))
  __builtin_abort ();
return 0;
  }
...

The atomic_flag_test_and_set is implemented using __atomic_test_and_set_1,
which corresponds to the "word-sized compare-and-swap loop" version of
libat_test_and_set in libatomic/tas_n.c.

The semantics of a test-and-set is that the return value is "true if and only
if the previous contents were 'set'".

But the code uses:
...
  return woldval != 0;
...
which means it doesn't look only at the byte that was either set or not set,
but at the entire word.

Fix this by using instead:
...
  return (woldval & ((UTYPE) ~(UTYPE) 0 << shift)) != 0;
...

Tested on nvptx.

libatomic/ChangeLog:

2022-03-24  Tom de Vries  

	PR target/105011
	* tas_n.c (libat_test_and_set): Fix return value.

---
 libatomic/tas_n.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libatomic/tas_n.c b/libatomic/tas_n.c
index d0d8c283b495..524312e7d8db 100644
--- a/libatomic/tas_n.c
+++ b/libatomic/tas_n.c
@@ -73,7 +73,7 @@ SIZE(libat_test_and_set) (UTYPE *mptr, int smodel)
  __ATOMIC_RELAXED, __ATOMIC_RELAXED));
 
   post_barrier (smodel);
-  return woldval != 0;
+  return (woldval & ((UTYPE) ~(UTYPE) 0 << shift)) != 0;
 }
 
 #define DONE 1


Re: [PATCH][libatomic] Fix return value in libat_test_and_set

2022-03-24 Thread Jakub Jelinek via Gcc-patches
On Thu, Mar 24, 2022 at 01:08:56PM +0100, Tom de Vries wrote:
> Ack, updated patch, added missing changelog contribution.
> 
> OK for trunk?

Yes.  I guess it is a backport candidate to release branches as well
(after a while).

Jakub



[PATCH v10 00/12] Add LoongArch support.

2022-03-24 Thread chenglulu
Hi, all:

This is the v10 version of LoongArch Port based on 
d1ca63a1b7d5986913b14567a4950b055a5a3f07. 
Please review.

We know it is stage4, I think it is ok for a new prot.
The kernel side upstream waiting for a approval by gcc side,
if it is blocked by stage4, a approval for GCC13 will be appreciation.

The LoongArch architecture (LoongArch) is an Instruction Set
Architecture (ISA) that has a Reduced Instruction Set Computer (RISC)
style.
The documents are on
https://loongson.github.io/LoongArch-Documentation/README-EN.html

The ELF ABI Documents are on:
https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html

The binutils has been merged into trunk:
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=560b3fe208255ae909b4b1c88ba9c28b09043307

Note: We split -mabi= into -mabi=lp64d/f/s, the new options not support by 
upstream binutils yet,
this GCC port requires the following patch applied to binutils to build.
https://github.com/loongson/binutils-gdb/commit/aacb0bf860f02aa5a7dcb76dd0e392bf871c7586
(will be submitted to upstream after gcc side comfirmed)

We have compiled more than 300 CLFS packages with this compiler.
The CLFS are currently used on Cfarm machines gcc400 and gcc401.

changelog:

v1 -> v2
1. Split patch set.
2. Change some code style.
3. Add -mabi=lp64d/f/s options.
4. Change GLIBC_DYNAMIC_LINKER_LP64 name.

v2 -> v3
1. Change some code style.
2. Bug fix.

v3 -> v4
1. Change some code style.
2. Bug fix.
3. Delete some builtin macros.

v4 -> v5
1. delete wrong insn zero_extendsidi2_internal.
2. Adjust some build options.
3. Change some .c files to .cc.

v5 -> v6
1. Fix compilation issues. The generated files *.opt and *.h
   are generated to $(objdir).

v6 -> v7
1. Bug fix.
2. Change some code style.

v7 -> v8
1. Add new addressing type ADDRESS_REG_REG support.
2. Modify documentation.
3. Eliminate compile-time warnings.

v8 -> v9
1. Undefine the hook TARGET_TRULY_NOOP_TRUNCATION under the architecture.
2. Delete some unsed hooks.
3. Change some code style.
4. Modify documentation.

v9 -> v10
1. Modify code style.

*** BLURB HERE ***

chenglulu (12):
  LoongArch Port: Regenerate configure
  LoongArch Port: gcc build
  LoongArch Port: Regenerate gcc/configure.
  LoongArch Port: Machine description files.
  LoongArch Port: Machine description C files and .h files.
  LoongArch Port: Builtin functions.
  LoongArch Port: Builtin macros.
  LoongArch Port: libgcc
  LoongArch Port: Regenerate libgcc/configure.
  LoongArch Port: libgomp
  LoongArch Port: gcc/testsuite
  LoongArch Port: Add doc.

 config/picflag.m4 |3 +
 configure |   10 +-
 configure.ac  |   10 +-
 contrib/config-list.mk|4 +-
 contrib/gcc_update|2 +
 .../config/loongarch/loongarch-common.cc  |   43 +
 gcc/config.gcc|  435 +-
 gcc/config/host-linux.cc  |2 +
 gcc/config/loongarch/constraints.md   |  203 +
 gcc/config/loongarch/generic.md   |  118 +
 gcc/config/loongarch/genopts/genstr.sh|  104 +
 .../loongarch/genopts/loongarch-strings   |   58 +
 gcc/config/loongarch/genopts/loongarch.opt.in |  179 +
 gcc/config/loongarch/gnu-user.h   |   80 +
 gcc/config/loongarch/la464.md |  132 +
 gcc/config/loongarch/larchintrin.h|  355 +
 gcc/config/loongarch/linux.h  |   50 +
 gcc/config/loongarch/loongarch-builtins.cc|  424 ++
 gcc/config/loongarch/loongarch-c.cc   |  109 +
 gcc/config/loongarch/loongarch-cpu.cc |  206 +
 gcc/config/loongarch/loongarch-cpu.h  |   30 +
 gcc/config/loongarch/loongarch-def.c  |  179 +
 gcc/config/loongarch/loongarch-def.h  |  151 +
 gcc/config/loongarch/loongarch-driver.cc  |  187 +
 gcc/config/loongarch/loongarch-driver.h   |   69 +
 gcc/config/loongarch/loongarch-ftypes.def |   65 +
 gcc/config/loongarch/loongarch-modes.def  |   25 +
 gcc/config/loongarch/loongarch-opts.cc|  578 ++
 gcc/config/loongarch/loongarch-opts.h |   90 +
 gcc/config/loongarch/loongarch-protos.h   |  172 +
 gcc/config/loongarch/loongarch-str.h  |   59 +
 gcc/config/loongarch/loongarch-tune.h |   50 +
 gcc/config/loongarch/loongarch.cc | 5945 +
 gcc/config/loongarch/loongarch.h  | 1147 
 gcc/config/loongarch/loongarch.md | 3393 ++
 gcc/config/loongarch/loongarch.opt|  186 +
 gcc/config/loongarch/predicates.md|  253 +
 gcc/config/loongarch/sync.md  |  574 ++
 gcc/config/loongarch/t-linux  |   53 +
 gcc/config/loongarch/t-loongarch  |   72 +
 gcc/configure |   66 +-
 gcc/configure.ac  |   33 +-
 gcc/doc/install.texi   

[PATCH v10 01/12] LoongArch Port: Regenerate configure

2022-03-24 Thread chenglulu
* config/picflag.m4: Default add build option '-fpic' for LoongArch.
* configure: Add LoongArch tuples.
* configure.ac: Like wise.
---
 config/picflag.m4 |  3 +++
 configure | 10 +-
 configure.ac  | 10 +-
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/config/picflag.m4 b/config/picflag.m4
index 8b106f9af88..0aefcf619bf 100644
--- a/config/picflag.m4
+++ b/config/picflag.m4
@@ -44,6 +44,9 @@ case "${$2}" in
# sets the default TLS model and affects inlining.
$1=-fPIC
;;
+loongarch*-*-*)
+   $1=-fpic
+   ;;
 mips-sgi-irix6*)
# PIC is the default.
;;
diff --git a/configure b/configure
index f7e0fa46c9c..4f45340abb6 100755
--- a/configure
+++ b/configure
@@ -3060,7 +3060,7 @@ case "${ENABLE_GOLD}" in
   # Check for target supported by gold.
   case "${target}" in
 i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-* \
-| aarch64*-*-* | tilegx*-*-* | mips*-*-* | s390*-*-*)
+| aarch64*-*-* | tilegx*-*-* | mips*-*-* | s390*-*-* | loongarch*-*-*)
  configdirs="$configdirs gold"
  if test x${ENABLE_GOLD} = xdefault; then
default_ld=gold
@@ -3646,6 +3646,9 @@ case "${target}" in
   i[3456789]86-*-*)
 libgloss_dir=i386
 ;;
+  loongarch*-*-*)
+libgloss_dir=loongarch
+;;
   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
 libgloss_dir=m68hc11
 ;;
@@ -4030,6 +4033,11 @@ case "${target}" in
   wasm32-*-*)
 noconfigdirs="$noconfigdirs ld"
 ;;
+  loongarch*-*-linux*)
+;;
+  loongarch*-*-*)
+noconfigdirs="$noconfigdirs gprof"
+;;
 esac
 
 # If we aren't building newlib, then don't build libgloss, since libgloss
diff --git a/configure.ac b/configure.ac
index 434b1a267a4..3f0271ca71f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -353,7 +353,7 @@ case "${ENABLE_GOLD}" in
   # Check for target supported by gold.
   case "${target}" in
 i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-* \
-| aarch64*-*-* | tilegx*-*-* | mips*-*-* | s390*-*-*)
+| aarch64*-*-* | tilegx*-*-* | mips*-*-* | s390*-*-* | loongarch*-*-*)
  configdirs="$configdirs gold"
  if test x${ENABLE_GOLD} = xdefault; then
default_ld=gold
@@ -899,6 +899,9 @@ case "${target}" in
   i[[3456789]]86-*-*)
 libgloss_dir=i386
 ;;
+  loongarch*-*-*)
+libgloss_dir=loongarch
+;;
   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
 libgloss_dir=m68hc11
 ;;
@@ -1283,6 +1286,11 @@ case "${target}" in
   wasm32-*-*)
 noconfigdirs="$noconfigdirs ld"
 ;;
+  loongarch*-*-linux*)
+;;
+  loongarch*-*-*)
+noconfigdirs="$noconfigdirs gprof"
+;;
 esac
 
 # If we aren't building newlib, then don't build libgloss, since libgloss
-- 
2.31.1



[PATCH v10 10/12] LoongArch Port: libgomp

2022-03-24 Thread chenglulu
libgomp/

* configure.tgt: Add LoongArch triplet.
---
 libgomp/configure.tgt | 4 
 1 file changed, 4 insertions(+)

diff --git a/libgomp/configure.tgt b/libgomp/configure.tgt
index d4f1e741b5a..2cd7272fcd8 100644
--- a/libgomp/configure.tgt
+++ b/libgomp/configure.tgt
@@ -56,6 +56,10 @@ if test x$enable_linux_futex = xyes; then
config_path="linux/ia64 linux posix"
;;
 
+loongarch*-*-linux*)
+   config_path="linux posix"
+   ;;
+
 mips*-*-linux*)
config_path="linux/mips linux posix"
;;
-- 
2.31.1



[PATCH v10 03/12] LoongArch Port: Regenerate gcc/configure.

2022-03-24 Thread chenglulu
gcc/
* configure: Regenerate file.
---
 gcc/configure | 66 ++-
 1 file changed, 60 insertions(+), 6 deletions(-)

diff --git a/gcc/configure b/gcc/configure
index 14b19c8fe0c..1c1195e95cb 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -5442,6 +5442,9 @@ case "${target}" in
# sets the default TLS model and affects inlining.
PICFLAG_FOR_TARGET=-fPIC
;;
+loongarch*-*-*)
+   PICFLAG_FOR_TARGET=-fpic
+   ;;
 mips-sgi-irix6*)
# PIC is the default.
;;
@@ -7963,6 +7966,9 @@ else
 mips*-*-*)
   enable_fixed_point=yes
   ;;
+loongarch*-*-*)
+  enable_fixed_point=yes
+  ;;
 *)
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fixed-point is not 
supported for this target, ignored" >&5
 $as_echo "$as_me: WARNING: fixed-point is not supported for this target, 
ignored" >&2;}
@@ -19667,7 +19673,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 19670 "configure"
+#line 19676 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -19773,7 +19779,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 19776 "configure"
+#line 19782 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -25556,6 +25562,17 @@ foo:   data8   25
movlr24 = @tprel(foo#)'
tls_as_opt=--fatal-warnings
;;
+  loongarch*-*-*)
+conftest_s='
+   .section .tdata,"awT",@progbits
+x: .word 2
+   .text
+   la.tls.gd $a0,x
+   bl __tls_get_addr'
+   tls_first_major=0
+   tls_first_minor=0
+   tls_as_opt='--fatal-warnings'
+   ;;
   microblaze*-*-*)
 conftest_s='
.section .tdata,"awT",@progbits
@@ -28780,6 +28797,43 @@ $as_echo "#define HAVE_AS_MARCH_ZIFENCEI 1" 
>>confdefs.h
 fi
 
 ;;
+  loongarch*-*-*)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for 
.dtprelword support" >&5
+$as_echo_n "checking assembler for .dtprelword support... " >&6; }
+if ${gcc_cv_as_loongarch_dtprelword+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_loongarch_dtprelword=no
+  if test x$gcc_cv_as != x; then
+$as_echo '' > conftest.s
+if { ac_try='$gcc_cv_as $gcc_cv_as_flags 2,18,0 -o conftest.o conftest.s 
>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+then
+   .section .tdata,"awT",@progbits
+x:
+   .word 2
+   .text
+   .dtprelword x+0x8000
+else
+  echo "configure: failed program was" >&5
+  cat conftest.s >&5
+fi
+rm -f conftest.o conftest.s
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: 
$gcc_cv_as_loongarch_dtprelword" >&5
+$as_echo "$gcc_cv_as_loongarch_dtprelword" >&6; }
+
+if test $gcc_cv_as_loongarch_dtprelword != yes; then
+
+$as_echo "#define HAVE_AS_DTPRELWORD 1" >>confdefs.h
+
+fi
+;;
 s390*-*-*)
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for 
.gnu_attribute support" >&5
 $as_echo_n "checking assembler for .gnu_attribute support... " >&6; }
@@ -28943,11 +28997,11 @@ fi
 ;;
 esac
 
-# Mips and HP-UX need the GNU assembler.
+# Mips, LoongArch and HP-UX need the GNU assembler.
 # Linux on IA64 might be able to use the Intel assembler.
 
 case "$target" in
-  mips*-*-* | *-*-hpux* )
+  mips*-*-* | loongarch*-*-* | *-*-hpux* )
 if test x$gas_flag = xyes \
|| test x"$host" != x"$build" \
|| test ! -x "$gcc_cv_as" \
@@ -29384,8 +29438,8 @@ esac
 # ??? Once 2.11 is released, probably need to add first known working
 # version to the per-target configury.
 case "$cpu_type" in
-  aarch64 | alpha | arc | arm | avr | bfin | cris | csky | i386 | m32c | m68k \
-  | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc \
+  aarch64 | alpha | arc | arm | avr | bfin | cris | csky | i386 | loongarch | 
m32c \
+  | m68k | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | 
sparc \
   | tilegx | tilepro | visium | xstormy16 | xtensa)
 insn="nop"
 ;;
-- 
2.31.1



[PATCH v10 07/12] LoongArch Port: Builtin macros.

2022-03-24 Thread chenglulu
gcc/

* config/loongarch/loongarch-c.cc
---
 gcc/config/loongarch/loongarch-c.cc | 109 
 1 file changed, 109 insertions(+)
 create mode 100644 gcc/config/loongarch/loongarch-c.cc

diff --git a/gcc/config/loongarch/loongarch-c.cc 
b/gcc/config/loongarch/loongarch-c.cc
new file mode 100644
index 000..d6e3e19f049
--- /dev/null
+++ b/gcc/config/loongarch/loongarch-c.cc
@@ -0,0 +1,109 @@
+/* LoongArch-specific code for C family languages.
+   Copyright (C) 2021-2022 Free Software Foundation, Inc.
+   Contributed by Loongson Ltd.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "c-family/c-common.h"
+#include "cpplib.h"
+
+#define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM)
+#define builtin_define(TXT) cpp_define (pfile, TXT)
+#define builtin_assert(TXT) cpp_assert (pfile, TXT)
+
+/* Define preprocessor macros for the -march and -mtune options.
+   PREFIX is either _LOONGARCH_ARCH or _LOONGARCH_TUNE, INFO is
+   the selected processor.  If INFO's canonical name is "foo",
+   define PREFIX to be "foo", and define an additional macro
+   PREFIX_FOO.  */
+#define LARCH_CPP_SET_PROCESSOR(PREFIX, CPU_TYPE)  \
+  do   \
+{  \
+  char *macro, *p; \
+  int cpu_type = (CPU_TYPE);   \
+   \
+  macro = concat ((PREFIX), "_",   \
+ loongarch_cpu_strings[cpu_type], NULL);   \
+  for (p = macro; *p != 0; p++)\
+   *p = TOUPPER (*p);  \
+   \
+  builtin_define (macro);  \
+  builtin_define_with_value ((PREFIX), \
+loongarch_cpu_strings[cpu_type], 1);   \
+  free (macro);\
+}  \
+  while (0)
+
+void
+loongarch_cpu_cpp_builtins (cpp_reader *pfile)
+{
+  builtin_assert ("machine=loongarch");
+  builtin_assert ("cpu=loongarch");
+  builtin_define ("__loongarch__");
+
+  LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_ARCH", LARCH_ACTUAL_ARCH);
+  LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_TUNE", LARCH_ACTUAL_TUNE);
+
+  /* Base architecture / ABI.  */
+  if (TARGET_64BIT)
+{
+  builtin_define ("__loongarch_grlen=64");
+  builtin_define ("__loongarch64");
+}
+
+  if (TARGET_ABI_LP64)
+{
+  builtin_define ("_ABILP64=3");
+  builtin_define ("_LOONGARCH_SIM=_ABILP64");
+  builtin_define ("__loongarch_lp64");
+}
+
+  /* These defines reflect the ABI in use, not whether the
+ FPU is directly accessible.  */
+  if (TARGET_DOUBLE_FLOAT_ABI)
+builtin_define ("__loongarch_double_float=1");
+  else if (TARGET_SINGLE_FLOAT_ABI)
+builtin_define ("__loongarch_single_float=1");
+
+  if (TARGET_DOUBLE_FLOAT_ABI || TARGET_SINGLE_FLOAT_ABI)
+builtin_define ("__loongarch_hard_float=1");
+  else
+builtin_define ("__loongarch_soft_float=1");
+
+
+  /* ISA Extensions.  */
+  if (TARGET_DOUBLE_FLOAT)
+builtin_define ("__loongarch_frlen=64");
+  else if (TARGET_SINGLE_FLOAT)
+builtin_define ("__loongarch_frlen=32");
+  else
+builtin_define ("__loongarch_frlen=0");
+
+  /* Native Data Sizes.  */
+  builtin_define_with_int_value ("_LOONGARCH_SZINT", INT_TYPE_SIZE);
+  builtin_define_with_int_value ("_LOONGARCH_SZLONG", LONG_TYPE_SIZE);
+  builtin_define_with_int_value ("_LOONGARCH_SZPTR", POINTER_SIZE);
+  builtin_define_with_int_value ("_LOONGARCH_FPSET", 32);
+  builtin_define_with_int_value ("_LOONGARCH_SPFPSET", 32);
+
+}
-- 
2.31.1



[PATCH v10 09/12] LoongArch Port: Regenerate libgcc/configure.

2022-03-24 Thread chenglulu
libgcc/
* configure: Regenerate file.
---
 libgcc/configure | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libgcc/configure b/libgcc/configure
index 52bf25d4e94..1f9b2ac578b 100755
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -2403,6 +2403,9 @@ case "${host}" in
# sets the default TLS model and affects inlining.
PICFLAG=-fPIC
;;
+loongarch*-*-*)
+   PICFLAG=-fpic
+   ;;
 mips-sgi-irix6*)
# PIC is the default.
;;
@@ -5073,7 +5076,7 @@ $as_echo "$libgcc_cv_cfi" >&6; }
 # word size rather than the address size.
 cat > conftest.c <

[PATCH v10 02/12] LoongArch Port: gcc build

2022-03-24 Thread chenglulu
gcc/

* common/config/loongarch/loongarch-common.cc: New file.
* config/loongarch/genopts/genstr.sh: New file.
* config/loongarch/genopts/loongarch-strings: New file.
* config/loongarch/genopts/loongarch.opt.in: New file.
* config/loongarch/loongarch-str.h: New file.
* config/loongarch/gnu-user.h: New file.
* config/loongarch/linux.h: New file.
* config/loongarch/loongarch-cpu.cc: New file.
* config/loongarch/loongarch-cpu.h: New file.
* config/loongarch/loongarch-def.c: New file.
* config/loongarch/loongarch-def.h: New file.
* config/loongarch/loongarch-driver.cc: New file.
* config/loongarch/loongarch-driver.h: New file.
* config/loongarch/loongarch-opts.cc: New file.
* config/loongarch/loongarch-opts.h: New file.
* config/loongarch/loongarch.opt: New file.
* config/loongarch/t-linux: New file.
* config/loongarch/t-loongarch: New file.
* config.gcc: Add LoongArch support.
* configure.ac: Add LoongArch support.

contrib/
* gcc_update (files_and_dependencies): Add
  config/loongarch/loongarch.opt and config/loongarch/loongarch-str.h.
---
 contrib/gcc_update|   2 +
 .../config/loongarch/loongarch-common.cc  |  43 ++
 gcc/config.gcc| 435 -
 gcc/config/loongarch/genopts/genstr.sh| 104 
 .../loongarch/genopts/loongarch-strings   |  58 ++
 gcc/config/loongarch/genopts/loongarch.opt.in | 179 ++
 gcc/config/loongarch/gnu-user.h   |  80 +++
 gcc/config/loongarch/linux.h  |  50 ++
 gcc/config/loongarch/loongarch-cpu.cc | 206 +++
 gcc/config/loongarch/loongarch-cpu.h  |  30 +
 gcc/config/loongarch/loongarch-def.c  | 179 ++
 gcc/config/loongarch/loongarch-def.h  | 151 +
 gcc/config/loongarch/loongarch-driver.cc  | 187 ++
 gcc/config/loongarch/loongarch-driver.h   |  69 +++
 gcc/config/loongarch/loongarch-opts.cc| 578 ++
 gcc/config/loongarch/loongarch-opts.h |  90 +++
 gcc/config/loongarch/loongarch-str.h  |  59 ++
 gcc/config/loongarch/loongarch.opt| 186 ++
 gcc/config/loongarch/t-linux  |  53 ++
 gcc/config/loongarch/t-loongarch  |  72 +++
 gcc/configure.ac  |  33 +-
 21 files changed, 2839 insertions(+), 5 deletions(-)
 create mode 100644 gcc/common/config/loongarch/loongarch-common.cc
 create mode 100755 gcc/config/loongarch/genopts/genstr.sh
 create mode 100644 gcc/config/loongarch/genopts/loongarch-strings
 create mode 100644 gcc/config/loongarch/genopts/loongarch.opt.in
 create mode 100644 gcc/config/loongarch/gnu-user.h
 create mode 100644 gcc/config/loongarch/linux.h
 create mode 100644 gcc/config/loongarch/loongarch-cpu.cc
 create mode 100644 gcc/config/loongarch/loongarch-cpu.h
 create mode 100644 gcc/config/loongarch/loongarch-def.c
 create mode 100644 gcc/config/loongarch/loongarch-def.h
 create mode 100644 gcc/config/loongarch/loongarch-driver.cc
 create mode 100644 gcc/config/loongarch/loongarch-driver.h
 create mode 100644 gcc/config/loongarch/loongarch-opts.cc
 create mode 100644 gcc/config/loongarch/loongarch-opts.h
 create mode 100644 gcc/config/loongarch/loongarch-str.h
 create mode 100644 gcc/config/loongarch/loongarch.opt
 create mode 100644 gcc/config/loongarch/t-linux
 create mode 100644 gcc/config/loongarch/t-loongarch

diff --git a/contrib/gcc_update b/contrib/gcc_update
index 1cf15f9b3c2..641ce164775 100755
--- a/contrib/gcc_update
+++ b/contrib/gcc_update
@@ -86,6 +86,8 @@ gcc/config/arm/arm-tables.opt: gcc/config/arm/arm-cpus.in 
gcc/config/arm/parsecp
 gcc/config/c6x/c6x-tables.opt: gcc/config/c6x/c6x-isas.def 
gcc/config/c6x/genopt.sh
 gcc/config/c6x/c6x-sched.md: gcc/config/c6x/c6x-sched.md.in 
gcc/config/c6x/gensched.sh
 gcc/config/c6x/c6x-mult.md: gcc/config/c6x/c6x-mult.md.in 
gcc/config/c6x/genmult.sh
+gcc/config/loongarch/loongarch-str.h: gcc/config/loongarch/genopts/genstr.sh 
gcc/config/loongarch/genopts/loongarch-string
+gcc/config/loongarch/loongarch.opt: gcc/config/loongarch/genopts/genstr.sh 
gcc/config/loongarch/genopts/loongarch.opt.in
 gcc/config/m68k/m68k-tables.opt: gcc/config/m68k/m68k-devices.def 
gcc/config/m68k/m68k-isas.def gcc/config/m68k/m68k-microarchs.def 
gcc/config/m68k/genopt.sh
 gcc/config/mips/mips-tables.opt: gcc/config/mips/mips-cpus.def 
gcc/config/mips/genopt.sh
 gcc/config/rs6000/rs6000-tables.opt: gcc/config/rs6000/rs6000-cpus.def 
gcc/config/rs6000/genopt.sh
diff --git a/gcc/common/config/loongarch/loongarch-common.cc 
b/gcc/common/config/loongarch/loongarch-common.cc
new file mode 100644
index 000..085d3d98f1c
--- /dev/null
+++ b/gcc/common/config/loongarch/loongarch-common.cc
@@ -0,0 +1,43 @@
+/* Common hooks for LoongArch.
+   Copyright (C) 2021-2022 Free Software Foundation, Inc

[PATCH v10 11/12] LoongArch Port: gcc/testsuite

2022-03-24 Thread chenglulu
gcc/testsuite/

* g++.dg/cpp0x/constexpr-rom.C: Add build options for LoongArch.
* g++.old-deja/g++.abi/ptrmem.C: Add LoongArch support.
* g++.old-deja/g++.pt/ptrmem6.C: xfail for LoongArch.
* gcc.dg/20020312-2.c: Add LoongArch support.
* c-c++-common/zero-scratch-regs-10.c: Like wise
* c-c++-common/zero-scratch-regs-11.c: Like wise
* c-c++-common/zero-scratch-regs-8.c: Like wise
* c-c++-common/zero-scratch-regs-9.c: Like wise
* gcc.dg/loop-8.c: Skip on LoongArch.
* gcc.dg/torture/stackalign/builtin-apply-2.c: Likewise.
* gcc.dg/tree-ssa/ssa-fre-3.c: Likewise.
* go.test/go-test.exp: Define the LoongArch target.
* lib/target-supports.exp: Like wise.
* gcc.target/loongarch/loongarch.exp: New file.
* gcc.target/loongarch/tst-asm-const.c: Like wise.
* gcc.target/loongarch/larch-builtin.c: Like wise.
---
 .../c-c++-common/zero-scratch-regs-10.c   |   2 +-
 .../c-c++-common/zero-scratch-regs-11.c   |   2 +-
 .../c-c++-common/zero-scratch-regs-8.c|   2 +-
 .../c-c++-common/zero-scratch-regs-9.c|   2 +-
 gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C|   2 +-
 gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C   |   2 +-
 gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C   |   2 +-
 gcc/testsuite/gcc.dg/20020312-2.c |   2 +
 gcc/testsuite/gcc.dg/loop-8.c |   2 +-
 .../torture/stackalign/builtin-apply-2.c  |   2 +-
 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c |   2 +-
 .../gcc.target/loongarch/larch-builtin.c  | 265 ++
 .../gcc.target/loongarch/loongarch.exp|  40 +++
 .../gcc.target/loongarch/tst-asm-const.c  |  16 ++
 gcc/testsuite/go.test/go-test.exp |   3 +
 gcc/testsuite/lib/target-supports.exp |  10 +
 16 files changed, 346 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/larch-builtin.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/loongarch.exp
 create mode 100644 gcc/testsuite/gcc.target/loongarch/tst-asm-const.c

diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c 
b/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c
index 96e0b79b328..a89de4850a6 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* nvptx*-*-* s390*-*-* } } } */
+/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* nvptx*-*-* s390*-*-* loongarch64*-*-* } } } */
 /* { dg-options "-O2" } */
 
 #include 
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c 
b/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
index 0714f95a04f..b7739b2c6f6 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* } } } */
+/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* loongarch64*-*-* } } } */
 /* { dg-options "-O2 -fzero-call-used-regs=all" } */
 
 #include "zero-scratch-regs-10.c"
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c 
b/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c
index aceda7e5cb8..067b2c67778 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* } } } */
+/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* loongarch64*-*-* } } } */
 /* { dg-options "-O2 -fzero-call-used-regs=all-arg" } */
 
 #include "zero-scratch-regs-1.c"
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c 
b/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
index f3152a7a732..ea83bc146b7 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* } } } */
+/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* loongarch64*-*-* } } } */
 /* { dg-options "-O2 -fzero-call-used-regs=all" } */
 
 #include "zero-scratch-regs-1.c"
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C 
b/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C
index 2e0ef685f36..424979a604b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C
@@ -1,6 +1,6 @@
 // PR c++/49673: check that test_data goes 

[PATCH v10 06/12] LoongArch Port: Builtin functions.

2022-03-24 Thread chenglulu
gcc/

* config/loongarch/larchintrin.h: New file.
* config/loongarch/loongarch-builtins.cc: New file.
---
 gcc/config/loongarch/larchintrin.h | 355 +
 gcc/config/loongarch/loongarch-builtins.cc | 424 +
 2 files changed, 779 insertions(+)
 create mode 100644 gcc/config/loongarch/larchintrin.h
 create mode 100644 gcc/config/loongarch/loongarch-builtins.cc

diff --git a/gcc/config/loongarch/larchintrin.h 
b/gcc/config/loongarch/larchintrin.h
new file mode 100644
index 000..2833f148709
--- /dev/null
+++ b/gcc/config/loongarch/larchintrin.h
@@ -0,0 +1,355 @@
+/* Intrinsics for LoongArch BASE operations.
+   Copyright (C) 2021-2022 Free Software Foundation, Inc.
+   Contributed by Loongson Ltd.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published
+by the Free Software Foundation; either version 3, or (at your
+option) any later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+.  */
+
+#ifndef _GCC_LOONGARCH_BASE_INTRIN_H
+#define _GCC_LOONGARCH_BASE_INTRIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct drdtime
+{
+  unsigned long dvalue;
+  unsigned long dtimeid;
+} __drdtime_t;
+
+typedef struct rdtime
+{
+  unsigned int value;
+  unsigned int timeid;
+} __rdtime_t;
+
+#ifdef __loongarch64
+extern __inline __drdtime_t
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__rdtime_d (void)
+{
+  __drdtime_t __drdtime;
+  __asm__ volatile (
+"rdtime.d\t%[val],%[tid]\n\t"
+: [val]"=&r"(__drdtime.dvalue),[tid]"=&r"(__drdtime.dtimeid)
+:);
+  return __drdtime;
+}
+#endif
+
+extern __inline __rdtime_t
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__rdtimeh_w (void)
+{
+  __rdtime_t __rdtime;
+  __asm__ volatile (
+"rdtimeh.w\t%[val],%[tid]\n\t"
+: [val]"=&r"(__rdtime.value),[tid]"=&r"(__rdtime.timeid)
+:);
+  return __rdtime;
+}
+
+extern __inline __rdtime_t
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__rdtimel_w (void)
+{
+  __rdtime_t __rdtime;
+  __asm__ volatile (
+"rdtimel.w\t%[val],%[tid]\n\t"
+: [val]"=&r"(__rdtime.value),[tid]"=&r"(__rdtime.timeid)
+:);
+  return __rdtime;
+}
+
+/* Assembly instruction format:rj, fcsr.  */
+/* Data types in instruction templates:  USI, UQI.  */
+#define __movfcsr2gr(/*ui5*/ _1) __builtin_loongarch_movfcsr2gr ((_1));
+
+/* Assembly instruction format:fcsr, rj.  */
+/* Data types in instruction templates:  VOID, UQI, USI.  */
+#define __movgr2fcsr(/*ui5*/ _1, _2) \
+  __builtin_loongarch_movgr2fcsr ((_1), (unsigned int) _2);
+
+#if defined __loongarch64
+/* Assembly instruction format:ui5, rj, si12.  */
+/* Data types in instruction templates:  VOID, USI, UDI, SI.  */
+#define __cacop_d(/*ui5*/ _1, /*unsigned long int*/ _2, /*si12*/ _3) \
+  ((void) __builtin_loongarch_cacop_d ((_1), (unsigned long int) (_2), (_3)))
+#else
+#error "Unsupported ABI."
+#endif
+
+/* Assembly instruction format:rd, rj.  */
+/* Data types in instruction templates:  USI, USI.  */
+extern __inline unsigned int
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__cpucfg (unsigned int _1)
+{
+  return (unsigned int) __builtin_loongarch_cpucfg ((unsigned int) _1);
+}
+
+#ifdef __loongarch64
+/* Assembly instruction format:rj, rk.  */
+/* Data types in instruction templates:  DI, DI.  */
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__asrtle_d (long int _1, long int _2)
+{
+  __builtin_loongarch_asrtle_d ((long int) _1, (long int) _2);
+}
+
+/* Assembly instruction format:rj, rk.  */
+/* Data types in instruction templates:  DI, DI.  */
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__asrtgt_d (long int _1, long int _2)
+{
+  __builtin_loongarch_asrtgt_d ((long int) _1, (long int) _2);
+}
+#endif
+
+#if defined __loongarch64
+/* Assembly instruction format:rd, rj, ui5.  */
+/* Data types in instruction templates:  DI, DI, UQI.  */
+#define __lddir_d(/*long int*/ _1, /*ui5*/ _2) \
+  ((long int) __builtin_loongarch_lddir_d ((long int) (_1), (_2)))
+#else
+#error "Unsupported ABI."
+#endif
+
+#if defined __loongarch64
+/* Assembly instruction forma

[PATCH v10 08/12] LoongArch Port: libgcc

2022-03-24 Thread chenglulu
libgcc/

* config/loongarch/crtfastmath.c: New file.
* config/loongarch/linux-unwind.h: Like wise.
* config/loongarch/sfp-machine.h: Like wise.
* config/loongarch/t-crtstuff: Like wise.
* config/loongarch/t-loongarch: Like wise.
* config/loongarch/t-loongarch64: Like wise.
* config/loongarch/t-softfp-tf: Like wise.
* config.host: Add LoongArch tuples.
* configure.ac: Add LoongArch support.
---
 libgcc/config.host |  28 -
 libgcc/config/loongarch/crtfastmath.c  |  52 +
 libgcc/config/loongarch/linux-unwind.h |  80 +
 libgcc/config/loongarch/sfp-machine.h  | 152 +
 libgcc/config/loongarch/t-crtstuff |   5 +
 libgcc/config/loongarch/t-loongarch|   7 ++
 libgcc/config/loongarch/t-loongarch64  |   1 +
 libgcc/config/loongarch/t-softfp-tf|   3 +
 libgcc/configure.ac|   2 +-
 9 files changed, 328 insertions(+), 2 deletions(-)
 create mode 100644 libgcc/config/loongarch/crtfastmath.c
 create mode 100644 libgcc/config/loongarch/linux-unwind.h
 create mode 100644 libgcc/config/loongarch/sfp-machine.h
 create mode 100644 libgcc/config/loongarch/t-crtstuff
 create mode 100644 libgcc/config/loongarch/t-loongarch
 create mode 100644 libgcc/config/loongarch/t-loongarch64
 create mode 100644 libgcc/config/loongarch/t-softfp-tf

diff --git a/libgcc/config.host b/libgcc/config.host
index 094fd3ad254..8c56fcae5d2 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -138,6 +138,22 @@ hppa*-*-*)
 lm32*-*-*)
cpu_type=lm32
;;
+loongarch*-*-*)
+   cpu_type=loongarch
+   tmake_file="loongarch/t-loongarch"
+   if test "${libgcc_cv_loongarch_hard_float}" = yes; then
+   tmake_file="${tmake_file} t-hardfp-sfdf t-hardfp"
+   else
+   tmake_file="${tmake_file} t-softfp-sfdf"
+   fi
+   if test "${ac_cv_sizeof_long_double}" = 16; then
+   tmake_file="${tmake_file} loongarch/t-softfp-tf"
+   fi
+   if test "${host_address}" = 64; then
+   tmake_file="${tmake_file} loongarch/t-loongarch64"
+   fi
+   tmake_file="${tmake_file} t-softfp"
+   ;;
 m32r*-*-*)
 cpu_type=m32r
 ;;
@@ -925,7 +941,17 @@ lm32-*-rtems*)
 lm32-*-uclinux*)
 extra_parts="$extra_parts crtbegin.o crtendS.o crtbeginT.o"
 tmake_file="lm32/t-lm32 lm32/t-uclinux t-libgcc-pic t-softfp-sfdf 
t-softfp"
-   ;;  
+   ;;
+loongarch*-*-linux*)
+   extra_parts="$extra_parts crtfastmath.o"
+   tmake_file="${tmake_file} t-crtfm loongarch/t-crtstuff"
+   case ${host} in
+ *)
+   tmake_file="${tmake_file} t-slibgcc-libgcc"
+   ;;
+   esac
+   md_unwind_header=loongarch/linux-unwind.h
+   ;;
 m32r-*-elf*)
tmake_file="$tmake_file m32r/t-m32r t-fdpbit"
extra_parts="$extra_parts crtinit.o crtfini.o"
diff --git a/libgcc/config/loongarch/crtfastmath.c 
b/libgcc/config/loongarch/crtfastmath.c
new file mode 100644
index 000..52b0d6da087
--- /dev/null
+++ b/libgcc/config/loongarch/crtfastmath.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2021-2022 Free Software Foundation, Inc.
+   Contributed by Loongson Ltd.
+   Based on MIPS target for GNU compiler.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License
+and a copy of the GCC Runtime Library Exception along with this
+program; see the files COPYING3 and COPYING.RUNTIME respectively.
+If not, see .  */
+
+#ifdef __loongarch_hard_float
+
+/* Rounding control.  */
+#define _FPU_RC_NEAREST 0x000 /* RECOMMENDED.  */
+#define _FPU_RC_ZERO0x100
+#define _FPU_RC_UP  0x200
+#define _FPU_RC_DOWN0x300
+
+/* Enable interrupts for IEEE exceptions.  */
+#define _FPU_IEEE 0x001F
+
+/* Macros for accessing the hardware control word.  */
+#define _FPU_GETCW(cw) __asm__ volatile ("movfcsr2gr %0,$r0" : "=r" (cw))
+#define _FPU_SETCW(cw) __asm__ volatile ("movgr2fcsr $r0,%0" : : "r" (cw))
+
+static void __attribute__((constructor))
+set_fast_math (void)
+{
+  unsigned int fcr;
+
+  /* Flush to zero, round to nearest, IEEE exceptions disabled.  */
+  fcr = _FPU_RC_NEAREST;
+
+  _FPU_SETCW (fcr);
+}
+
+#endif /* __loongarch_hard_float  */
diff --git a/libgcc

[PATCH v10 12/12] LoongArch Port: Add doc.

2022-03-24 Thread chenglulu
* contrib/config-list.mk: Add LoongArch triplet.
* gcc/doc/install.texi: Add LoongArch options section.
* gcc/doc/invoke.texi: Add LoongArch options section.
* gcc/doc/md.texi: Add LoongArch options section.
---
 contrib/config-list.mk |   4 +-
 gcc/doc/install.texi   |  47 --
 gcc/doc/invoke.texi| 200 +
 gcc/doc/md.texi|  26 ++
 4 files changed, 271 insertions(+), 6 deletions(-)

diff --git a/contrib/config-list.mk b/contrib/config-list.mk
index 3e1d1321861..e042105561a 100644
--- a/contrib/config-list.mk
+++ b/contrib/config-list.mk
@@ -57,7 +57,9 @@ LIST = aarch64-elf aarch64-linux-gnu aarch64-rtems \
   i686-wrs-vxworksae \
   i686-cygwinOPT-enable-threads=yes i686-mingw32crt ia64-elf \
   ia64-freebsd6 ia64-linux ia64-hpux ia64-hp-vms iq2000-elf lm32-elf \
-  lm32-rtems lm32-uclinux m32c-rtems m32c-elf m32r-elf m32rle-elf \
+  lm32-rtems lm32-uclinux \
+  loongarch64-linux-gnuf64 loongarch64-linux-gnuf32 loongarch64-linux-gnusf \
+  m32c-rtems m32c-elf m32r-elf m32rle-elf \
   m68k-elf m68k-netbsdelf \
   m68k-uclinux m68k-linux m68k-rtems \
   mcore-elf microblaze-linux microblaze-elf \
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 7258f9def6c..ab67a639836 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -747,9 +747,9 @@ Here are the possible CPU types:
 @quotation
 aarch64, aarch64_be, alpha, alpha64, amdgcn, arc, arceb, arm, armeb, avr, bfin,
 bpf, cr16, cris, csky, epiphany, fido, fr30, frv, ft32, h8300, hppa, hppa2.0,
-hppa64, i486, i686, ia64, iq2000, lm32, m32c, m32r, m32rle, m68k, mcore,
-microblaze, microblazeel, mips, mips64, mips64el, mips64octeon, mips64orion,
-mips64vr, mipsel, mipsisa32, mipsisa32r2, mipsisa64, mipsisa64r2,
+hppa64, i486, i686, ia64, iq2000, lm32, loongarch64, m32c, m32r, m32rle, m68k,
+mcore, microblaze, microblazeel, mips, mips64, mips64el, mips64octeon,
+mips64orion, mips64vr, mipsel, mipsisa32, mipsisa32r2, mipsisa64, mipsisa64r2,
 mipsisa64r2el, mipsisa64sb1, mipsisa64sr71k, mipstx39, mmix, mn10300, moxie,
 msp430, nds32be, nds32le, nios2, nvptx, or1k, pdp11, powerpc, powerpc64,
 powerpc64le, powerpcle, pru, riscv32, riscv32be, riscv64, riscv64be, rl78, rx,
@@ -1166,8 +1166,9 @@ sysv, aix.
 @itemx --without-multilib-list
 Specify what multilibs to build.  @var{list} is a comma separated list of
 values, possibly consisting of a single value.  Currently only implemented
-for aarch64*-*-*, arm*-*-*, riscv*-*-*, sh*-*-* and x86-64-*-linux*.  The
-accepted values and meaning for each target is given below.
+for aarch64*-*-*, arm*-*-*, loongarch64-*-*, riscv*-*-*, sh*-*-* and
+x86-64-*-linux*.  The accepted values and meaning for each target is given
+below.
 
 @table @code
 @item aarch64*-*-*
@@ -1254,6 +1255,14 @@ profile.  The union of these options is considered when 
specifying both
 @code{-mfloat-abi=hard}
 @end multitable
 
+@item loongarch*-*-*
+@var{list} is a comma-separated list of the following ABI identifiers:
+@code{lp64d[/base]} @code{lp64f[/base]} @code{lp64d[/base]}, where the
+@code{/base} suffix may be omitted, to enable their respective run-time
+libraries.  If @var{list} is empty or @code{default},
+or if @option{--with-multilib-list} is not specified, then the default ABI
+as specified by @option{--with-abi} or implied by @option{--target} is 
selected.
+
 @item riscv*-*-*
 @var{list} is a single ABI name.  The target architecture must be either
 @code{rv32gc} or @code{rv64gc}.  This will build a single multilib for the
@@ -4439,6 +4448,34 @@ This configuration is intended for embedded systems.
 Lattice Mico32 processor.
 This configuration is intended for embedded systems running uClinux.
 
+@html
+
+@end html
+@anchor{loongarch}
+@heading LoongArch
+LoongArch processor.
+The following LoongArch targets are available:
+@table @code
+@item loongarch64-linux-gnu*
+LoongArch processor running GNU/Linux.  This target triplet may be coupled
+with a small set of possible suffixes to identify their default ABI type:
+@table @code
+@item f64
+Uses @code{lp64d/base} ABI by default.
+@item f32
+Uses @code{lp64f/base} ABI by default.
+@item sf
+Uses @code{lp64s/base} ABI by default.
+@end table
+
+@item loongarch64-linux-gnu
+Same as @code{loongarch64-linux-gnuf64}, but may be used with
+@option{--with-abi=*} to configure the default ABI type.
+@end table
+
+More information about LoongArch can be found at
+@uref{https://github.com/loongson/LoongArch-Documentation}.
+
 @html
 
 @end html
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4da4a1170f5..78b380e262f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -995,6 +995,16 @@ Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-mbarrel-shift-enabled  -mdivide-enabled  -mmultiply-enabled @gol
 -msign-extend-enabled  -muser-enabled}
 
+@emph{LoongArch Options}
+@gccoptlist{-march=@var{cpu-type}  -mtune=@var{cpu-type} 
-mabi=@var{base-abi-type} @gol
+-mfpu=@va

Re: [PATCH v10 10/12] LoongArch Port: libgomp

2022-03-24 Thread Jakub Jelinek via Gcc-patches
On Thu, Mar 24, 2022 at 08:37:32PM +0800, chenglulu wrote:
> libgomp/
> 
> * configure.tgt: Add LoongArch triplet.

Ok.

> diff --git a/libgomp/configure.tgt b/libgomp/configure.tgt
> index d4f1e741b5a..2cd7272fcd8 100644
> --- a/libgomp/configure.tgt
> +++ b/libgomp/configure.tgt
> @@ -56,6 +56,10 @@ if test x$enable_linux_futex = xyes; then
>   config_path="linux/ia64 linux posix"
>   ;;
>  
> +loongarch*-*-linux*)
> + config_path="linux posix"
> + ;;
> +
>  mips*-*-linux*)
>   config_path="linux/mips linux posix"
>   ;;
> -- 
> 2.31.1

Jakub



Re: [PATCH v10 10/12] LoongArch Port: libgomp

2022-03-24 Thread 程璐璐

Hi, Jakub:

 Thanks for your review.

在 2022/3/24 下午8:41, Jakub Jelinek 写道:

On Thu, Mar 24, 2022 at 08:37:32PM +0800, chenglulu wrote:

libgomp/

 * configure.tgt: Add LoongArch triplet.

Ok.


diff --git a/libgomp/configure.tgt b/libgomp/configure.tgt
index d4f1e741b5a..2cd7272fcd8 100644
--- a/libgomp/configure.tgt
+++ b/libgomp/configure.tgt
@@ -56,6 +56,10 @@ if test x$enable_linux_futex = xyes; then
config_path="linux/ia64 linux posix"
;;
  
+loongarch*-*-linux*)

+   config_path="linux posix"
+   ;;
+
  mips*-*-linux*)
config_path="linux/mips linux posix"
;;
--
2.31.1

Jakub




Fix another Rust demangling bugs (PR 105039)

2022-03-24 Thread Nick Clifton via Gcc-patches

Hi Guys,

  Attached is a proposed patch to fix another Rust demangling bug
  reported in PR 105039.  I would like to say that this is the
  last time that we will see this problem for the Rust demangler,
  but I am not that naive...

  OK to apply ?

Cheers
  Nickdiff --git a/libiberty/rust-demangle.c b/libiberty/rust-demangle.c
index 3b24d63892a..d601182ac50 100644
--- a/libiberty/rust-demangle.c
+++ b/libiberty/rust-demangle.c
@@ -126,7 +126,7 @@ parse_integer_62 (struct rust_demangler *rdm)
 return 0;
 
   x = 0;
-  while (!eat (rdm, '_'))
+  while (!eat (rdm, '_') && !rdm->errored)
 {
   c = next (rdm);
   x *= 62;
@@ -1148,6 +1148,15 @@ demangle_const (struct rust_demangler *rdm)
   if (rdm->errored)
 return;
 
+  if (rdm->recursion != RUST_NO_RECURSION_LIMIT)
+{
+  ++ rdm->recursion;
+  if (rdm->recursion > RUST_MAX_RECURSION_COUNT)
+	/* FIXME: There ought to be a way to report
+	   that the recursion limit has been reached.  */
+	goto fail_return;
+}
+  
   if (eat (rdm, 'B'))
 {
   backref = parse_integer_62 (rdm);
@@ -1158,7 +1167,7 @@ demangle_const (struct rust_demangler *rdm)
   demangle_const (rdm);
   rdm->next = old_next;
 }
-  return;
+  goto pass_return;
 }
 
   ty_tag = next (rdm);
@@ -1167,7 +1176,7 @@ demangle_const (struct rust_demangler *rdm)
 /* Placeholder. */
 case 'p':
   PRINT ("_");
-  return;
+  goto pass_return;
 
 /* Unsigned integer types. */
 case 'h':
@@ -1200,18 +1209,20 @@ demangle_const (struct rust_demangler *rdm)
   break;
 
 default:
-  rdm->errored = 1;
-  return;
+  goto fail_return;
 }
 
-  if (rdm->errored)
-return;
-
-  if (rdm->verbose)
+  if (!rdm->errored && rdm->verbose)
 {
   PRINT (": ");
   PRINT (basic_type (ty_tag));
 }
+
+ fail_return:
+  rdm->errored = 1;
+ pass_return:
+  if (rdm->recursion != RUST_NO_RECURSION_LIMIT)
+-- rdm->recursion;
 }
 
 static void


Re: [PATCH] configure: cache result of "sys/sdt.h" header check

2022-03-24 Thread David Seifert via Gcc-patches
On Mon, 2022-03-14 at 18:38 +0100, David Seifert wrote:
> Use AC_CACHE_CHECK to store the result of the header check for
> systemtap's "sys/sdt.h", which is similar in spirit to libstdc++'s
> AC_CACHE_CHECK(..., glibcxx_cv_sys_sdt_h).
> 
> gcc/
>     * configure.ac: Add AC_CACHE_CHECK(..., gcc_cv_sys_sdt_h).
>     * configure: Regenerate.
> ---
>  gcc/configure    | 20 +++-
>  gcc/configure.ac | 16 +---
>  2 files changed, 24 insertions(+), 12 deletions(-)
> 
> diff --git a/gcc/configure b/gcc/configure
> index 14b19c8fe0c..1dfc5cc7344 100755
> --- a/gcc/configure
> +++ b/gcc/configure
> @@ -31389,15 +31389,25 @@ fi
>  
>  { $as_echo "$as_me:${as_lineno-$LINENO}: checking sys/sdt.h in the
> target C library" >&5
>  $as_echo_n "checking sys/sdt.h in the target C library... " >&6; }
> -have_sys_sdt_h=no
> -if test -f $target_header_dir/sys/sdt.h; then
> -  have_sys_sdt_h=yes
> +if ${gcc_cv_sys_sdt_h+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +
> +  gcc_cv_sys_sdt_h=no
> +  if test -f $target_header_dir/sys/sdt.h; then
> +    gcc_cv_sys_sdt_h=yes
> +  fi
> +
> +fi
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_sys_sdt_h"
> >&5
> +$as_echo "$gcc_cv_sys_sdt_h" >&6; }
> +if test x$gcc_cv_sys_sdt_h = xyes; then :
> +
>  
>  $as_echo "#define HAVE_SYS_SDT_H 1" >>confdefs.h
>  
> +
>  fi
> -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_sys_sdt_h" >&5
> -$as_echo "$have_sys_sdt_h" >&6; }
>  
>  # Check if TFmode long double should be used by default or not.
>  # Some glibc targets used DFmode long double, but with glibc 2.4
> diff --git a/gcc/configure.ac b/gcc/configure.ac
> index 90cad309762..c86ce5e0a9b 100644
> --- a/gcc/configure.ac
> +++ b/gcc/configure.ac
> @@ -6904,14 +6904,16 @@ AC_SUBST([enable_default_ssp])
>  
>  # Test for  on the target.
>  GCC_TARGET_TEMPLATE([HAVE_SYS_SDT_H])
> -AC_MSG_CHECKING(sys/sdt.h in the target C library)
> -have_sys_sdt_h=no
> -if test -f $target_header_dir/sys/sdt.h; then
> -  have_sys_sdt_h=yes
> -  AC_DEFINE(HAVE_SYS_SDT_H, 1,
> +AC_CACHE_CHECK([sys/sdt.h in the target C library],
> [gcc_cv_sys_sdt_h], [
> +  gcc_cv_sys_sdt_h=no
> +  if test -f $target_header_dir/sys/sdt.h; then
> +    gcc_cv_sys_sdt_h=yes
> +  fi
> +])
> +AS_IF([test x$gcc_cv_sys_sdt_h = xyes], [
> +  AC_DEFINE([HAVE_SYS_SDT_H], [1],
>  [Define if your target C library provides sys/sdt.h])
> -fi
> -AC_MSG_RESULT($have_sys_sdt_h)
> +])
>  
>  # Check if TFmode long double should be used by default or not.
>  # Some glibc targets used DFmode long double, but with glibc 2.4

Ping, I think we agreed making this a cache variable is fine (which is
how libstdc++ also does it).



Re: [PATCH] c++: FIX_TRUNC_EXPR in tsubst [PR102990]

2022-03-24 Thread Jason Merrill via Gcc-patches

On 3/23/22 19:26, Marek Polacek wrote:

On Wed, Mar 23, 2022 at 04:35:32PM -0400, Jason Merrill wrote:

On 3/22/22 19:55, Marek Polacek wrote:

This is a crash where a FIX_TRUNC_EXPR gets into tsubst_copy_and_build
where it hits gcc_unreachable ().

The history of tsubst_copy_and_build/FIX_TRUNC_EXPR is such that it
was introduced in r181478, but it did the wrong thing, whereupon it
was turned into gcc_unreachable () in r258821 (see this thread:
).

In a template, we should never create a FIX_TRUNC_EXPR (that's what
conv_unsafe_in_template_p is for).  But in this test we are NOT in
a template when we call digest_nsdmi_init which ends up calling
convert_like, converting 1.0e+0 to int, so convert_to_integer_1
gives us a FIX_TRUNC_EXPR.

But then when we get to parsing f's parameters, we are in a template
when processing decltype(Helpers{}), and since r268321, when the
compound literal isn't instantiation-dependent and the type isn't
type-dependent, finish_compound_literal falls back to the normal
processing, so it calls digest_init, which does fold_non_dependent_init
and since the FIX_TRUNC_EXPR isn't dependent, we instantiate and
therefore crash in tsubst_copy_and_build.


Hmm, we shouldn't be doing fold_non_dependent_init on the result of
get_nsdmi.  Why does that happen?


OK, so we have decltype(Helpers{}), finish_compound_literal gets
Helpers{}, it's not type-dependent, so:

- call digest_init (type=Helpers, init={})
   init is BRACE_ENCLOSED_INITIALIZER_P, type is !TYPE_NON_AGGREGATE_CLASS
   so go down to...
- process_init_constructor_record (type=Helpers, init={})
- we walk the fields of Helpers, there's 'inputs' of type knob_t
  type_build_ctor_call (knob_t) is true, we want to default-init this
  field
- create a {} as the init for default-initialization
- call massage_init_elt (type=knob_t, init={}) to adjust the init
  - we do so by calling digest_init_r (type=knob_t, init={})
- here we again call process_init_constructor_record, walk knob_t's
  fields, see the field 'value', it has a DECL_INITIAL, so call
 get_nsdmi, that returns the FIX_TRUNC_EXPR we've created before
- so digesting {} for knob_t produced
  init = {.value=(int) NON_LVALUE_EXPR <1.0e+0>}
  - then we call fold_non_dependent_init on this init, and die


Maybe we shouldn't call fold_non_dependent_init on a CONSTRUCTOR here, 
since presumably we already called it on elements that needed it in the 
recursive digest_init_r.



Do we have a mechanism to avoid folding get_nsdmi's trees that I've missed?
  

Either I can tweak p_c_e to say that a FIX_TRUNC_EXPR in a template
is not potentially constant, or I can just remove the whole F_T_E
case, since:
a) we could not have created an IMPLICIT_CONV_EXPR here, and
b) similar code, FLOAT_EXPR, is not handled here, either.

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

PR c++/102990

gcc/cp/ChangeLog:

* pt.cc (tsubst_copy_and_build) : Remove.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/nsdmi-template22.C: New test.
* g++.dg/cpp0x/nsdmi-template23.C: New test.
---
   gcc/cp/pt.cc  |  4 
   gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C | 13 +
   gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C | 13 +
   3 files changed, 26 insertions(+), 4 deletions(-)
   create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C
   create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 715eea27577..a3becc19290 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -20184,10 +20184,6 @@ tsubst_copy_and_build (tree t,
templated_operator_saved_lookups (t),
complain|decltype_flag));
-case FIX_TRUNC_EXPR:
-  /* convert_like should have created an IMPLICIT_CONV_EXPR.  */
-  gcc_unreachable ();
-
   case ADDR_EXPR:
 op1 = TREE_OPERAND (t, 0);
 if (TREE_CODE (op1) == LABEL_DECL)
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C 
b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C
new file mode 100644
index 000..4ed2501035c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C
@@ -0,0 +1,13 @@
+// PR c++/102990
+// { dg-do compile { target c++11 } }
+
+struct knob_t {
+  /* Let's create a FIX_TRUNC_EXPR.  */
+  int value = 1.0;
+};
+
+struct Helpers {
+  knob_t inputs;
+};
+
+template void f(decltype(Helpers{}));
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C 
b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C
new file mode 100644
index 000..240cab4347a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C
@@ -0,0 +1,13 @@
+// PR c++/102990
+// { dg-do compile { target c++11 } }
+
+struct knob_t {
+  /* Let's create a FLOAT_EXPR.  */
+  double value = 1UL;
+};
+
+struct Helpers

[PATCH] c++: missing SFINAE for consteval calls [PR104620]

2022-03-24 Thread Patrick Palka via Gcc-patches
Here we weren't respecting SFINAE when evaluating a substituted call to
a consteval function, which caused us to reject the new testcase below.
This patch fixes this by making build_over_call use the SFINAE-friendly
version of cxx_constant_value.

This change causes us to no longer diagnose ahead of time a couple of
invalid non-dependent consteval calls in consteval-if2.C (with
-fchecking=2).  These errors were apparently coming from the call to
fold_non_dependent_expr in build_non_dependent_expr (for the RHS of the +=)
despite complain=tf_none being passed.  Now that build_over_call
respects the value of complain during constant evaluation of a consteval
call, the errors are gone.

That the errors don't occur without -fchecking=2 is a regression caused
by r12-7264-gc19f317a78c0e4 and is the subject of PR104620.  As described
in comment #5, I think it was only an accident that we were diagnosing
these two calls correctly before r12-7264, so perhaps we can live
without them in GCC 12.  To that end this patch just XFAILs the two tests.

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

PR c++/104620

gcc/cp/ChangeLog:

* call.cc (build_over_call): Use cxx_constant_value_sfinae
instead of cxx_constant_value to evaluate a consteval call.
* constexpr.cc (cxx_constant_value_sfinae): Add decl parameter
and pass it to cxx_eval_outermost_constant_expr.
* cp-tree.h (cxx_constant_value_sfinae): Add decl parameter.
* pt.cc (fold_targs_r): Pass NULL_TREE as decl to
cxx_constant_value_sfinae.

gcc/testsuite/ChangeLog:

* g++.dg/cpp23/consteval-if2.C: XFAIL two dg-error tests where
the argument to the non-dependent consteval call is wrapped in
NON_DEPENDENT_EXPR.
* g++.dg/cpp2a/consteval30.C: New test.
---
 gcc/cp/call.cc |  2 +-
 gcc/cp/constexpr.cc|  4 ++--
 gcc/cp/cp-tree.h   |  2 +-
 gcc/cp/pt.cc   |  2 +-
 gcc/testsuite/g++.dg/cpp23/consteval-if2.C |  4 ++--
 gcc/testsuite/g++.dg/cpp2a/consteval30.C   | 12 
 6 files changed, 19 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/consteval30.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 23d3fc496b8..ec6c5d5baa2 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -9939,7 +9939,7 @@ build_over_call (struct z_candidate *cand, int flags, 
tsubst_flags_t complain)
obj_arg = TREE_OPERAND (addr, 0);
}
}
- call = cxx_constant_value (call, obj_arg);
+ call = cxx_constant_value_sfinae (call, obj_arg, complain);
  if (obj_arg && !error_operand_p (call))
call = build2 (INIT_EXPR, void_type_node, obj_arg, call);
  call = convert_from_reference (call);
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index a3136ce819d..2163a328e74 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -7959,10 +7959,10 @@ cxx_constant_value (tree t, tree decl)
 /* As above, but respect SFINAE.  */
 
 tree
-cxx_constant_value_sfinae (tree t, tsubst_flags_t complain)
+cxx_constant_value_sfinae (tree t, tree decl, tsubst_flags_t complain)
 {
   bool sfinae = !(complain & tf_error);
-  tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, true);
+  tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, true, false, 
decl);
   if (sfinae && !TREE_CONSTANT (r))
 r = error_mark_node;
   return r;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1bd7bc6fca2..2f718852ac1 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8414,7 +8414,7 @@ extern bool require_constant_expression (tree);
 extern bool require_rvalue_constant_expression (tree);
 extern bool require_potential_rvalue_constant_expression (tree);
 extern tree cxx_constant_value (tree, tree = NULL_TREE);
-extern tree cxx_constant_value_sfinae  (tree, tsubst_flags_t);
+extern tree cxx_constant_value_sfinae  (tree, tree, tsubst_flags_t);
 extern void cxx_constant_dtor  (tree, tree);
 extern tree cxx_constant_init  (tree, tree = NULL_TREE);
 extern tree maybe_constant_value   (tree, tree = NULL_TREE, bool = 
false);
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 715eea27577..173bc3a8c7f 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -19811,7 +19811,7 @@ fold_targs_r (tree targs, tsubst_flags_t complain)
   && !glvalue_p (elt)
   && !TREE_CONSTANT (elt))
{
- elt = cxx_constant_value_sfinae (elt, complain);
+ elt = cxx_constant_value_sfinae (elt, NULL_TREE, complain);
  if (elt == error_mark_node)
return false;
}
diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if2.C 
b/gcc/testsuite/g++.dg/cpp23/consteval-if2.C
index f7053b91c3c..d1845da9e58 100644
--- a/gcc/testsuite/g++.dg/cpp23/consteval-if2.C
+++ 

Re: [PATCH] c++: missing SFINAE for consteval calls [PR104620]

2022-03-24 Thread Jason Merrill via Gcc-patches

On 3/24/22 10:32, Patrick Palka wrote:

Here we weren't respecting SFINAE when evaluating a substituted call to
a consteval function, which caused us to reject the new testcase below.
This patch fixes this by making build_over_call use the SFINAE-friendly
version of cxx_constant_value.

This change causes us to no longer diagnose ahead of time a couple of
invalid non-dependent consteval calls in consteval-if2.C (with
-fchecking=2).  These errors were apparently coming from the call to
fold_non_dependent_expr in build_non_dependent_expr (for the RHS of the +=)
despite complain=tf_none being passed.  Now that build_over_call
respects the value of complain during constant evaluation of a consteval
call, the errors are gone.

That the errors don't occur without -fchecking=2 is a regression caused
by r12-7264-gc19f317a78c0e4 and is the subject of PR104620.  As described
in comment #5, I think it was only an accident that we were diagnosing
these two calls correctly before r12-7264, so perhaps we can live
without them in GCC 12.  To that end this patch just XFAILs the two tests.

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


OK.


PR c++/104620

gcc/cp/ChangeLog:

* call.cc (build_over_call): Use cxx_constant_value_sfinae
instead of cxx_constant_value to evaluate a consteval call.
* constexpr.cc (cxx_constant_value_sfinae): Add decl parameter
and pass it to cxx_eval_outermost_constant_expr.
* cp-tree.h (cxx_constant_value_sfinae): Add decl parameter.
* pt.cc (fold_targs_r): Pass NULL_TREE as decl to
cxx_constant_value_sfinae.

gcc/testsuite/ChangeLog:

* g++.dg/cpp23/consteval-if2.C: XFAIL two dg-error tests where
the argument to the non-dependent consteval call is wrapped in
NON_DEPENDENT_EXPR.
* g++.dg/cpp2a/consteval30.C: New test.
---
  gcc/cp/call.cc |  2 +-
  gcc/cp/constexpr.cc|  4 ++--
  gcc/cp/cp-tree.h   |  2 +-
  gcc/cp/pt.cc   |  2 +-
  gcc/testsuite/g++.dg/cpp23/consteval-if2.C |  4 ++--
  gcc/testsuite/g++.dg/cpp2a/consteval30.C   | 12 
  6 files changed, 19 insertions(+), 7 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/consteval30.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 23d3fc496b8..ec6c5d5baa2 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -9939,7 +9939,7 @@ build_over_call (struct z_candidate *cand, int flags, 
tsubst_flags_t complain)
obj_arg = TREE_OPERAND (addr, 0);
}
}
- call = cxx_constant_value (call, obj_arg);
+ call = cxx_constant_value_sfinae (call, obj_arg, complain);
  if (obj_arg && !error_operand_p (call))
call = build2 (INIT_EXPR, void_type_node, obj_arg, call);
  call = convert_from_reference (call);
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index a3136ce819d..2163a328e74 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -7959,10 +7959,10 @@ cxx_constant_value (tree t, tree decl)
  /* As above, but respect SFINAE.  */
  
  tree

-cxx_constant_value_sfinae (tree t, tsubst_flags_t complain)
+cxx_constant_value_sfinae (tree t, tree decl, tsubst_flags_t complain)
  {
bool sfinae = !(complain & tf_error);
-  tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, true);
+  tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, true, false, 
decl);
if (sfinae && !TREE_CONSTANT (r))
  r = error_mark_node;
return r;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1bd7bc6fca2..2f718852ac1 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8414,7 +8414,7 @@ extern bool require_constant_expression (tree);
  extern bool require_rvalue_constant_expression (tree);
  extern bool require_potential_rvalue_constant_expression (tree);
  extern tree cxx_constant_value(tree, tree = 
NULL_TREE);
-extern tree cxx_constant_value_sfinae  (tree, tsubst_flags_t);
+extern tree cxx_constant_value_sfinae  (tree, tree, tsubst_flags_t);
  extern void cxx_constant_dtor (tree, tree);
  extern tree cxx_constant_init (tree, tree = NULL_TREE);
  extern tree maybe_constant_value  (tree, tree = NULL_TREE, bool = 
false);
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 715eea27577..173bc3a8c7f 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -19811,7 +19811,7 @@ fold_targs_r (tree targs, tsubst_flags_t complain)
   && !glvalue_p (elt)
   && !TREE_CONSTANT (elt))
{
- elt = cxx_constant_value_sfinae (elt, complain);
+ elt = cxx_constant_value_sfinae (elt, NULL_TREE, complain);
  if (elt == error_mark_node)
return false;
}
diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if2.C 
b/gcc/testsuite/g++.dg/cpp23/consteval-if2.C
index f7053b91c

Re: [PATCH v2] c++: ICE with template code in constexpr [PR104284]

2022-03-24 Thread Jason Merrill via Gcc-patches

On 3/18/22 17:55, Marek Polacek wrote:

On Fri, Mar 11, 2022 at 06:46:42PM -0500, Jason Merrill wrote:

On 3/10/22 18:04, Marek Polacek wrote:

Since r9-6073 cxx_eval_store_expression preevaluates the value to
be stored, and that revealed a crash where a template code (here,
code=IMPLICIT_CONV_EXPR) leaks into cxx_eval*.

It happens because we're performing build_vec_init while processing
a template


Hmm, that seems like the bug.  Where's that call coming from?


 From build_aggr_init.  So we're handling e.g.

   template
   constexpr void g () {
 constexpr S s2[]{{'a'}};
   }

cp_finish_decl (decl=s2, init={{'a'}}) sees we're in processing_template_decl,
but also that we have a constexpr var which is not dependent, nor is its
initializer:

   else if (init
&& (init_const_expr_p || DECL_DECLARED_CONSTEXPR_P (decl))
&& !TYPE_REF_P (type)
&& decl_maybe_constant_var_p (decl)
&& !(dep_init = value_dependent_init_p (init)))
 {
   /* This variable seems to be a non-dependent constant, so process
  its initializer.  If check_initializer returns non-null the
  initialization wasn't constant after all.  */
   tree init_code;
   cleanups = make_tree_vector ();
   init_code = check_initializer (decl, init, flags, &cleanups);

so we call check_initializer, where we go down this path:

   init_code = build_aggr_init_full_exprs (decl, init, flags);

build_aggr_init sees that the type of 's2' is ARRAY_TYPE, so it calls
build_vec_init.

I now recall that we've discussed build_vec_init in a template in the
past, for example in the context of c++/93676.  So I agree we ought to
make an effort to avoid calling build_vec_init in a template.  Perhaps
like this: use an INIT_EXPR.  With that, we should call build_vec_init
if needed while instantiating.  Does that make any sense?


Hmm.  If we do that, then we get back to


  if (TREE_CODE (init_code) == INIT_EXPR)


in check_initializer, and pull out the same init again, and set 
LOOKUP_ALREADY_DIGESTED.  But I think that's wrong, we haven't digested 
it yet.


Maybe we could avoid entering the below block of check_initializer at 
all in this situation?



  if (((type_build_ctor_call (type) || CLASS_TYPE_P (type))
   && !(flags & LOOKUP_ALREADY_DIGESTED)
   && !(init && BRACE_ENCLOSED_INITIALIZER_P (init)
&& CP_AGGREGATE_TYPE_P (type)
&& (CLASS_TYPE_P (type)


Maybe by adding || processing_template_decl here?


|| !TYPE_NEEDS_CONSTRUCTING (type)
|| type_has_extended_temps (type
  || (DECL_DECOMPOSITION_P (decl) && TREE_CODE (type) == ARRAY_TYPE))


Jason



[PATCH] c, c++: alignas and alignof void [PR104944]

2022-03-24 Thread Marek Polacek via Gcc-patches
I started looking into this PR because in GCC 4.9 we were able to
detect the invalid

  struct alignas(void) S{};

but I broke it in r210262.

It's ill-formed code in C++:
[dcl.align]/3: "An alignment-specifier of the form alignas(type-id) has
the same effect as alignas(alignof(type-id))", and [expr.align]/1:
"The operand shall be a type-id representing a complete object type,
or an array thereof, or a reference to one of those types." and void
is not a complete type.

It's also invalid in C:
6.7.5: _Alignas(type-name) is equivalent to _Alignas(_Alignof(type-name))
6.5.3.4: "The _Alignof operator shall not be applied to a function type
or an incomplete type."

We have a GNU extension whereby we treat sizeof(void) as 1, but I assume
it doesn't apply to alignof, so I'd like to reject it in C too.

(We still say "invalid application of '__alignof__'" rather than
'alignas' but I felt that fixing that may not be suitable as part of this
patch.)

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

PR c++/104944

gcc/c-family/ChangeLog:

* c-common.cc (c_sizeof_or_alignof_type): Do not allow alignof(void).

gcc/cp/ChangeLog:

* typeck.cc (cxx_alignas_expr): Call cxx_sizeof_or_alignof_type with
complain == true.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/alignas20.C: New test.
* gcc.dg/c11-align-10.c: New test.
---
 gcc/c-family/c-common.cc   | 20 +++-
 gcc/cp/typeck.cc   | 14 --
 gcc/testsuite/g++.dg/cpp0x/alignas20.C | 24 
 gcc/testsuite/gcc.dg/c11-align-10.c| 18 ++
 4 files changed, 65 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alignas20.C
 create mode 100644 gcc/testsuite/gcc.dg/c11-align-10.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index d034837bb5b..8b76eba64c2 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -3849,7 +3849,7 @@ c_common_get_alias_set (tree t)
the IS_SIZEOF parameter indicates which operator is being applied.
The COMPLAIN flag controls whether we should diagnose possibly
ill-formed constructs or not.  LOC is the location of the SIZEOF or
-   TYPEOF operator.  If MIN_ALIGNOF, the least alignment required for
+   ALIGNOF operator.  If MIN_ALIGNOF, the least alignment required for
a type in any context should be returned, rather than the normal
alignment for that type.  */
 
@@ -3891,10 +3891,20 @@ c_sizeof_or_alignof_type (location_t loc,
 }
   else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
 {
-  if (type_code == VOID_TYPE
- && complain && warn_pointer_arith)
-   pedwarn (loc, OPT_Wpointer_arith,
-"invalid application of %qs to a void type", op_name);
+  if (type_code == VOID_TYPE && complain)
+   {
+ /* sizeof(void) is a GNU extension.  */
+ if (is_sizeof)
+   pedwarn (loc, OPT_Wpointer_arith,
+"invalid application of %qs to a void type", op_name);
+ /* But alignof(void) is not.  */
+ else
+   {
+ error_at (loc, "invalid application of %qs to a void type",
+   op_name);
+ return error_mark_node;
+   }
+   }
   else if (!complain)
 return error_mark_node;
   value = size_one_node;
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 516fa574ef6..96653c4f96e 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -1873,9 +1873,9 @@ compparms (const_tree parms1, const_tree parms2)
 }
 
 
-/* Process a sizeof or alignof expression where the operand is a
-   type. STD_ALIGNOF indicates whether an alignof has C++11 (minimum alignment)
-   or GNU (preferred alignment) semantics; it is ignored if op is
+/* Process a sizeof or alignof expression where the operand is a type.
+   STD_ALIGNOF indicates whether an alignof has C++11 (minimum alignment)
+   or GNU (preferred alignment) semantics; it is ignored if OP is
SIZEOF_EXPR.  */
 
 tree
@@ -2132,11 +2132,13 @@ cxx_alignas_expr (tree e)
 /* [dcl.align]/3:

   When the alignment-specifier is of the form
-  alignas(type-id ), it shall have the same effect as
-  alignas(alignof(type-id )).  */
+  alignas(type-id), it shall have the same effect as
+  alignas(alignof(type-id)).  */
 
 return cxx_sizeof_or_alignof_type (input_location,
-  e, ALIGNOF_EXPR, true, false);
+  e, ALIGNOF_EXPR,
+  /*std_alignof=*/true,
+  /*complain=*/true);
   
   /* If we reach this point, it means the alignas expression if of
  the form "alignas(assignment-expression)", so we should follow
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas20.C 
b/gcc/testsuite/g++.dg/cpp0x/alignas20.C
new file mode 100644
index 0

Re: [PATCH] c, c++: alignas and alignof void [PR104944]

2022-03-24 Thread Jason Merrill via Gcc-patches

On 3/24/22 11:49, Marek Polacek wrote:

I started looking into this PR because in GCC 4.9 we were able to
detect the invalid

   struct alignas(void) S{};

but I broke it in r210262.

It's ill-formed code in C++:
[dcl.align]/3: "An alignment-specifier of the form alignas(type-id) has
the same effect as alignas(alignof(type-id))", and [expr.align]/1:
"The operand shall be a type-id representing a complete object type,
or an array thereof, or a reference to one of those types." and void
is not a complete type.

It's also invalid in C:
6.7.5: _Alignas(type-name) is equivalent to _Alignas(_Alignof(type-name))
6.5.3.4: "The _Alignof operator shall not be applied to a function type
or an incomplete type."

We have a GNU extension whereby we treat sizeof(void) as 1, but I assume
it doesn't apply to alignof, so I'd like to reject it in C too.


That makes sense to me in principle, but we've allowed it since the 
beginning of version control, back when c_alignof was a separate 
function.  Changing that seems questionable for a regression fix.



(We still say "invalid application of '__alignof__'" rather than
'alignas' but I felt that fixing that may not be suitable as part of this
patch.)

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

PR c++/104944

gcc/c-family/ChangeLog:

* c-common.cc (c_sizeof_or_alignof_type): Do not allow alignof(void).

gcc/cp/ChangeLog:

* typeck.cc (cxx_alignas_expr): Call cxx_sizeof_or_alignof_type with
complain == true.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/alignas20.C: New test.
* gcc.dg/c11-align-10.c: New test.
---
  gcc/c-family/c-common.cc   | 20 +++-
  gcc/cp/typeck.cc   | 14 --
  gcc/testsuite/g++.dg/cpp0x/alignas20.C | 24 
  gcc/testsuite/gcc.dg/c11-align-10.c| 18 ++
  4 files changed, 65 insertions(+), 11 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/alignas20.C
  create mode 100644 gcc/testsuite/gcc.dg/c11-align-10.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index d034837bb5b..8b76eba64c2 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -3849,7 +3849,7 @@ c_common_get_alias_set (tree t)
 the IS_SIZEOF parameter indicates which operator is being applied.
 The COMPLAIN flag controls whether we should diagnose possibly
 ill-formed constructs or not.  LOC is the location of the SIZEOF or
-   TYPEOF operator.  If MIN_ALIGNOF, the least alignment required for
+   ALIGNOF operator.  If MIN_ALIGNOF, the least alignment required for
 a type in any context should be returned, rather than the normal
 alignment for that type.  */
  
@@ -3891,10 +3891,20 @@ c_sizeof_or_alignof_type (location_t loc,

  }
else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
  {
-  if (type_code == VOID_TYPE
- && complain && warn_pointer_arith)
-   pedwarn (loc, OPT_Wpointer_arith,
-"invalid application of %qs to a void type", op_name);
+  if (type_code == VOID_TYPE && complain)
+   {
+ /* sizeof(void) is a GNU extension.  */
+ if (is_sizeof)
+   pedwarn (loc, OPT_Wpointer_arith,
+"invalid application of %qs to a void type", op_name);
+ /* But alignof(void) is not.  */
+ else
+   {
+ error_at (loc, "invalid application of %qs to a void type",
+   op_name);
+ return error_mark_node;
+   }
+   }
else if (!complain)
  return error_mark_node;
value = size_one_node;
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 516fa574ef6..96653c4f96e 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -1873,9 +1873,9 @@ compparms (const_tree parms1, const_tree parms2)
  }
  
  

-/* Process a sizeof or alignof expression where the operand is a
-   type. STD_ALIGNOF indicates whether an alignof has C++11 (minimum alignment)
-   or GNU (preferred alignment) semantics; it is ignored if op is
+/* Process a sizeof or alignof expression where the operand is a type.
+   STD_ALIGNOF indicates whether an alignof has C++11 (minimum alignment)
+   or GNU (preferred alignment) semantics; it is ignored if OP is
 SIZEOF_EXPR.  */
  
  tree

@@ -2132,11 +2132,13 @@ cxx_alignas_expr (tree e)
  /* [dcl.align]/3:
 
  	   When the alignment-specifier is of the form

-  alignas(type-id ), it shall have the same effect as
-  alignas(alignof(type-id )).  */
+  alignas(type-id), it shall have the same effect as
+  alignas(alignof(type-id)).  */
  
  return cxx_sizeof_or_alignof_type (input_location,

-  e, ALIGNOF_EXPR, true, false);
+  e, ALIGNOF_EXPR,
+  /*std_alignof=*/true,
+  /*complain=

Re: [PATCH] Add condition coverage profiling

2022-03-24 Thread Martin Liška

On 3/21/22 12:55, Jørgen Kvalsvik via Gcc-patches wrote:

Hello.

Thanks for very interesting extension of the existing GCOV profiling.

I briefly read the patch and investigated what happens and I've got various
questions/comments about it:

1) Do I correctly understand that __conditions_accu_true/false track
every short-circuit sub-expression of a condition and record
if a given sub-expr is seen to be true or false?

2) As mentioned these are bit sets, can you please explain why you (& -value)
from these sets?

3) I noticed a false report for a simple test-case:

$ cat cond.c
int x;

void foo (int a, int b)
{
if (a || b)
  x = 1;
else
  x = 2;
}

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

$ rm *gcda ; gcc --coverage cond.c -fprofile-conditions && ./a.out && gcov -g 
-t a-cond.c
-:0:Source:cond.c
-:0:Graph:a-cond.gcno
-:0:Data:a-cond.gcda
-:0:Runs:1
-:1:int x;
-:2:
1:3:void foo (int a, int b)
-:4:{
1:5:if (a || b)
conditions covered 1/4
condition  0 not covered (true)
condition  0 not covered (false) <-- this was executed if I'm correct
condition  1 not covered (false)
1:6:  x = 1;
-:7:else
#:8:  x = 2;
1:9:}
-:   10:
1:   11:int main()
-:   12:{
1:   13:  foo (0, 1);
1:   14:  return 0;
-:   15:}

4) I noticed various CFG patterns in tree-profile.cc which are handled. Can you 
please
explain how the algorithm works even without knowing the original paper?

5) I noticed the following ICE:

$ gcc cond.c -fprofile-conditions -fprofile-generate
during IPA pass: profile
cond.c: In function ‘foo’:
cond.c:15:1: internal compiler error: Segmentation fault
   15 | }
  | ^
0xf4d64a crash_signal
/home/marxin/Programming/gcc/gcc/toplev.cc:322
0x778b93cf ???

/usr/src/debug/glibc-2.35-2.1.x86_64/signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
0x778f29ed __GI__IO_ftell
/usr/src/debug/glibc-2.35-2.1.x86_64/libio/ioftell.c:37
0xa9dfda gcov_position
/home/marxin/Programming/gcc/gcc/gcov-io.cc:48
0xa9dfda gcov_write_tag(unsigned int)
/home/marxin/Programming/gcc/gcc/gcov-io.cc:321
0xe9734a branch_prob(bool)
/home/marxin/Programming/gcc/gcc/profile.cc:1542
0x1032e08 tree_profiling
/home/marxin/Programming/gcc/gcc/tree-profile.cc:1620
0x1032e08 execute
/home/marxin/Programming/gcc/gcc/tree-profile.cc:1726
Please submit a full bug report, with preprocessed source (by using 
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.

6) Please follow the GNU coding style, most notable we replace 8 spaces with a 
tab.
And we break line before {, (, ... Remove noexcept specifiers for functions and 
I think
most of the newly added functions can be static. And each newly added function 
should
have a comment.

7) Please consider supporting of -profile-update=atomic where you'll need to 
utilize
an atomic builts (see how other instrumentation looks like with it).

That's the very first round of the review. Hope it's helpful.

Cheers,
Martin


This patch adds support in gcc+gcov for modified condition/decision
coverage (MC/DC) with the -fprofile-conditions flag. MC/DC is a type of
test/code coverage, and it is particularly important in the avation and
automotive industries for safety-critical applications. In particular,
it is required or recommended by:

 * DO-178C for the most critical software (Level A) in avionics
 * IEC 61508 for SIL 4
 * ISO 26262-6 for ASIL D

 From the SQLite webpage:

 Two methods of measuring test coverage were described above:
 "statement" and "branch" coverage. There are many other test
 coverage metrics besides these two. Another popular metric is
 "Modified Condition/Decision Coverage" or MC/DC. Wikipedia defines
 MC/DC as follows:

 * Each decision tries every possible outcome.
 * Each condition in a decision takes on every possible outcome.
 * Each entry and exit point is invoked.
 * Each condition in a decision is shown to independently affect
   the outcome of the decision.

 In the C programming language where && and || are "short-circuit"
 operators, MC/DC and branch coverage are very nearly the same thing.
 The primary difference is in boolean vector tests. One can test for
 any of several bits in bit-vector and still obtain 100% branch test
 coverage even though the second element of MC/DC - the requirement
 that each condition in a decision take on every possible outcome -
 might not be satisfied.

 https://sqlite.org/testing.html#mcdc

Wahlen, Heimdahl, and De Silva "Efficient Test Coverage Measurement for
MC/DC" describes an algorithm for adding instrumentation by carrying
over information from the AST, but

[PATCH v2] c++: FIX_TRUNC_EXPR in tsubst [PR102990]

2022-03-24 Thread Marek Polacek via Gcc-patches
On Thu, Mar 24, 2022 at 09:32:19AM -0400, Jason Merrill wrote:
> On 3/23/22 19:26, Marek Polacek wrote:
> > On Wed, Mar 23, 2022 at 04:35:32PM -0400, Jason Merrill wrote:
> > > On 3/22/22 19:55, Marek Polacek wrote:
> > > > This is a crash where a FIX_TRUNC_EXPR gets into tsubst_copy_and_build
> > > > where it hits gcc_unreachable ().
> > > > 
> > > > The history of tsubst_copy_and_build/FIX_TRUNC_EXPR is such that it
> > > > was introduced in r181478, but it did the wrong thing, whereupon it
> > > > was turned into gcc_unreachable () in r258821 (see this thread:
> > > > ).
> > > > 
> > > > In a template, we should never create a FIX_TRUNC_EXPR (that's what
> > > > conv_unsafe_in_template_p is for).  But in this test we are NOT in
> > > > a template when we call digest_nsdmi_init which ends up calling
> > > > convert_like, converting 1.0e+0 to int, so convert_to_integer_1
> > > > gives us a FIX_TRUNC_EXPR.
> > > > 
> > > > But then when we get to parsing f's parameters, we are in a template
> > > > when processing decltype(Helpers{}), and since r268321, when the
> > > > compound literal isn't instantiation-dependent and the type isn't
> > > > type-dependent, finish_compound_literal falls back to the normal
> > > > processing, so it calls digest_init, which does fold_non_dependent_init
> > > > and since the FIX_TRUNC_EXPR isn't dependent, we instantiate and
> > > > therefore crash in tsubst_copy_and_build.
> > > 
> > > Hmm, we shouldn't be doing fold_non_dependent_init on the result of
> > > get_nsdmi.  Why does that happen?
> > 
> > OK, so we have decltype(Helpers{}), finish_compound_literal gets
> > Helpers{}, it's not type-dependent, so:
> > 
> > - call digest_init (type=Helpers, init={})
> >init is BRACE_ENCLOSED_INITIALIZER_P, type is !TYPE_NON_AGGREGATE_CLASS
> >so go down to...
> > - process_init_constructor_record (type=Helpers, init={})
> > - we walk the fields of Helpers, there's 'inputs' of type knob_t
> >   type_build_ctor_call (knob_t) is true, we want to default-init this
> >   field
> > - create a {} as the init for default-initialization
> > - call massage_init_elt (type=knob_t, init={}) to adjust the init
> >   - we do so by calling digest_init_r (type=knob_t, init={})
> > - here we again call process_init_constructor_record, walk knob_t's
> >   fields, see the field 'value', it has a DECL_INITIAL, so call
> >  get_nsdmi, that returns the FIX_TRUNC_EXPR we've created before
> > - so digesting {} for knob_t produced
> >   init = {.value=(int) NON_LVALUE_EXPR <1.0e+0>}
> >   - then we call fold_non_dependent_init on this init, and die
> 
> Maybe we shouldn't call fold_non_dependent_init on a CONSTRUCTOR here, since
> presumably we already called it on elements that needed it in the recursive
> digest_init_r.

Ah, that works.  It's still a bit weird that we don't treat FLOAT_EXPR and
FIX_TRUNC_EXPR the same.

I've tried to remove the call to fold_non_dependent_init in massage_init_elt
to see what breaks...a lot.  So it has to stay at least in this form.

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

Thanks,

-- >8 --
This is a crash where a FIX_TRUNC_EXPR gets into tsubst_copy_and_build
where it hits gcc_unreachable ().

The history of tsubst_copy_and_build/FIX_TRUNC_EXPR is such that it
was introduced in r181478, but it did the wrong thing, whereupon it
was turned into gcc_unreachable () in r258821 (see this thread:
).

In a template, we should never create a FIX_TRUNC_EXPR (that's what
conv_unsafe_in_template_p is for).  But in this test we are NOT in
a template when we call digest_nsdmi_init which ends up calling
convert_like, converting 1.0e+0 to int, so convert_to_integer_1
gives us a FIX_TRUNC_EXPR.

But then when we get to parsing f's parameters, we are in a template
when processing decltype(Helpers{}), and since r268321, when the
compound literal isn't instantiation-dependent and the type isn't
type-dependent, finish_compound_literal falls back to the normal
processing, so it calls digest_init, which does fold_non_dependent_init
and since the FIX_TRUNC_EXPR isn't dependent, we instantiate and
therefore crash in tsubst_copy_and_build.

The fateful call to fold_non_dependent_init comes from massage_init_elt,
We shouldn't be calling f_n_d_i on the result of get_nsdmi.  This we can
avoid by eschewing calling f_n_d_i on CONSTRUCTORs; their elements have
already been folded.

PR c++/102990

gcc/cp/ChangeLog:

* typeck2.cc (massage_init_elt): Avoid folding CONSTRUCTORs.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/nsdmi-template22.C: New test.
* g++.dg/cpp0x/nsdmi-template23.C: New test.
---
 gcc/cp/typeck2.cc | 13 +
 gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C | 13 +
 gcc/testsuite/g++.dg/cpp0x

Re: [PATCH v2] c++: FIX_TRUNC_EXPR in tsubst [PR102990]

2022-03-24 Thread Jason Merrill via Gcc-patches

On 3/24/22 13:03, Marek Polacek wrote:

On Thu, Mar 24, 2022 at 09:32:19AM -0400, Jason Merrill wrote:

On 3/23/22 19:26, Marek Polacek wrote:

On Wed, Mar 23, 2022 at 04:35:32PM -0400, Jason Merrill wrote:

On 3/22/22 19:55, Marek Polacek wrote:

This is a crash where a FIX_TRUNC_EXPR gets into tsubst_copy_and_build
where it hits gcc_unreachable ().

The history of tsubst_copy_and_build/FIX_TRUNC_EXPR is such that it
was introduced in r181478, but it did the wrong thing, whereupon it
was turned into gcc_unreachable () in r258821 (see this thread:
).

In a template, we should never create a FIX_TRUNC_EXPR (that's what
conv_unsafe_in_template_p is for).  But in this test we are NOT in
a template when we call digest_nsdmi_init which ends up calling
convert_like, converting 1.0e+0 to int, so convert_to_integer_1
gives us a FIX_TRUNC_EXPR.

But then when we get to parsing f's parameters, we are in a template
when processing decltype(Helpers{}), and since r268321, when the
compound literal isn't instantiation-dependent and the type isn't
type-dependent, finish_compound_literal falls back to the normal
processing, so it calls digest_init, which does fold_non_dependent_init
and since the FIX_TRUNC_EXPR isn't dependent, we instantiate and
therefore crash in tsubst_copy_and_build.


Hmm, we shouldn't be doing fold_non_dependent_init on the result of
get_nsdmi.  Why does that happen?


OK, so we have decltype(Helpers{}), finish_compound_literal gets
Helpers{}, it's not type-dependent, so:

- call digest_init (type=Helpers, init={})
init is BRACE_ENCLOSED_INITIALIZER_P, type is !TYPE_NON_AGGREGATE_CLASS
so go down to...
- process_init_constructor_record (type=Helpers, init={})
 - we walk the fields of Helpers, there's 'inputs' of type knob_t
   type_build_ctor_call (knob_t) is true, we want to default-init this
   field
 - create a {} as the init for default-initialization
 - call massage_init_elt (type=knob_t, init={}) to adjust the init
   - we do so by calling digest_init_r (type=knob_t, init={})
 - here we again call process_init_constructor_record, walk knob_t's
   fields, see the field 'value', it has a DECL_INITIAL, so call
 get_nsdmi, that returns the FIX_TRUNC_EXPR we've created before
 - so digesting {} for knob_t produced
   init = {.value=(int) NON_LVALUE_EXPR <1.0e+0>}
   - then we call fold_non_dependent_init on this init, and die


Maybe we shouldn't call fold_non_dependent_init on a CONSTRUCTOR here, since
presumably we already called it on elements that needed it in the recursive
digest_init_r.


Ah, that works.  It's still a bit weird that we don't treat FLOAT_EXPR and
FIX_TRUNC_EXPR the same.

I've tried to remove the call to fold_non_dependent_init in massage_init_elt
to see what breaks...a lot.  So it has to stay at least in this form.

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


OK.


Thanks,

-- >8 --
This is a crash where a FIX_TRUNC_EXPR gets into tsubst_copy_and_build
where it hits gcc_unreachable ().

The history of tsubst_copy_and_build/FIX_TRUNC_EXPR is such that it
was introduced in r181478, but it did the wrong thing, whereupon it
was turned into gcc_unreachable () in r258821 (see this thread:
).

In a template, we should never create a FIX_TRUNC_EXPR (that's what
conv_unsafe_in_template_p is for).  But in this test we are NOT in
a template when we call digest_nsdmi_init which ends up calling
convert_like, converting 1.0e+0 to int, so convert_to_integer_1
gives us a FIX_TRUNC_EXPR.

But then when we get to parsing f's parameters, we are in a template
when processing decltype(Helpers{}), and since r268321, when the
compound literal isn't instantiation-dependent and the type isn't
type-dependent, finish_compound_literal falls back to the normal
processing, so it calls digest_init, which does fold_non_dependent_init
and since the FIX_TRUNC_EXPR isn't dependent, we instantiate and
therefore crash in tsubst_copy_and_build.

The fateful call to fold_non_dependent_init comes from massage_init_elt,
We shouldn't be calling f_n_d_i on the result of get_nsdmi.  This we can
avoid by eschewing calling f_n_d_i on CONSTRUCTORs; their elements have
already been folded.

PR c++/102990

gcc/cp/ChangeLog:

* typeck2.cc (massage_init_elt): Avoid folding CONSTRUCTORs.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/nsdmi-template22.C: New test.
* g++.dg/cpp0x/nsdmi-template23.C: New test.
---
  gcc/cp/typeck2.cc | 13 +
  gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C | 13 +
  gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C | 13 +
  3 files changed, 35 insertions(+), 4 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdm

Re: [aarch64] Update Neoverse N2 core definition

2022-03-24 Thread Andre Vieira (lists) via Gcc-patches

Ping.

On 16/03/2022 15:00, Andre Vieira (lists) via Gcc-patches wrote:

Hi,

As requested, I updated the Neoverse N2 entry to use the 
AARCH64_FL_FOR_ARCH9 feature set, removed duplicate entries, updated 
the ARCH_INDENT to 9A and moved it under the Armv9 cores.


gcc/ChangeLog:

    * config/aarch64/aarch64-cores.def: Update Neoverse N2 core 
entry.


[pushed] c++: delayed parse DMI [PR96645]

2022-03-24 Thread Jason Merrill via Gcc-patches
With the changes for PR81359 and PR88368 to make get_nsdmi errors be treated
as substitution failure, we have the problem that if we check
std::is_default_constructible for a complete class that still has unparsed
default member initializers, we get an answer (false) that will be wrong
once the DMIs have been parsed.  The traits avoid this problem for regular
incomplete classes by giving an error if the operand is incomplete; we
should do the same if get_nsdmi is going to fail due to unparsed DMI.

Tested x86_64-pc-linux-gnu, applying to trunk.

PR c++/96645

gcc/cp/ChangeLog:

* cp-tree.h (type_has_default_ctor_to_be_synthesized): Declare.
* class.cc (type_has_default_ctor_to_be_synthesized): New.
(type_has_non_user_provided_default_constructor_1): Support it.
(type_has_non_user_provided_default_constructor): Now a wrapper.
* method.cc (complain_about_unparsed_dmi): New.
(constructible_expr): Call it.

gcc/testsuite/ChangeLog:

* g++.dg/ext/is_constructible3.C: Expect error.
* g++.dg/ext/is_constructible7.C: New test.
---
 gcc/cp/cp-tree.h |  1 +
 gcc/cp/class.cc  | 25 ++---
 gcc/cp/method.cc | 24 +
 gcc/testsuite/g++.dg/ext/is_constructible3.C |  2 +-
 gcc/testsuite/g++.dg/ext/is_constructible7.C | 28 
 5 files changed, 75 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_constructible7.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2f718852ac1..02734a42f1b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6720,6 +6720,7 @@ extern tree in_class_defaulted_default_constructor (tree);
 extern bool user_provided_p(tree);
 extern bool type_has_user_provided_constructor  (tree);
 extern bool type_has_non_user_provided_default_constructor (tree);
+extern bool type_has_default_ctor_to_be_synthesized (tree);
 extern bool vbase_has_user_provided_move_assign (tree);
 extern tree default_init_uninitialized_part (tree);
 extern bool trivial_default_constructor_is_constexpr (tree);
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 40e17140db5..c75b889cb84 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -5415,10 +5415,11 @@ type_has_user_provided_or_explicit_constructor (tree t)
 
 /* Returns true iff class T has a non-user-provided (i.e. implicitly
declared or explicitly defaulted in the class body) default
-   constructor.  */
+   constructor.  If SYNTH, only return true if it hasn't been
+   implicitly defined yet.  */
 
-bool
-type_has_non_user_provided_default_constructor (tree t)
+static bool
+type_has_non_user_provided_default_constructor_1 (tree t, bool synth)
 {
   if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (t))
 return false;
@@ -5431,12 +5432,28 @@ type_has_non_user_provided_default_constructor (tree t)
   if (TREE_CODE (fn) == FUNCTION_DECL
  && default_ctor_p (fn)
  && !user_provided_p (fn))
-   return true;
+   {
+ if (synth)
+   return !DECL_INITIAL (fn);
+ return true;
+   }
 }
 
   return false;
 }
 
+bool
+type_has_non_user_provided_default_constructor (tree t)
+{
+  return type_has_non_user_provided_default_constructor_1 (t, false);
+}
+
+bool
+type_has_default_ctor_to_be_synthesized (tree t)
+{
+  return type_has_non_user_provided_default_constructor_1 (t, true);
+}
+
 /* TYPE is being used as a virtual base, and has a non-trivial move
assignment.  Return true if this is due to there being a user-provided
move assignment in TYPE or one of its subobjects; if there isn't, then
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 903ee666ef3..e0fe2177730 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -2056,6 +2056,28 @@ assignable_expr (tree to, tree from)
   return r;
 }
 
+/* An unparsed default member initializer prevents calling a defaulted default
+   constructor; make checking std::is_constructible ill-formed until the DMI
+   has been parsed, to avoid caching the wrong value.  */
+
+static bool
+complain_about_unparsed_dmi (tree t)
+{
+  if (type_has_default_ctor_to_be_synthesized (t)
+  && TYPE_HAS_COMPLEX_DFLT (t))
+for (tree f = TYPE_FIELDS (t); f; f = DECL_CHAIN (f))
+  if (TREE_CODE (f) == FIELD_DECL
+ && DECL_INITIAL (f)
+ && TREE_CODE (DECL_INITIAL (f)) == DEFERRED_PARSE)
+   {
+ error ("default member initializer for %qD required by %qs before "
+"the end of its enclosing class", f, "std::is_constructible");
+ inform (location_of (f), "defined here");
+ return true;
+   }
+  return false;
+}
+
 /* The predicate condition for a template specialization
is_constructible shall be satisfied if and only if the
following variable definition would be well-formed for some invented
@@ -2070,6 +2092,8 @@ constructible_expr (tree to, tree from)
   cp_unevaluated cp_u

[PATCH v2] c++: alignas and alignof void [PR104944]

2022-03-24 Thread Marek Polacek via Gcc-patches
On Thu, Mar 24, 2022 at 12:02:29PM -0400, Jason Merrill wrote:
> On 3/24/22 11:49, Marek Polacek wrote:
> > I started looking into this PR because in GCC 4.9 we were able to
> > detect the invalid
> > 
> >struct alignas(void) S{};
> > 
> > but I broke it in r210262.
> > 
> > It's ill-formed code in C++:
> > [dcl.align]/3: "An alignment-specifier of the form alignas(type-id) has
> > the same effect as alignas(alignof(type-id))", and [expr.align]/1:
> > "The operand shall be a type-id representing a complete object type,
> > or an array thereof, or a reference to one of those types." and void
> > is not a complete type.
> > 
> > It's also invalid in C:
> > 6.7.5: _Alignas(type-name) is equivalent to _Alignas(_Alignof(type-name))
> > 6.5.3.4: "The _Alignof operator shall not be applied to a function type
> > or an incomplete type."
> > 
> > We have a GNU extension whereby we treat sizeof(void) as 1, but I assume
> > it doesn't apply to alignof, so I'd like to reject it in C too.
> 
> That makes sense to me in principle, but we've allowed it since the
> beginning of version control, back when c_alignof was a separate function.
> Changing that seems questionable for a regression fix.

Ok, that makes sense.  How about rejecting alignof(void) in C++ only
now (where it is a regression), and maybe come back to this in GCC 13 for C?

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

-- >8 --
I started looking into this PR because in GCC 4.9 we were able to
detect the invalid

  struct alignas(void) S{};

but I broke it in r210262.

It's ill-formed code in C++:
[dcl.align]/3: "An alignment-specifier of the form alignas(type-id) has
the same effect as alignas(alignof(type-id))", and [expr.align]/1:
"The operand shall be a type-id representing a complete object type,
or an array thereof, or a reference to one of those types." and void
is not a complete type.

It's also invalid in C:
6.7.5: _Alignas(type-name) is equivalent to _Alignas(_Alignof(type-name))
6.5.3.4: "The _Alignof operator shall not be applied to a function type
or an incomplete type."

We have a GNU extension whereby we treat sizeof(void) as 1, but I assume
it doesn't apply to alignof, so I'd like to reject it in C too, but it's
probably not a good time to do so in stage4.

(We still say "invalid application of '__alignof__'" rather than
'alignas' but I felt that fixing that may not be suitable as part of this
patch.)

PR c++/104944

gcc/c-family/ChangeLog:

* c-common.cc (c_sizeof_or_alignof_type): Do not allow alignof(void)
in C++.

gcc/cp/ChangeLog:

* typeck.cc (cxx_alignas_expr): Call cxx_sizeof_or_alignof_type with
complain == true.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/alignas20.C: New test.
---
 gcc/c-family/c-common.cc   | 20 +++-
 gcc/cp/typeck.cc   | 14 --
 gcc/testsuite/g++.dg/cpp0x/alignas20.C | 24 
 3 files changed, 47 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alignas20.C

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index d034837bb5b..f99717f540b 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -3849,7 +3849,7 @@ c_common_get_alias_set (tree t)
the IS_SIZEOF parameter indicates which operator is being applied.
The COMPLAIN flag controls whether we should diagnose possibly
ill-formed constructs or not.  LOC is the location of the SIZEOF or
-   TYPEOF operator.  If MIN_ALIGNOF, the least alignment required for
+   ALIGNOF operator.  If MIN_ALIGNOF, the least alignment required for
a type in any context should be returned, rather than the normal
alignment for that type.  */
 
@@ -3891,10 +3891,20 @@ c_sizeof_or_alignof_type (location_t loc,
 }
   else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
 {
-  if (type_code == VOID_TYPE
- && complain && warn_pointer_arith)
-   pedwarn (loc, OPT_Wpointer_arith,
-"invalid application of %qs to a void type", op_name);
+  if (type_code == VOID_TYPE && complain)
+   {
+ /* sizeof(void) is a GNU extension.  */
+ if (is_sizeof || !c_dialect_cxx ())
+   pedwarn (loc, OPT_Wpointer_arith,
+"invalid application of %qs to a void type", op_name);
+ /* But alignof(void) is not (in C++).  */
+ else
+   {
+ error_at (loc, "invalid application of %qs to a void type",
+   op_name);
+ return error_mark_node;
+   }
+   }
   else if (!complain)
 return error_mark_node;
   value = size_one_node;
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 516fa574ef6..96653c4f96e 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -1873,9 +1873,9 @@ compparms (const_tree parms1, const_tree parms2)
 }
 
 
-/* Process a sizeof or alignof expression where the operand is a
-   type. STD_

Re: [PATCH] c++: call complete_type after performing auto deduction [PR80351]

2022-03-24 Thread Jason Merrill via Gcc-patches

On 3/23/22 21:01, Pokechu22 via Gcc-patches wrote:

When cp_finish_decl calls cp_apply_type_quals_to_decl on a const auto or
constexpr auto variable, the type might not be complete the first time
(this happened when auto deduces to an initializer_list).
cp_apply_type_quals_to_decl removes the const qualifier if the type is
not complete, which is appropriate for grokdeclarator, on the assumption
that the type will be complete when called by cp_finish_decl.

Tested on x86_64 Ubuntu under WSL1 by bootstrapping and comparing results
from 24d51e749570dcb85bd43d3b528f58ad6141de26 with results from this
change.  As far as I can tell, this fixes Wunused-var-38.C and
Wunused-var-39.C without regressions.
(Wunused-var-37.C passed before this change.)


Thanks!  For future reference, the patch doesn't apply easily because 
gmail wrapped lines; for sending patches via gmail you'll need to use 
attachments.  Or you can use another MUA, or git send-email.  This time 
I fixed the wrapping by hand, but that's a pain (especially since 
there's no "try again" flag to git am).


Also, like other DCO projects, we can't normally accept pseudonymous 
contributions.  But as you say in the PR, this patch is trivial enough 
that I'm content to apply it myself; I want to make some adjustments anyway.


Currently GCC 12 development is in the regression fixes only stage, so 
I'll queue this for GCC 13.


Thanks again,
Jason



Re: [PATCH] c++: Fall through for arrays of T vs T cv [PR104996]

2022-03-24 Thread Jason Merrill via Gcc-patches

On 3/22/22 16:59, Marek Polacek via Gcc-patches wrote:

On Tue, Mar 22, 2022 at 08:39:21PM +, Ed Catmur wrote:

If two arrays do not have the exact same element type including qualification, this could 
be e.g. f(int (&&)[]) vs. f(int const (&)[]), which can still be distinguished 
by the lvalue-rvalue tiebreaker.

By tightening this branch (in accordance with the letter of the Standard) we 
fall through to the next branch, which tests whether they have different 
element type ignoring qualification and returns 0 in that case; thus we only 
actually fall through in the T[...] vs. T cv[...] case, eventually considering 
the lvalue-rvalue tiebreaker at the end of compare_ics.

Add test.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104996


Thanks, the patch looks reasonable.  Can you describe how it's been tested?

You're going to need a ChangeLog entry, something like

* call.c (compare_ics): When comparing list-initialization sequences,
do not return early.


Indeed.  Note that contrib/gcc-git-customization.sh creates a 'git 
gcc-commit-mklog' alias that is useful for generating a ChangeLog skeleton.


Also, you don't seem to have a copyright assignment on file, so please 
add a DCO sign-off; see https://gcc.gnu.org/contribute.html#legal



and an entry for the test, which...


---
  gcc/cp/call.cc  | 7 ++-
  gcc/testsuite/g++.dg/pr104996.C | 5 +
  2 files changed, 7 insertions(+), 5 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/pr104996.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 23d3fc496b822..28589ab3459ea 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -11535,12 +11535,9 @@ compare_ics (conversion *ics1, conversion *ics2)
 P0388R4.)  */
else if (t1->kind == ck_aggr
   && TREE_CODE (t1->type) == ARRAY_TYPE
-  && TREE_CODE (t2->type) == ARRAY_TYPE)
+  && TREE_CODE (t2->type) == ARRAY_TYPE
+  && same_type_p (TREE_TYPE (t1->type), TREE_TYPE (t2->type)))
{
- /* The type of the array elements must be the same.  */
- if (!same_type_p (TREE_TYPE (t1->type), TREE_TYPE (t2->type)))
-   return 0;
-
  tree n1 = nelts_initialized_by_list_init (t1);
  tree n2 = nelts_initialized_by_list_init (t2);
  if (tree_int_cst_lt (n1, n2))
diff --git a/gcc/testsuite/g++.dg/pr104996.C b/gcc/testsuite/g++.dg/pr104996.C
new file mode 100644
index 0..2e7558c7b9c77
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr104996.C


...can you please rename the test to initlist129.C and put it into g++.dg/cpp0x?


@@ -0,0 +1,5 @@


Also please add

// PR c++/104996

in the first line.


+// { dg-do compile { target c++11 } }
+
+template char f(int (&&)[size]);
+template int f(int const (&)[size]);
+static_assert(sizeof(f({1, 2, 3})) == 1, "");



Marek





Re: [PATCH v2] c++: alignas and alignof void [PR104944]

2022-03-24 Thread Jason Merrill via Gcc-patches

On 3/24/22 15:56, Marek Polacek wrote:

On Thu, Mar 24, 2022 at 12:02:29PM -0400, Jason Merrill wrote:

On 3/24/22 11:49, Marek Polacek wrote:

I started looking into this PR because in GCC 4.9 we were able to
detect the invalid

struct alignas(void) S{};

but I broke it in r210262.

It's ill-formed code in C++:
[dcl.align]/3: "An alignment-specifier of the form alignas(type-id) has
the same effect as alignas(alignof(type-id))", and [expr.align]/1:
"The operand shall be a type-id representing a complete object type,
or an array thereof, or a reference to one of those types." and void
is not a complete type.

It's also invalid in C:
6.7.5: _Alignas(type-name) is equivalent to _Alignas(_Alignof(type-name))
6.5.3.4: "The _Alignof operator shall not be applied to a function type
or an incomplete type."

We have a GNU extension whereby we treat sizeof(void) as 1, but I assume
it doesn't apply to alignof, so I'd like to reject it in C too.


That makes sense to me in principle, but we've allowed it since the
beginning of version control, back when c_alignof was a separate function.
Changing that seems questionable for a regression fix.


Ok, that makes sense.  How about rejecting alignof(void) in C++ only
now (where it is a regression), and maybe come back to this in GCC 13 for C?


I'd probably just leave it alone for C and __alignof.


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

-- >8 --
I started looking into this PR because in GCC 4.9 we were able to
detect the invalid

   struct alignas(void) S{};

but I broke it in r210262.

It's ill-formed code in C++:
[dcl.align]/3: "An alignment-specifier of the form alignas(type-id) has
the same effect as alignas(alignof(type-id))", and [expr.align]/1:
"The operand shall be a type-id representing a complete object type,
or an array thereof, or a reference to one of those types." and void
is not a complete type.

It's also invalid in C:
6.7.5: _Alignas(type-name) is equivalent to _Alignas(_Alignof(type-name))
6.5.3.4: "The _Alignof operator shall not be applied to a function type
or an incomplete type."

We have a GNU extension whereby we treat sizeof(void) as 1, but I assume
it doesn't apply to alignof, so I'd like to reject it in C too, but it's
probably not a good time to do so in stage4.

(We still say "invalid application of '__alignof__'" rather than
'alignas' but I felt that fixing that may not be suitable as part of this
patch.)

PR c++/104944

gcc/c-family/ChangeLog:

* c-common.cc (c_sizeof_or_alignof_type): Do not allow alignof(void)
in C++.

gcc/cp/ChangeLog:

* typeck.cc (cxx_alignas_expr): Call cxx_sizeof_or_alignof_type with
complain == true.


This hunk is OK.  But let's put the diagnostic in 
cxx_sizeof_or_alignof_type, where it can depend on std_alignof.



gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/alignas20.C: New test.
---
  gcc/c-family/c-common.cc   | 20 +++-
  gcc/cp/typeck.cc   | 14 --
  gcc/testsuite/g++.dg/cpp0x/alignas20.C | 24 
  3 files changed, 47 insertions(+), 11 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/alignas20.C

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index d034837bb5b..f99717f540b 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -3849,7 +3849,7 @@ c_common_get_alias_set (tree t)
 the IS_SIZEOF parameter indicates which operator is being applied.
 The COMPLAIN flag controls whether we should diagnose possibly
 ill-formed constructs or not.  LOC is the location of the SIZEOF or
-   TYPEOF operator.  If MIN_ALIGNOF, the least alignment required for
+   ALIGNOF operator.  If MIN_ALIGNOF, the least alignment required for
 a type in any context should be returned, rather than the normal
 alignment for that type.  */
  
@@ -3891,10 +3891,20 @@ c_sizeof_or_alignof_type (location_t loc,

  }
else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
  {
-  if (type_code == VOID_TYPE
- && complain && warn_pointer_arith)
-   pedwarn (loc, OPT_Wpointer_arith,
-"invalid application of %qs to a void type", op_name);
+  if (type_code == VOID_TYPE && complain)
+   {
+ /* sizeof(void) is a GNU extension.  */
+ if (is_sizeof || !c_dialect_cxx ())
+   pedwarn (loc, OPT_Wpointer_arith,
+"invalid application of %qs to a void type", op_name);
+ /* But alignof(void) is not (in C++).  */
+ else
+   {
+ error_at (loc, "invalid application of %qs to a void type",
+   op_name);
+ return error_mark_node;
+   }
+   }
else if (!complain)
  return error_mark_node;
value = size_one_node;
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 516fa574ef6..96653c4f96e 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -1873,9 +

[PATCH v3] c++: ICE with template code in constexpr [PR104284]

2022-03-24 Thread Marek Polacek via Gcc-patches
On Thu, Mar 24, 2022 at 11:40:11AM -0400, Jason Merrill wrote:
> On 3/18/22 17:55, Marek Polacek wrote:
> > On Fri, Mar 11, 2022 at 06:46:42PM -0500, Jason Merrill wrote:
> > > On 3/10/22 18:04, Marek Polacek wrote:
> > > > Since r9-6073 cxx_eval_store_expression preevaluates the value to
> > > > be stored, and that revealed a crash where a template code (here,
> > > > code=IMPLICIT_CONV_EXPR) leaks into cxx_eval*.
> > > > 
> > > > It happens because we're performing build_vec_init while processing
> > > > a template
> > > 
> > > Hmm, that seems like the bug.  Where's that call coming from?
> > 
> >  From build_aggr_init.  So we're handling e.g.
> > 
> >template
> >constexpr void g () {
> >  constexpr S s2[]{{'a'}};
> >}
> > 
> > cp_finish_decl (decl=s2, init={{'a'}}) sees we're in 
> > processing_template_decl,
> > but also that we have a constexpr var which is not dependent, nor is its
> > initializer:
> > 
> >else if (init
> > && (init_const_expr_p || DECL_DECLARED_CONSTEXPR_P (decl))
> > && !TYPE_REF_P (type)
> > && decl_maybe_constant_var_p (decl)
> > && !(dep_init = value_dependent_init_p (init)))
> >  {
> >/* This variable seems to be a non-dependent constant, so process
> >   its initializer.  If check_initializer returns non-null the
> >   initialization wasn't constant after all.  */
> >tree init_code;
> >cleanups = make_tree_vector ();
> >init_code = check_initializer (decl, init, flags, &cleanups);
> > 
> > so we call check_initializer, where we go down this path:
> > 
> >init_code = build_aggr_init_full_exprs (decl, init, flags);
> > 
> > build_aggr_init sees that the type of 's2' is ARRAY_TYPE, so it calls
> > build_vec_init.
> > 
> > I now recall that we've discussed build_vec_init in a template in the
> > past, for example in the context of c++/93676.  So I agree we ought to
> > make an effort to avoid calling build_vec_init in a template.  Perhaps
> > like this: use an INIT_EXPR.  With that, we should call build_vec_init
> > if needed while instantiating.  Does that make any sense?
> 
> Hmm.  If we do that, then we get back to
> 
> >   if (TREE_CODE (init_code) == INIT_EXPR)
> 
> in check_initializer, and pull out the same init again, and set
> LOOKUP_ALREADY_DIGESTED.  But I think that's wrong, we haven't digested it
> yet.

Yeah, that's probably no good :(
 
> Maybe we could avoid entering the below block of check_initializer at all in
> this situation?
> 
> >   if (((type_build_ctor_call (type) || CLASS_TYPE_P (type))
> >&& !(flags & LOOKUP_ALREADY_DIGESTED)
> >&& !(init && BRACE_ENCLOSED_INITIALIZER_P (init)
> > && CP_AGGREGATE_TYPE_P (type)
> > && (CLASS_TYPE_P (type)
> 
> Maybe by adding || processing_template_decl here?

That seems to work!  Thanks.

I've checked that we call build_vec_init when instantiating, so we
shouldn't be losing any of its effects.

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

-- >8 --
Since r9-6073 cxx_eval_store_expression preevaluates the value to
be stored, and that revealed a crash where a template code (here,
code=IMPLICIT_CONV_EXPR) leaks into cxx_eval*.

It happens because we're performing build_vec_init while processing
a template, which calls get_temp_regvar which creates an INIT_EXPR.
This INIT_EXPR's RHS contains an rvalue conversion so we create an
IMPLICIT_CONV_EXPR.  Its operand is not type-dependent and the whole
INIT_EXPR is not type-dependent.  So we call build_non_dependent_expr
which, with -fchecking=2, calls fold_non_dependent_expr.  At this
point the expression still has an IMPLICIT_CONV_EXPR, which ought to
be handled in instantiate_non_dependent_expr_internal.  However,
tsubst_copy_and_build doesn't handle INIT_EXPR; it will just call
tsubst_copy which does nothing when args is null.  So we fail to
replace the IMPLICIT_CONV_EXPR and ICE.

The problem is that we call build_vec_init in a template in the
first place.  We can avoid doing so by checking p_t_d before
calling build_aggr_init in check_initializer.

PR c++/104284

gcc/cp/ChangeLog:

* decl.cc (check_initializer): Don't call build_aggr_init in
a template.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/constexpr-104284-1.C: New test.
* g++.dg/cpp1y/constexpr-104284-2.C: New test.
* g++.dg/cpp1y/constexpr-104284-3.C: New test.
* g++.dg/cpp1y/constexpr-104284-4.C: New test.
---
 gcc/cp/decl.cc|  4 +++
 .../g++.dg/cpp1y/constexpr-104284-1.C | 34 ++
 .../g++.dg/cpp1y/constexpr-104284-2.C | 33 +
 .../g++.dg/cpp1y/constexpr-104284-3.C | 33 +
 .../g++.dg/cpp1y/constexpr-104284-4.C | 35 +++
 5 files changed, 139 insertions(+)
 create mode 100644 gcc/testsuite/

Re: [PATCH v2] c++/96765: warn when casting Base* to Derived* in Base ctor/dtor

2022-03-24 Thread Jason Merrill via Gcc-patches

On 3/17/22 01:51, Zhao Wei Liew wrote:

Thanks for the review. I've tested and uploaded a new patch v2 with
the requested changes.

On Thu, 17 Mar 2022 at 09:20, Jason Merrill  wrote:


On 3/14/22 02:36, Zhao Wei Liew via Gcc-patches wrote:


This patch adds a warning when casting "this" to Derived* in the Base
class constructor and destructor. I've added the warning under the
-Wextra flag as I can't find a more appropriate flag for it.


It's generally best to add a new warning flag if an existing one isn't a
good match.  Maybe -Wderived-cast-undefined?  It seems like it could be
part of -Wall.


Hmm, I agree. I've added a new -Wderived-cast-undefined flag for this.


+  if (current_function_decl
+  && (DECL_CONSTRUCTOR_P (current_function_decl)
+  || DECL_DESTRUCTOR_P (current_function_decl))
+  && TREE_CODE (expr) == NOP_EXPR
+  && is_this_parameter (TREE_OPERAND (expr, 0)))


I think the resolves_to_fixed_type_p function would be useful here;
you're testing for a subset of the cases it handles.


Does the new patch look like how you intended it to? The new patch
passes all regression tests and newly added tests. However, I don't
fully understand the code for resolves_to_fixed_type_p() and
fixed_type_or_null(), except that I see that they contain logic to
return -1 when within a ctor/dtor.



+  if (TREE_CODE (expr) == NOP_EXPR
+  && resolves_to_fixed_type_p (TREE_OPERAND (expr, 0)) == -1)


Why not just pass expr itself to resolves_to_fixed_type_p?

We might as well also warn if it returns >0, e.g.

struct A { } a;
struct B: A { };
auto p = static_cast(&a); // undefined

You should also handle reference casts.

Jason



Re: [PATCH v7] c++: Add diagnostic when operator= is used as truth cond [PR25689]

2022-03-24 Thread Jason Merrill via Gcc-patches

On 3/13/22 19:43, Zhao Wei Liew wrote:

On Sat, 12 Mar 2022 at 06:15, Jason Merrill  wrote:

It looks good, but unfortunately regresses some other warning tests,
such as Wnonnull5.C.  Please remember to run the regression tests before
sending a patch (https://gcc.gnu.org/contribute.html#testing).

This seems to be a complicated problem with suppress_warning, which
means your call to suppress_warning effectively silences all later
warnings, not just -Wparentheses.

You should be able to work around this issue by only calling
suppress_warning in the specific case we're interested in, i.e. when
warn_parentheses is enabled and "call" is a MODIFY_EXPR.


My apologies. I've fixed the issue as you suggested and run the regression tests
to ensure no test regressions. The new patch (v9) is attached.


Looks good.  One thing:


+   /* Ideally, we'd warn for empty classes using trivial operator= (below),
+  but we don't do so yet as it is a non-trivial COMPOUND_EXPR. */
+	// if (a1 = a2); 


It would be better to uncomment this line and give it an xfailed 
warning, i.e.


/* { dg-warning "suggest parentheses" "" { xfail *-*-* } } */

I've made this change and added the patch to my queue to commit when GCC 
13 stage 1 opens, probably next month.


Thanks!

Jason



Re: [PATCH v3] c++: ICE with template code in constexpr [PR104284]

2022-03-24 Thread Jason Merrill via Gcc-patches

On 3/24/22 17:53, Marek Polacek wrote:

On Thu, Mar 24, 2022 at 11:40:11AM -0400, Jason Merrill wrote:

On 3/18/22 17:55, Marek Polacek wrote:

On Fri, Mar 11, 2022 at 06:46:42PM -0500, Jason Merrill wrote:

On 3/10/22 18:04, Marek Polacek wrote:

Since r9-6073 cxx_eval_store_expression preevaluates the value to
be stored, and that revealed a crash where a template code (here,
code=IMPLICIT_CONV_EXPR) leaks into cxx_eval*.

It happens because we're performing build_vec_init while processing
a template


Hmm, that seems like the bug.  Where's that call coming from?


  From build_aggr_init.  So we're handling e.g.

template
constexpr void g () {
  constexpr S s2[]{{'a'}};
}

cp_finish_decl (decl=s2, init={{'a'}}) sees we're in processing_template_decl,
but also that we have a constexpr var which is not dependent, nor is its
initializer:

else if (init
 && (init_const_expr_p || DECL_DECLARED_CONSTEXPR_P (decl))
 && !TYPE_REF_P (type)
 && decl_maybe_constant_var_p (decl)
 && !(dep_init = value_dependent_init_p (init)))
  {
/* This variable seems to be a non-dependent constant, so process
   its initializer.  If check_initializer returns non-null the
   initialization wasn't constant after all.  */
tree init_code;
cleanups = make_tree_vector ();
init_code = check_initializer (decl, init, flags, &cleanups);

so we call check_initializer, where we go down this path:

init_code = build_aggr_init_full_exprs (decl, init, flags);

build_aggr_init sees that the type of 's2' is ARRAY_TYPE, so it calls
build_vec_init.

I now recall that we've discussed build_vec_init in a template in the
past, for example in the context of c++/93676.  So I agree we ought to
make an effort to avoid calling build_vec_init in a template.  Perhaps
like this: use an INIT_EXPR.  With that, we should call build_vec_init
if needed while instantiating.  Does that make any sense?


Hmm.  If we do that, then we get back to


   if (TREE_CODE (init_code) == INIT_EXPR)


in check_initializer, and pull out the same init again, and set
LOOKUP_ALREADY_DIGESTED.  But I think that's wrong, we haven't digested it
yet.


Yeah, that's probably no good :(
  

Maybe we could avoid entering the below block of check_initializer at all in
this situation?


   if (((type_build_ctor_call (type) || CLASS_TYPE_P (type))
&& !(flags & LOOKUP_ALREADY_DIGESTED)
&& !(init && BRACE_ENCLOSED_INITIALIZER_P (init)
 && CP_AGGREGATE_TYPE_P (type)
 && (CLASS_TYPE_P (type)


Maybe by adding || processing_template_decl here?


That seems to work!  Thanks.

I've checked that we call build_vec_init when instantiating, so we
shouldn't be losing any of its effects.

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


OK.


-- >8 --
Since r9-6073 cxx_eval_store_expression preevaluates the value to
be stored, and that revealed a crash where a template code (here,
code=IMPLICIT_CONV_EXPR) leaks into cxx_eval*.

It happens because we're performing build_vec_init while processing
a template, which calls get_temp_regvar which creates an INIT_EXPR.
This INIT_EXPR's RHS contains an rvalue conversion so we create an
IMPLICIT_CONV_EXPR.  Its operand is not type-dependent and the whole
INIT_EXPR is not type-dependent.  So we call build_non_dependent_expr
which, with -fchecking=2, calls fold_non_dependent_expr.  At this
point the expression still has an IMPLICIT_CONV_EXPR, which ought to
be handled in instantiate_non_dependent_expr_internal.  However,
tsubst_copy_and_build doesn't handle INIT_EXPR; it will just call
tsubst_copy which does nothing when args is null.  So we fail to
replace the IMPLICIT_CONV_EXPR and ICE.

The problem is that we call build_vec_init in a template in the
first place.  We can avoid doing so by checking p_t_d before
calling build_aggr_init in check_initializer.

PR c++/104284

gcc/cp/ChangeLog:

* decl.cc (check_initializer): Don't call build_aggr_init in
a template.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/constexpr-104284-1.C: New test.
* g++.dg/cpp1y/constexpr-104284-2.C: New test.
* g++.dg/cpp1y/constexpr-104284-3.C: New test.
* g++.dg/cpp1y/constexpr-104284-4.C: New test.
---
  gcc/cp/decl.cc|  4 +++
  .../g++.dg/cpp1y/constexpr-104284-1.C | 34 ++
  .../g++.dg/cpp1y/constexpr-104284-2.C | 33 +
  .../g++.dg/cpp1y/constexpr-104284-3.C | 33 +
  .../g++.dg/cpp1y/constexpr-104284-4.C | 35 +++
  5 files changed, 139 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-104284-1.C
  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-104284-2.C
  create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-104284-3.C
  creat

[PATCH v3] c++: alignas and alignof void [PR104944]

2022-03-24 Thread Marek Polacek via Gcc-patches
On Thu, Mar 24, 2022 at 05:12:12PM -0400, Jason Merrill wrote:
> On 3/24/22 15:56, Marek Polacek wrote:
> > On Thu, Mar 24, 2022 at 12:02:29PM -0400, Jason Merrill wrote:
> > > On 3/24/22 11:49, Marek Polacek wrote:
> > > > I started looking into this PR because in GCC 4.9 we were able to
> > > > detect the invalid
> > > > 
> > > > struct alignas(void) S{};
> > > > 
> > > > but I broke it in r210262.
> > > > 
> > > > It's ill-formed code in C++:
> > > > [dcl.align]/3: "An alignment-specifier of the form alignas(type-id) has
> > > > the same effect as alignas(alignof(type-id))", and [expr.align]/1:
> > > > "The operand shall be a type-id representing a complete object type,
> > > > or an array thereof, or a reference to one of those types." and void
> > > > is not a complete type.
> > > > 
> > > > It's also invalid in C:
> > > > 6.7.5: _Alignas(type-name) is equivalent to 
> > > > _Alignas(_Alignof(type-name))
> > > > 6.5.3.4: "The _Alignof operator shall not be applied to a function type
> > > > or an incomplete type."
> > > > 
> > > > We have a GNU extension whereby we treat sizeof(void) as 1, but I assume
> > > > it doesn't apply to alignof, so I'd like to reject it in C too.
> > > 
> > > That makes sense to me in principle, but we've allowed it since the
> > > beginning of version control, back when c_alignof was a separate function.
> > > Changing that seems questionable for a regression fix.
> > 
> > Ok, that makes sense.  How about rejecting alignof(void) in C++ only
> > now (where it is a regression), and maybe come back to this in GCC 13 for C?
> 
> I'd probably just leave it alone for C and __alignof.

Fair enough.

> > PR c++/104944
> > 
> > gcc/c-family/ChangeLog:
> > 
> > * c-common.cc (c_sizeof_or_alignof_type): Do not allow alignof(void)
> > in C++.
> > 
> > gcc/cp/ChangeLog:
> > 
> > * typeck.cc (cxx_alignas_expr): Call cxx_sizeof_or_alignof_type with
> > complain == true.
> 
> This hunk is OK.  But let's put the diagnostic in
> cxx_sizeof_or_alignof_type, where it can depend on std_alignof.

Like so?  With this patch __alignof only produces a pedwarn (there's no
__alignas to worry about).

-- >8 --
I started looking into this PR because in GCC 4.9 we were able to
detect the invalid

  struct alignas(void) S{};

but I broke it in r210262.

It's ill-formed code in C++:
[dcl.align]/3: "An alignment-specifier of the form alignas(type-id) has
the same effect as alignas(alignof(type-id))", and [expr.align]/1:
"The operand shall be a type-id representing a complete object type,
or an array thereof, or a reference to one of those types." and void
is not a complete type.

It's also invalid in C:
6.7.5: _Alignas(type-name) is equivalent to _Alignas(_Alignof(type-name))
6.5.3.4: "The _Alignof operator shall not be applied to a function type
or an incomplete type."

We have a GNU extension whereby we treat sizeof(void) as 1, but I assume
it doesn't apply to alignof, at least in C++.  However, __alignof__(void)
is still accepted with a -Wpedantic warning.

(We still say "invalid application of '__alignof__'" rather than
'alignas' but I felt that fixing that may not be suitable as part of this
patch.)

PR c++/104944

gcc/cp/ChangeLog:

* typeck.cc (cxx_sizeof_or_alignof_type): Diagnose alignof(void).
(cxx_alignas_expr): Call cxx_sizeof_or_alignof_type with
complain == true.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/alignas20.C: New test.
---
 gcc/cp/typeck.cc   | 21 +++--
 gcc/testsuite/g++.dg/cpp0x/alignas20.C | 26 ++
 2 files changed, 41 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alignas20.C

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 516fa574ef6..26a7cb4b50d 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -1873,9 +1873,9 @@ compparms (const_tree parms1, const_tree parms2)
 }
 
 
-/* Process a sizeof or alignof expression where the operand is a
-   type. STD_ALIGNOF indicates whether an alignof has C++11 (minimum alignment)
-   or GNU (preferred alignment) semantics; it is ignored if op is
+/* Process a sizeof or alignof expression where the operand is a type.
+   STD_ALIGNOF indicates whether an alignof has C++11 (minimum alignment)
+   or GNU (preferred alignment) semantics; it is ignored if OP is
SIZEOF_EXPR.  */
 
 tree
@@ -1899,6 +1899,13 @@ cxx_sizeof_or_alignof_type (location_t loc, tree type, 
enum tree_code op,
   else
return error_mark_node;
 }
+  else if (VOID_TYPE_P (type) && std_alignof)
+{
+  if (complain)
+   error_at (loc, "invalid application of %qs to a void type",
+ OVL_OP_INFO (false, op)->name);
+  return error_mark_node;
+}
 
   bool dependent_p = dependent_type_p (type);
   if (!dependent_p)
@@ -2132,11 +2139,13 @@ cxx_alignas_expr (tree e)
 /* [dcl.align]/3:

   When the alignment-specifier is of the form
-  alignas(type

[committed] Docs: Document that taint analyzer checker disables some warnings [PR103533]

2022-03-24 Thread David Malcolm via Gcc-patches
From: Avinash Sonawane 

On Thu, 2022-03-24 at 10:41 +0530, Avinash Sonawane wrote:
> On Wed, 23 Mar 2022 18:33:38 -0400
> David Malcolm  wrote:
>  
> > This is almost ready to push to trunk, but there are a couple of
> > extra
> > tasks needed to be done:
> 
> Done.
> 
> Please find the attached v3 patch and let me know if something needs
> to
> be changed/added. 
> 
> Thanks!

I tweaked the wording: "disables following" to "disables the following",
added references to PR analyzer/103533 to the Subject and ChangeLog,
inspected the generated manpage, and ran it through a full bootstrap.

I've gone ahead and pushed it to trunk as r12-7808-g319ba7e241e7e2:
  
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=319ba7e241e7e21f9eb481f075310796f13d2035
(the patch I committed follows)

Thanks again!
Dave

gcc/ChangeLog:
PR analyzer/103533
* doc/invoke.texi: Document that enabling taint analyzer
checker disables some warnings from `-fanalyzer`.

Signed-off-by: Avinash Sonawane 
---
 gcc/doc/invoke.texi | 33 +++--
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4da4a1170f5..8b16b35ec12 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -421,14 +421,13 @@ Objective-C and Objective-C++ Dialects}.
 -fanalyzer-checker=@var{name} @gol
 -fno-analyzer-feasibility @gol
 -fanalyzer-fine-grained @gol
--fanalyzer-state-merge @gol
--fanalyzer-state-purge @gol
+-fno-analyzer-state-merge @gol
+-fno-analyzer-state-purge @gol
 -fanalyzer-transitivity @gol
 -fanalyzer-verbose-edges @gol
 -fanalyzer-verbose-state-changes @gol
 -fanalyzer-verbosity=@var{level} @gol
 -fdump-analyzer @gol
--fdump-analyzer-stderr @gol
 -fdump-analyzer-callgraph @gol
 -fdump-analyzer-exploded-graph @gol
 -fdump-analyzer-exploded-nodes @gol
@@ -438,6 +437,7 @@ Objective-C and Objective-C++ Dialects}.
 -fdump-analyzer-feasibility @gol
 -fdump-analyzer-json @gol
 -fdump-analyzer-state-purge @gol
+-fdump-analyzer-stderr @gol
 -fdump-analyzer-supergraph @gol
 -Wno-analyzer-double-fclose @gol
 -Wno-analyzer-double-free @gol
@@ -9659,22 +9659,24 @@ Enabling this option effectively enables the following 
warnings:
 -Wanalyzer-free-of-non-heap @gol
 -Wanalyzer-malloc-leak @gol
 -Wanalyzer-mismatching-deallocation @gol
--Wanalyzer-possible-null-argument @gol
--Wanalyzer-possible-null-dereference @gol
 -Wanalyzer-null-argument @gol
 -Wanalyzer-null-dereference @gol
+-Wanalyzer-possible-null-argument @gol
+-Wanalyzer-possible-null-dereference @gol
 -Wanalyzer-shift-count-negative @gol
 -Wanalyzer-shift-count-overflow @gol
 -Wanalyzer-stale-setjmp-buffer @gol
+@ignore
 -Wanalyzer-tainted-allocation-size @gol
 -Wanalyzer-tainted-array-index @gol
 -Wanalyzer-tainted-divisor @gol
 -Wanalyzer-tainted-offset @gol
 -Wanalyzer-tainted-size @gol
+@end ignore
 -Wanalyzer-unsafe-call-within-signal-handler @gol
 -Wanalyzer-use-after-free @gol
--Wanalyzer-use-of-uninitialized-value @gol
 -Wanalyzer-use-of-pointer-in-stale-stack-frame @gol
+-Wanalyzer-use-of-uninitialized-value @gol
 -Wanalyzer-write-to-const @gol
 -Wanalyzer-write-to-string-literal @gol
 }
@@ -10015,6 +10017,25 @@ such as the @code{taint} checker that implements
 @option{-Wanalyzer-tainted-array-index}, and this option is required
 to enable them.
 
+@emph{Note:} currently, @option{-fanalyzer-checker=taint} disables the
+following warnings from @option{-fanalyzer}:
+
+@gccoptlist{ @gol
+-Wanalyzer-double-fclose @gol
+-Wanalyzer-double-free @gol
+-Wanalyzer-exposure-through-output-file @gol
+-Wanalyzer-file-leak @gol
+-Wanalyzer-free-of-non-heap @gol
+-Wanalyzer-malloc-leak @gol
+-Wanalyzer-mismatching-deallocation @gol
+-Wanalyzer-null-argument @gol
+-Wanalyzer-null-dereference @gol
+-Wanalyzer-possible-null-argument @gol
+-Wanalyzer-possible-null-dereference @gol
+-Wanalyzer-unsafe-call-within-signal-handler @gol
+-Wanalyzer-use-after-free @gol
+}
+
 @item -fno-analyzer-feasibility
 @opindex fanalyzer-feasibility
 @opindex fno-analyzer-feasibility
-- 
2.26.3



[committed] analyzer: add region::tracked_p to optimize state objects [PR104954]

2022-03-24 Thread David Malcolm via Gcc-patches
PR analyzer/104954 tracks that -fanalyzer was taking a very long time
on a particular source file in the Linux kernel:
  drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c

One issue occurs with the repeated use of dynamic debug lines e.g. via
the DC_LOG_BANDWIDTH_CALCS macro, such as in print_bw_calcs_dceip in
drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h:

  
DC_LOG_BANDWIDTH_CALCS("#");
  DC_LOG_BANDWIDTH_CALCS("struct bw_calcs_dceip");
  
DC_LOG_BANDWIDTH_CALCS("#");

  [...snip dozens of lines...]

  DC_LOG_BANDWIDTH_CALCS("[bw_fixed] dmif_request_buffer_size: %d",
 bw_fixed_to_int(dceip->dmif_request_buffer_size));

When this is configured to use __dynamic_pr_debug, each of these becomes
code like:

  do {
static struct _ddebug __attribute__((__aligned__(8)))
__attribute__((__section__("__dyndbg"))) __UNIQUE_ID_ddebug277 = {
  [...snip...]
};
if (arch_static_branch(&__UNIQUE_ID_ddebug277.key, false))
  __dynamic_pr_debug(&__UNIQUE_ID_ddebug277, [...the message...]);
  } while (0);

The analyzer was naively seeing each call to __dynamic_pr_debug, noting
that the __UNIQUE_ID_ object escapes.  At each call, as successive
__UNIQUE_ID_ object escapes, there are N escaped objects, and thus N
need clobbering, and so we have O(N^2) clobbering of escaped objects overall,
leading to huge amounts of pointless work: print_bw_calcs_data has 225
uses of DC_LOG_BANDWIDTH_CALCS, many of which are in loops.

This patch adds a way to identify declarations that aren't interesting
to the analyzer, so that we don't attempt to create binding_clusters
for them (i.e. we don't store any state for them in our state objects).
This is implemented by adding a new region::tracked_p, implemented for
declarations by walking the existing IPA data the first time the
analyzer sees a declaration, setting it to false for global vars that
have no loads/stores/aliases, and "sufficiently safe" address-of
ipa-refs.

The patch gives a large speedup of -fanalyzer on the above kernel
source file:
   Before  After
Total cc1 wallclock time:180s36s
analyzer wallclock time: 162s17s
% spent in analyzer:  90%47%

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r12-7809-g5f6197d7c197f9.

gcc/analyzer/ChangeLog:
PR analyzer/104954
* analyzer.opt (-fdump-analyzer-untracked): New option.
* engine.cc (impl_run_checkers): Handle it.
* region-model-asm.cc (region_model::on_asm_stmt): Don't attempt
to clobber regions with !tracked_p ().
* region-model-manager.cc (dump_untracked_region): New.
(region_model_manager::dump_untracked_regions): New.
(frame_region::dump_untracked_regions): New.
* region-model.h (region_model_manager::dump_untracked_regions):
New decl.
* region.cc (ipa_ref_requires_tracking): New.
(symnode_requires_tracking_p): New.
(decl_region::calc_tracked_p): New.
* region.h (region::tracked_p): New vfunc.
(frame_region::dump_untracked_regions): New decl.
(class decl_region): Note that this is also used fo SSA names.
(decl_region::decl_region): Initialize m_tracked.
(decl_region::tracked_p): New.
(decl_region::calc_tracked_p): New decl.
(decl_region::m_tracked): New.
* store.cc (store::get_or_create_cluster): Assert that we
don't try to create clusters for base regions that aren't
trackable.
(store::mark_as_escaped): Don't mark base regions that we're not
tracking.

gcc/ChangeLog:
PR analyzer/104954
* doc/invoke.texi (Static Analyzer Options): Add
-fdump-analyzer-untracked.

gcc/testsuite/ChangeLog:
PR analyzer/104954
* gcc.dg/analyzer/asm-x86-dyndbg-1.c: New test.
* gcc.dg/analyzer/asm-x86-dyndbg-2.c: New test.
* gcc.dg/analyzer/many-unused-locals.c: New test.
* gcc.dg/analyzer/untracked-1.c: New test.
* gcc.dg/analyzer/unused-local-1.c: New test.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/analyzer.opt |   4 +
 gcc/analyzer/engine.cc|   3 +
 gcc/analyzer/region-model-asm.cc  |   3 +-
 gcc/analyzer/region-model-manager.cc  |  41 ++
 gcc/analyzer/region-model.h   |   2 +
 gcc/analyzer/region.cc|  88 
 gcc/analyzer/region.h |  24 +++-
 gcc/analyzer/store.cc |   6 +-
 gcc/doc/invoke.texi   |   5 +
 .../gcc.dg/analyzer/asm-x86-dyndbg-1.c| 126 ++
 .../gcc.dg/analyzer/asm-x86-dyndbg-2.c|  77 +++
 .../gcc.dg/analyzer/many-unused-locals.c  |  69 ++
 gcc/testsuite/

[PATCH]rs6000: Update rtx_cost for constant building

2022-03-24 Thread Jiufu Guo via Gcc-patches
When building a const to a reg, it may need a few instructions.
This patch updates rs6000_rtx_costs to make it more accurate for
constant building.

With this patch, cse.cc could get accurate cost for complex
constant and then read the constant from a pool.
As discussed in the mail list, this patch is updating rtx_cost hook
which may be preferred for this issue.

Bootstrap and regtest pass on ppc64 and ppc64le.
Is this ok for trunk or more suitable for stage1?


BR,
Jiufu

PR target/63281

gcc/ChangeLog:

* config/rs6000/rs6000.cc (rs6000_rtx_costs): Update for
const int.

gcc/testsuite/ChangeLog:

* gcc.target/powerpc/pr63281.c: New test.

---
 gcc/config/rs6000/rs6000.cc|  8 
 gcc/testsuite/gcc.target/powerpc/pr63281.c | 11 +++
 2 files changed, 19 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr63281.c

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 283e8306ff7..62fcd345af2 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -21838,6 +21838,14 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int 
outer_code,
 
 case CONST_DOUBLE:
 case CONST_WIDE_INT:
+  /* Set a const to reg, it may needs a few insns.  */
+  if (outer_code == SET)
+   {
+ *total = COSTS_N_INSNS (num_insns_constant (x, mode));
+ return true;
+   }
+  /* FALLTHRU */
+
 case CONST:
 case HIGH:
 case SYMBOL_REF:
diff --git a/gcc/testsuite/gcc.target/powerpc/pr63281.c 
b/gcc/testsuite/gcc.target/powerpc/pr63281.c
new file mode 100644
index 000..469a8f64400
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr63281.c
@@ -0,0 +1,11 @@
+/* PR target/63281 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -std=c99" } */
+
+void
+foo (unsigned long long *a)
+{
+  *a = 0x020805006106003;
+}
+
+/* { dg-final { scan-assembler-times {\mp?ld\M} 1 } } */
-- 
2.25.1



[PATCH] [x86_64] Zhaoxin lujiazui enablement

2022-03-24 Thread MayShao
Hi Uros,

This patch fix Zhaoxin CPU Vendor ID detection problem
and add Zhaoxin "lujiazui" processor support and tuning.

Currently gcc can't recognize Zhaoxin CPU (Vendor ID "CentaurHauls" and 
"Shanghai")
and wrongly identify Zhaoxin "lujiazui" as Intel core2 or i386, which is 
confusing for users.

This patch enables -march/-mtune=lujiazui. Lujiazui is Zhaonxin family 7th 
processor.
Costs and tunings are set according to the characteristics of the processor.
We add a new md file to describe lujiazui pipeline.

Testing :
Bootstrap is ok, and no regressions for i386/x86-64 testsuite.

OK for master?

Background:
Related Zhaoxin linux kernel patch can be found at:
https://lore.kernel.org/lkml/01042674b2f741b2aed1f797359bd...@zhaoxin.com/

Related Zhaoxin glibc patch can be found at:
https://sourceware.org/git/?p=glibc.git;a=commit;h=32ac0b988466785d6e3cc1dffc364bb26fc63193

gcc/ChangeLog:

   * common/config/i386/cpuinfo.h (get_zhaoxin_cpu): Detect
   the cpu type of ZHAOXIN processors.
   (cpu_indicator_init): Handle ZHAOXIN processors.
   * common/config/i386/i386-common.cc: Add lujiazui.
   * common/config/i386/i386-cpuinfo.h (enum processor_vendor): Add
   VENDOR_ZHAOXIN.
   (enum processor_types): Add ZHAOXIN_FAM7H.
   (enum processor_subtypes):Add ZHAOXIN_FAM7H_LUJIAZUI.
   * config.gcc: Add -march=lujiazui.
   * config/i386/cpuid.h (signature_SHANGHAI_ebx): New definition
   for ZHAOXIN.
   (signature_SHANGHAI_ecx): Likewise.
   (signature_SHANGHAI_edx): Likewise.
   * config/i386/driver-i386.cc (host_detect_local_cpu): Let
   -march=native recognize lujiazui processor.
   * config/i386/i386-c.cc (ix86_target_macros_internal): Add
   lujiazui def_or_undef.
   * config/i386/i386-options.cc (m_LUJIAZUI): New definition.
   * config/i386/i386.h (enum processor_type): Add PROCESSOR_LUJIAZUI.
   * config/i386/i386.md: Add lujiazui cpu and include new md file.
   * config/i386/x86-tune-costs.h (struct processor_costs): Add
   lujiazui_cost.
   * config/i386/x86-tune-sched.cc (ix86_issue_rate): Add lujiazui.
   (ix86_adjust_cost): Likewise.
   * config/i386/x86-tune.def (X86_TUNE_SCHEDULE): Enable for lujiazui.
   (X86_TUNE_PARTIAL_REG_DEPENDENCY): Likewise.
   (X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY): Likewise.
   (X86_TUNE_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY): Likewise.
   (X86_TUNE_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY): Likewise.
   (X86_TUNE_MOVX): Likewise.
   (X86_TUNE_MEMORY_MISMATCH_STALL): Likewise.
   (X86_TUNE_FUSE_CMP_AND_BRANCH_32): Likewise.
   (X86_TUNE_FUSE_CMP_AND_BRANCH_64): Likewise.
   (X86_TUNE_FUSE_CMP_AND_BRANCH_SOFLAGS): Likewise.
   (X86_TUNE_FUSE_ALU_AND_BRANCH): Likewise.
   (X86_TUNE_ACCUMULATE_OUTGOING_ARGS): Likewise.
   (X86_TUNE_USE_LEAVE): Likewise.
   (X86_TUNE_PUSH_MEMORY): Likewise.
   (X86_TUNE_LCP_STALL): Likewise.
   (X86_TUNE_USE_INCDEC): Likewise.
   (X86_TUNE_INTEGER_DFMODE_MOVES): Likewise.
   (X86_TUNE_OPT_AGU): Likewise.
   (X86_TUNE_PREFER_KNOWN_REP_MOVSB_STOSB): Likewise.
   (X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES): Likewise.
   (X86_TUNE_USE_SAHF): Likewise.
   (X86_TUNE_USE_BT): Likewise.
   (X86_TUNE_AVOID_FALSE_DEP_FOR_BMI): Likewise.
   (X86_TUNE_ONE_IF_CONV_INSN): Likewise.
   (X86_TUNE_AVOID_MFENCE): Likewise.
   (X86_TUNE_EXPAND_ABS): Likewise.
   (X86_TUNE_USE_SIMODE_FIOP): Likewise.
   (X86_TUNE_USE_FFREEP): Likewise.
   (X86_TUNE_EXT_80387_CONSTANTS): Likewise.
   (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL): Likewise.
   (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL): Likewise.
   (X86_TUNE_SSE_TYPELESS_STORES): Likewise.
   (X86_TUNE_SSE_LOAD0_BY_PXOR): Likewise.
   (X86_TUNE_USE_GATHER): Likewise.
   * doc/extend.texi: Add lujiazui.
   * doc/invoke.texi: Add details about lujiazui.
   * config/i386/lujiazui.md: New file for describing lujiazui pipeline.

gcc/testsuite/ChangeLog:

   * gcc.target/i386/funcspec-56.inc: Handle new march.
   * g++.target/i386/mv31.C: New test for -march=lujiazui.
---
 gcc/common/config/i386/cpuinfo.h  |  51 +-
 gcc/common/config/i386/i386-common.cc |   9 +
 gcc/common/config/i386/i386-cpuinfo.h |   3 +
 gcc/config.gcc|  10 +-
 gcc/config/i386/cpuid.h   |   4 +
 gcc/config/i386/driver-i386.cc|  20 +-
 gcc/config/i386/i386-c.cc |   7 +
 gcc/config/i386/i386-options.cc   |   3 +
 gcc/config/i386/i386.h|   1 +
 gcc/config/i386/i386.md   |   5 +-
 gcc/config/i386/lujiazui.md   | 844 ++
 gcc/config/i386/x86-tune-costs.h  | 115 +++
 gcc/config/i386/x86-tune-sched.cc |   2 +
 gcc/config/i386/x86-tune.def  |  91 +-
 gcc/doc/extend.texi   

[PATCH 0/3] RISC-V: Add Ratified Cache Management Operation ISA Extensions

2022-03-24 Thread yulong
From: yulong-plct 

This patchset adds support for three recently ratified RISC-V extensions:

-   Zicbom (Cache-Block Management Instructions)
-   Zicbop (Cache-Block Prefetch hint instructions)
-   Zicboz (Cache-Block Zero Instructions)

The naming of builtin caused oddities, so in this release we have changed the 
names of builtin. For example, change "__builtin_riscv_zero()" to 
"__builtin_riscv_zicboz_cbo_zero"

Patch 1: Add Zicbom/z/p mininal support
Patch 2: Add Zicbom/z/p instructions arch support
Patch 3: Add Zicbom/z/p instructions testcases

cf. 
;

*** BLURB HERE ***

yulong-plct (3):
  RISC-V: Add mininal support for Zicbo[mzp]
  RISC-V:Cache Management Operation instructions
  RISC-V:Cache Management Operation instructions testcases

 gcc/common/config/riscv/riscv-common.cc   |  6 +++
 gcc/config/riscv/predicates.md|  4 ++
 gcc/config/riscv/riscv-builtins.cc| 16 ++
 gcc/config/riscv/riscv-cmo.def| 17 ++
 gcc/config/riscv/riscv-ftypes.def |  4 ++
 gcc/config/riscv/riscv-opts.h |  9 
 gcc/config/riscv/riscv.md | 52 +++
 gcc/config/riscv/riscv.opt|  3 ++
 gcc/testsuite/gcc.target/riscv/cmo-zicbom-1.c | 21 
 gcc/testsuite/gcc.target/riscv/cmo-zicbom-2.c | 21 
 gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c | 23 
 gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c | 23 
 gcc/testsuite/gcc.target/riscv/cmo-zicboz-1.c |  9 
 gcc/testsuite/gcc.target/riscv/cmo-zicboz-2.c |  9 
 14 files changed, 217 insertions(+)
 create mode 100644 gcc/config/riscv/riscv-cmo.def
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbom-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbom-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicboz-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicboz-2.c

-- 
2.17.1



[PATCH 1/3] RISC-V: Add mininal support for Zicbo[mzp]

2022-03-24 Thread yulong
From: yulong-plct 

This commit adds minimal support for 'Zicbom','Zicboz' and 'Zicbop' extensions.

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc: Add zicbom, zicboz, zicbop 
extensions.
* config/riscv/riscv-opts.h (MASK_ZICBOZ): New.
(MASK_ZICBOM): New.
(MASK_ZICBOP): New.
(TARGET_ZICBOZ): New.
(TARGET_ZICBOM): New.
(TARGET_ZICBOP): New.
* config/riscv/riscv.opt: New.

---
 gcc/common/config/riscv/riscv-common.cc | 6 ++
 gcc/config/riscv/riscv-opts.h   | 9 +
 gcc/config/riscv/riscv.opt  | 3 +++
 3 files changed, 18 insertions(+)

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 1501242e296..52c6ac3b1c8 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -164,6 +164,9 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"zksed", ISA_SPEC_CLASS_NONE, 1, 0},
   {"zksh",  ISA_SPEC_CLASS_NONE, 1, 0},
   {"zkt",   ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zicboz",ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zicbom",ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zicbop",ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"zk",ISA_SPEC_CLASS_NONE, 1, 0},
   {"zkn",   ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1109,6 +1112,9 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"zksed",  &gcc_options::x_riscv_zk_subext, MASK_ZKSED},
   {"zksh",   &gcc_options::x_riscv_zk_subext, MASK_ZKSH},
   {"zkt",&gcc_options::x_riscv_zk_subext, MASK_ZKT},
+  {"zicboz", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOZ},
+  {"zicbom", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOM},
+  {"zicbop", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOP},
 
   {"zve32x",   &gcc_options::x_target_flags, MASK_VECTOR},
   {"zve32f",   &gcc_options::x_target_flags, MASK_VECTOR},
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 15bb5e76854..42a7ff698e7 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -83,6 +83,15 @@ enum stack_protector_guard {
 #define TARGET_ZBC((riscv_zb_subext & MASK_ZBC) != 0)
 #define TARGET_ZBS((riscv_zb_subext & MASK_ZBS) != 0)
 
+#define MASK_ZICBOZ   (1 << 0)
+#define MASK_ZICBOM   (1 << 1)
+#define MASK_ZICBOP   (1 << 2)
+
+
+#define TARGET_ZICBOZ ((riscv_zicmo_subext & MASK_ZICBOZ) != 0)
+#define TARGET_ZICBOM ((riscv_zicmo_subext & MASK_ZICBOM) != 0)
+#define TARGET_ZICBOP ((riscv_zicmo_subext & MASK_ZICBOP) != 0)
+
 #define MASK_ZBKB (1 << 0)
 #define MASK_ZBKC (1 << 1)
 #define MASK_ZBKX (1 << 2)
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 492aad12324..a0722613fcc 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -200,6 +200,9 @@ int riscv_zi_subext
 TargetVariable
 int riscv_zb_subext
 
+TargetVariable
+int riscv_zicmo_subext
+
 TargetVariable
 int riscv_zk_subext
 
-- 
2.17.1



[PATCH 2/3] RISC-V:Cache Management Operation instructions

2022-03-24 Thread yulong
From: yulong-plct 

This commit adds cbo.clea,cbo.flush,cbo.inval,cbo.zero,prefetch.i,prefetch.r 
and prefetch.w instructions.

gcc/ChangeLog:

* config/riscv/predicates.md (imm5_operand): Add a new operand type for 
prefetch instructions.
* config/riscv/riscv-builtins.cc (AVAIL): Add new AVAILs for CMO ISA 
Extensions.
(RISCV_ATYPE_SI): New.
(RISCV_ATYPE_DI): New.
* config/riscv/riscv-ftypes.def (0): New.
(1): New.
* config/riscv/riscv.md (riscv_clean_): New.
(riscv_flush_): New.
(riscv_inval_): New.
(riscv_zero_): New.
(prefetch): New.
(riscv_prefetchi_): New.
* config/riscv/riscv-cmo.def: New file.
---
 gcc/config/riscv/predicates.md |  4 +++
 gcc/config/riscv/riscv-builtins.cc | 16 +
 gcc/config/riscv/riscv-cmo.def | 17 ++
 gcc/config/riscv/riscv-ftypes.def  |  4 +++
 gcc/config/riscv/riscv.md  | 52 ++
 5 files changed, 93 insertions(+)
 create mode 100644 gcc/config/riscv/riscv-cmo.def

diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 97cdbdf053b..3fb4d95ab08 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -239,3 +239,7 @@
 (define_predicate "const63_operand"
   (and (match_code "const_int")
(match_test "INTVAL (op) == 63")))
+
+(define_predicate "imm5_operand"
+  (and (match_code "const_int")
+   (match_test "INTVAL (op) < 5")))
\ No newline at end of file
diff --git a/gcc/config/riscv/riscv-builtins.cc 
b/gcc/config/riscv/riscv-builtins.cc
index 0658f8d3047..795132a0c16 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -87,6 +87,18 @@ struct riscv_builtin_description {
 
 AVAIL (hard_float, TARGET_HARD_FLOAT)
 
+
+AVAIL (clean32, TARGET_ZICBOM && !TARGET_64BIT)
+AVAIL (clean64, TARGET_ZICBOM && TARGET_64BIT)
+AVAIL (flush32, TARGET_ZICBOM && !TARGET_64BIT)
+AVAIL (flush64, TARGET_ZICBOM && TARGET_64BIT)
+AVAIL (inval32, TARGET_ZICBOM && !TARGET_64BIT)
+AVAIL (inval64, TARGET_ZICBOM && TARGET_64BIT)
+AVAIL (zero32,  TARGET_ZICBOZ && !TARGET_64BIT)
+AVAIL (zero64,  TARGET_ZICBOZ && TARGET_64BIT)
+AVAIL (prefetchi32, TARGET_ZICBOP && !TARGET_64BIT)
+AVAIL (prefetchi64, TARGET_ZICBOP && TARGET_64BIT)
+
 /* Construct a riscv_builtin_description from the given arguments.
 
INSN is the name of the associated instruction pattern, without the
@@ -119,6 +131,8 @@ AVAIL (hard_float, TARGET_HARD_FLOAT)
 /* Argument types.  */
 #define RISCV_ATYPE_VOID void_type_node
 #define RISCV_ATYPE_USI unsigned_intSI_type_node
+#define RISCV_ATYPE_SI intSI_type_node
+#define RISCV_ATYPE_DI intDI_type_node
 
 /* RISCV_FTYPE_ATYPESN takes N RISCV_FTYPES-like type codes and lists
their associated RISCV_ATYPEs.  */
@@ -128,6 +142,8 @@ AVAIL (hard_float, TARGET_HARD_FLOAT)
   RISCV_ATYPE_##A, RISCV_ATYPE_##B
 
 static const struct riscv_builtin_description riscv_builtins[] = {
+  #include "riscv-cmo.def"
+
   DIRECT_BUILTIN (frflags, RISCV_USI_FTYPE, hard_float),
   DIRECT_NO_TARGET_BUILTIN (fsflags, RISCV_VOID_FTYPE_USI, hard_float)
 };
diff --git a/gcc/config/riscv/riscv-cmo.def b/gcc/config/riscv/riscv-cmo.def
new file mode 100644
index 000..01cbf6ad64f
--- /dev/null
+++ b/gcc/config/riscv/riscv-cmo.def
@@ -0,0 +1,17 @@
+// zicbom
+RISCV_BUILTIN (clean_si, "zicbom_cbo_clean", RISCV_BUILTIN_DIRECT, 
RISCV_SI_FTYPE, clean32),
+RISCV_BUILTIN (clean_di, "zicbom_cbo_clean", RISCV_BUILTIN_DIRECT, 
RISCV_DI_FTYPE, clean64),
+
+RISCV_BUILTIN (flush_si, "zicbom_cbo_flush", RISCV_BUILTIN_DIRECT, 
RISCV_SI_FTYPE, flush32),
+RISCV_BUILTIN (flush_di, "zicbom_cbo_flush", RISCV_BUILTIN_DIRECT, 
RISCV_DI_FTYPE, flush64),
+
+RISCV_BUILTIN (inval_si, "zicbom_cbo_inval", RISCV_BUILTIN_DIRECT, 
RISCV_SI_FTYPE, inval32),
+RISCV_BUILTIN (inval_di, "zicbom_cbo_inval", RISCV_BUILTIN_DIRECT, 
RISCV_DI_FTYPE, inval64),
+
+// zicboz
+RISCV_BUILTIN (zero_si, "zicboz_cbo_zero", RISCV_BUILTIN_DIRECT, 
RISCV_SI_FTYPE, zero32),
+RISCV_BUILTIN (zero_di, "zicboz_cbo_zero", RISCV_BUILTIN_DIRECT, 
RISCV_DI_FTYPE, zero64),
+
+// zicbop
+RISCV_BUILTIN (prefetchi_si, "zicbop_cbo_prefetchi", RISCV_BUILTIN_DIRECT, 
RISCV_SI_FTYPE_SI, prefetchi32),
+RISCV_BUILTIN (prefetchi_di, "zicbop_cbo_prefetchi", RISCV_BUILTIN_DIRECT, 
RISCV_DI_FTYPE_DI, prefetchi64),
\ No newline at end of file
diff --git a/gcc/config/riscv/riscv-ftypes.def 
b/gcc/config/riscv/riscv-ftypes.def
index 2214c496f9b..62421292ce7 100644
--- a/gcc/config/riscv/riscv-ftypes.def
+++ b/gcc/config/riscv/riscv-ftypes.def
@@ -28,3 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 
 DEF_RISCV_FTYPE (0, (USI))
 DEF_RISCV_FTYPE (1, (VOID, USI))
+DEF_RISCV_FTYPE (0, (SI))
+DEF_RISCV_FTYPE (0, (DI))
+DEF_RISCV_FTYPE (1, (SI, SI))
+DEF_RISCV_FTYPE (1, (DI, DI))
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index b3c5bce842a..43ad6e5a481 100644
--- a/gcc/config/riscv/riscv.md
+++ b/g

[PATCH 3/3] RISC-V:Cache Management Operation instructions testcases

2022-03-24 Thread yulong
From: yulong-plct 

This commit adds testcases about CMO instructions.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/cmo-zicbom-1.c: New test.
* gcc.target/riscv/cmo-zicbom-2.c: New test.
* gcc.target/riscv/cmo-zicbop-1.c: New test.
* gcc.target/riscv/cmo-zicbop-2.c: New test.
* gcc.target/riscv/cmo-zicboz-1.c: New test.
* gcc.target/riscv/cmo-zicboz-2.c: New test.

---
 gcc/testsuite/gcc.target/riscv/cmo-zicbom-1.c | 21 +
 gcc/testsuite/gcc.target/riscv/cmo-zicbom-2.c | 21 +
 gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c | 23 +++
 gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c | 23 +++
 gcc/testsuite/gcc.target/riscv/cmo-zicboz-1.c |  9 
 gcc/testsuite/gcc.target/riscv/cmo-zicboz-2.c |  9 
 6 files changed, 106 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbom-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbom-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicboz-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cmo-zicboz-2.c

diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbom-1.c 
b/gcc/testsuite/gcc.target/riscv/cmo-zicbom-1.c
new file mode 100644
index 000..26f980feb98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbom-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicbom -mabi=lp64" } */
+
+int foo1()
+{
+return __builtin_riscv_zicbom_cbo_clean();
+}
+
+int foo2()
+{
+return __builtin_riscv_zicbom_cbo_flush();
+}
+
+int foo3()
+{
+return __builtin_riscv_zicbom_cbo_inval();
+}
+
+/* { dg-final { scan-assembler-times "cbo.clean" 1 } } */
+/* { dg-final { scan-assembler-times "cbo.flush" 1 } } */
+/* { dg-final { scan-assembler-times "cbo.inval" 1 } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbom-2.c 
b/gcc/testsuite/gcc.target/riscv/cmo-zicbom-2.c
new file mode 100644
index 000..a997f22c233
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbom-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zicbom -mabi=ilp32" } */
+
+int foo1()
+{
+return __builtin_riscv_zicbom_cbo_clean();
+}
+
+int foo2()
+{
+return __builtin_riscv_zicbom_cbo_flush();
+}
+
+int foo3()
+{
+return __builtin_riscv_zicbom_cbo_inval();
+}
+
+/* { dg-final { scan-assembler-times "cbo.clean" 1 } } */
+/* { dg-final { scan-assembler-times "cbo.flush" 1 } } */
+/* { dg-final { scan-assembler-times "cbo.inval" 1 } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c 
b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c
new file mode 100644
index 000..a6132d4d893
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile target { { rv64-*-*}}} */
+/* { dg-options "-march=rv64gc_zicbop -mabi=lp64" } */
+
+void foo (char *p)
+{
+  __builtin_prefetch (p, 0, 0);
+  __builtin_prefetch (p, 0, 1);
+  __builtin_prefetch (p, 0, 2);
+  __builtin_prefetch (p, 0, 3);
+  __builtin_prefetch (p, 1, 0);
+  __builtin_prefetch (p, 1, 1);
+  __builtin_prefetch (p, 1, 2);
+  __builtin_prefetch (p, 1, 3);
+}
+
+int foo1()
+{
+  return __builtin_riscv_zicbop_cbo_prefetchi(1);
+}
+
+/* { dg-final { scan-assembler-times "prefetch.i" 1 } } */
+/* { dg-final { scan-assembler-times "prefetch.r" 4 } } */
+/* { dg-final { scan-assembler-times "prefetch.w" 4 } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c 
b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c
new file mode 100644
index 000..b88c1e42d99
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cmo-zicbop-2.c
@@ -0,0 +1,23 @@
+/* { dg-do compile target { { rv32-*-*}}} */
+/* { dg-options "-march=rv32gc_zicbop -mabi=ilp32" } */
+
+void foo (char *p)
+{
+  __builtin_prefetch (p, 0, 0);
+  __builtin_prefetch (p, 0, 1);
+  __builtin_prefetch (p, 0, 2);
+  __builtin_prefetch (p, 0, 3);
+  __builtin_prefetch (p, 1, 0);
+  __builtin_prefetch (p, 1, 1);
+  __builtin_prefetch (p, 1, 2);
+  __builtin_prefetch (p, 1, 3);
+}
+
+int foo1()
+{
+  return __builtin_riscv_zicbop_cbo_prefetchi(1);
+}
+
+/* { dg-final { scan-assembler-times "prefetch.i" 1 } } */
+/* { dg-final { scan-assembler-times "prefetch.r" 4 } } */
+/* { dg-final { scan-assembler-times "prefetch.w" 4 } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/cmo-zicboz-1.c 
b/gcc/testsuite/gcc.target/riscv/cmo-zicboz-1.c
new file mode 100644
index 000..3f1488a21b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cmo-zicboz-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicboz -mabi=lp64" } */
+
+int foo1()
+{
+return __builtin_riscv_zicboz_cbo_zero();
+}
+
+/* { dg-final { scan-assembler-times "