Re: [PATCH] RISC-V: Fix regular expression in target-specific test

2020-07-10 Thread Jim Wilson
On Fri, Jul 10, 2020 at 6:53 AM Simon Cook  wrote:
> Some square brackets were missing escape characters, causing DejaGnu to
> try and call a proc with the name "at".
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/read-thread-pointer.c: Fix escaping on
> regular expression.

Thanks.  Committed.

I noticed that the riscv-gnu-toolchain "make report" command doesn't
check for or report dejagnu errors, which is maybe how Kito missed
this.

Jim


Re: [PATCH] rs6000: Define movsf_from_si2 to extract high part SF element from DImode[PR89310]

2020-07-10 Thread Segher Boessenkool
Hi!

On Fri, Jul 10, 2020 at 09:39:40AM +0800, luoxhu wrote:
> OK, seems the md file needs a format tool too...

Heh.  Just make sure it looks good (that is, does what it looks like),
looks like the rest, etc.  It's hard to do anything nice with unspecs,
[ ] lists do not format well.

> >> +  "TARGET_NO_SF_SUBREG"
> >> +  "#"
> >> +  "&& vsx_reg_sfsubreg_ok (operands[0], SFmode)"
> > 
> > Put this in the insn condition?  And since this is just a predicate,
> > you can just use it instead of gpc_reg_operand.
> > 
> > (The split condition becomes "&& 1" then, not "").
> 
> OK, this seems a bit strange as movsi_from_sf, movsf_from_si and
> movdi_from_sf_zero_ext all use it as condition...

Since in your case you *always* split, the split condition should be
"always".  There are no alternatives that do not split here.

> And why vsx_reg_sfsubreg_ok allows "SF SUBREGS" and TARGET_NO_SF_SUBREG
> "avoid (SUBREG:SF (REG:SI)", I guess they are not the same meaning? (The 
> TARGET_NO_SF_SUBREG is also copied from other similar defines.)  Thanks.

Good question.  I do not know.

Well...  Since this define_insn* requires p8 *anyway*, we do not need
any of these sf_subreg things?  We always know for each one if it should
be true or false.

> +  "TARGET_NO_SF_SUBREG"

But here we should require p8 some other way, then.

> +  (set_attr "isa" "p8v")])

(This isn't enough, unfortunately).


Segher


Re: [PATCH 2/2] rs6000: Define define_insn_and_split to split unspec sldi+or to rldimi

2020-07-10 Thread Segher Boessenkool
Hi!

On Thu, Jul 09, 2020 at 09:14:45PM -0500, Xiong Hu Luo wrote:
>   * config/rs6000/rs6000.md (rotl_unspec): New
>   define_insn_and_split.

> +; rldimi with UNSPEC_SI_FROM_SF.
> +(define_insn_and_split "*rotl_unspec"

Please have rotldi3_insert in the name.  "unspec" in the name doesn't
really mean much...  Can you put "sf" in the name, instead?  So something
like "*rotldi3_insert_sf"?

> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vector_float.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile  } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */

This needs p9vector_ok (yes, that name doesn't make too much sense).

> +vector float
> +test (float *a, float *b, float *c, float *d)
> +{
> +  return (vector float){*a, *b, *c, *d};
> +}
> +
> +/* { dg-final { scan-assembler-not {\mlxsspx\M} } } */
> +/* { dg-final { scan-assembler-not {\mlfs\M} } } */

No lxssp or lfsx either...  or the update forms...

/* { dg-final { scan-assembler-not {\mlxssp} } } */
/* { dg-final { scan-assembler-not {\mlfs} } } */

works fine (there are no other mnemonics starting with those strings).

> +/* { dg-final { scan-assembler-times {\mlwz\M} 4 } } */
> +/* { dg-final { scan-assembler-times {\mrldimi\M} 2 } } */
> +/* { dg-final { scan-assembler-times {\mmtvsrdd\M} 1 } } */

Okay for trunk with those changes (or post again if you prefer).  Thanks!


Segher


Re: [PATCH 1/2] rs6000: Init V4SF vector without converting SP to DP

2020-07-10 Thread Segher Boessenkool
Hi!

On Thu, Jul 09, 2020 at 09:14:44PM -0500, Xiong Hu Luo wrote:
> Move V4SF to V4SI, init vector like V4SI and move to V4SF back.
> Better instruction sequence could be generated on Power9:

> The point is to use lwz to avoid converting the single-precision to
> double-precision upon load, pack four 32-bit data into one 128-bit
> register directly.

> +   rtx tmpSF[4];
> +   rtx tmpSI[4];
> +   rtx tmpDI[4];
> +   rtx mrgDI[4];

Don't use upper case in variable names like this please.  Either tmpsf
or tmp_sf is fine.

> +   emit_move_insn (target, gen_lowpart (V4SFmode, tmpV2DI));

(This is a good example of why: it isn't obvious from just seeing this
that the tmpV2DI is a variable, while the V4SFmode is a symbolic
constant).

Looks fine other than that :-)


Segher


[PATCH] rs6000: add effective-target test ppc_mma_hw

2020-07-10 Thread Aaron Sawdey via Gcc-patches
Add a test for dejagnu to determine if execution of MMA instructions is
supported in the test environment. Add an execution test to make sure
that __builtin_cpu_supports("mma") is true if we can execute MMA
instructions.

OK for trunk and backport to 10?

Thanks!
   Aaron

gcc/testsuite/

* lib/target-supports.exp (check_ppc_mma_hw_available):
New function.
(is-effective-target): Add ppc_mma_hw.
(is-effective-target-keyword): Add ppc_mma_hw.
* gcc.target/powerpc/mma-supported.c: New file.
* gcc.target/powerpc/mma-single-test.c: Require ppc_mma_hw.
* gcc.target/powerpc/mma-double-test.c: Require ppc_mma_hw.
---
 .../gcc.target/powerpc/mma-double-test.c  |  1 +
 .../gcc.target/powerpc/mma-single-test.c  |  1 +
 .../gcc.target/powerpc/mma-supported.c| 24 +
 gcc/testsuite/lib/target-supports.exp | 27 +++
 4 files changed, 53 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/mma-supported.c

diff --git a/gcc/testsuite/gcc.target/powerpc/mma-double-test.c 
b/gcc/testsuite/gcc.target/powerpc/mma-double-test.c
index 9ba0010978f..ac84ae30004 100755
--- a/gcc/testsuite/gcc.target/powerpc/mma-double-test.c
+++ b/gcc/testsuite/gcc.target/powerpc/mma-double-test.c
@@ -1,5 +1,6 @@
 /* { dg-do run } */
 /* { dg-require-effective-target power10_hw } */
+/* { dg-require-effective-target ppc_mma_hw } */
 /* { dg-options "-mdejagnu-cpu=power10 -O2" } */
 
 #include 
diff --git a/gcc/testsuite/gcc.target/powerpc/mma-single-test.c 
b/gcc/testsuite/gcc.target/powerpc/mma-single-test.c
index aa71fa7f0af..15369a64025 100755
--- a/gcc/testsuite/gcc.target/powerpc/mma-single-test.c
+++ b/gcc/testsuite/gcc.target/powerpc/mma-single-test.c
@@ -1,5 +1,6 @@
 /* { dg-do run } */
 /* { dg-require-effective-target power10_hw } */
+/* { dg-require-effective-target ppc_mma_hw } */
 /* { dg-options "-mdejagnu-cpu=power10 -O2" } */
 
 #include 
diff --git a/gcc/testsuite/gcc.target/powerpc/mma-supported.c 
b/gcc/testsuite/gcc.target/powerpc/mma-supported.c
new file mode 100644
index 000..64943e362a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/mma-supported.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ppc_mma_hw } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+/* This test will only run when the ppc_mma_hw test passes.  If that
+   test passes, then we expect to see that mma feature is supported.
+   If this is not the case, then the test environment has problems. */
+
+#include 
+#include 
+
+int
+main (int argc, char *argv[])
+{
+  int ret = 0;
+#ifdef __BUILTIN_CPU_SUPPORTS__
+  if ( !__builtin_cpu_supports ("mma"))
+{
+  printf ("Error: __builtin_cpu_supports says mma not supported, but 
ppc_mma_hw test passed.\n");
+  ret++;
+}
+#endif
+  return ret;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index aeb0351073d..04f6db53eca 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2234,6 +2234,31 @@ proc check_power10_hw_available { } {
 }]
 }
 
+# Return 1 if the target supports executing MMA instructions, 0 otherwise.
+# Cache the result.  It is assumed that if a simulator does not support the
+# MMA instructions, that it will generate an error and this test will fail.
+
+proc check_ppc_mma_hw_available { } {
+return [check_cached_effective_target ppc_mma_hw_available {
+   check_runtime_nocache ppc_mma_hw_available {
+   #include 
+   typedef double v4sf_t __attribute__ ((vector_size (16)));
+
+   int main()
+   {
+   __vector_quad acc0;
+   v4sf_t result[4];
+   result[0][0] = 1.0;
+   __builtin_mma_xxsetaccz ();
+   __builtin_mma_disassemble_acc (result, );
+   if ( result[0][0] != 0.0 )
+   return 1;
+   return 0;
+   }
+   } "-mcpu=power10"
+}]
+}
+
 # Return 1 if the target supports executing __float128 on PowerPC via software
 # emulation, 0 otherwise.  Cache the result.
 
@@ -7836,6 +7861,7 @@ proc is-effective-target { arg } {
  "gc_sections"{ set selected [check_gc_sections_available] }
  "cxa_atexit" { set selected [check_cxa_atexit_available] }
  "power10_hw" { set selected [check_power10_hw_available] }
+ "ppc_mma_hw" { set selected [check_ppc_mma_hw_available] }
  default  { error "unknown effective target keyword `$arg'" }
}
 }
@@ -7865,6 +7891,7 @@ proc is-effective-target-keyword { arg } {
  "named_sections" { return 1 }
  "gc_sections"{ return 1 }
  "cxa_atexit" { return 1 }
+ "ppc_mma_hw" { return 1 }
  default  { return 0 }
}
 }
-- 
2.17.1



[PATCH] x86: Require Linux target for PR target/93492 tests

2020-07-10 Thread H.J. Lu via Gcc-patches
Since -fpatchable-function-entry is only supported on Linux and used by
Linux kernel, require Linux target for PR target/93492 tests.

PR target/93492
* gcc.target/i386/pr93492-1.c: Require Linux target.
* gcc.target/i386/pr93492-2.c: Likewise.
* gcc.target/i386/pr93492-3.c: Likewise.
* gcc.target/i386/pr93492-4.c: Likewise.
* gcc.target/i386/pr93492-5.c: Likewise.
---
 gcc/testsuite/gcc.target/i386/pr93492-1.c | 2 +-
 gcc/testsuite/gcc.target/i386/pr93492-2.c | 2 +-
 gcc/testsuite/gcc.target/i386/pr93492-3.c | 2 +-
 gcc/testsuite/gcc.target/i386/pr93492-4.c | 2 +-
 gcc/testsuite/gcc.target/i386/pr93492-5.c | 3 +--
 5 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/gcc.target/i386/pr93492-1.c 
b/gcc/testsuite/gcc.target/i386/pr93492-1.c
index f978d2e5220..7a82d0c68e1 100644
--- a/gcc/testsuite/gcc.target/i386/pr93492-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr93492-1.c
@@ -1,4 +1,4 @@
-/* { dg-do "compile" } */
+/* { dg-do "compile" { target *-*-linux* } } */
 /* { dg-options "-O1 -fcf-protection -mmanual-endbr" } */
 /* { dg-final { check-function-bodies "**" "" } } */
 
diff --git a/gcc/testsuite/gcc.target/i386/pr93492-2.c 
b/gcc/testsuite/gcc.target/i386/pr93492-2.c
index ec26d4cc367..3d67095fd10 100644
--- a/gcc/testsuite/gcc.target/i386/pr93492-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr93492-2.c
@@ -1,4 +1,4 @@
-/* { dg-do "compile" } */
+/* { dg-do "compile" { target *-*-linux* } } */
 /* { dg-options "-O1 -fcf-protection -mmanual-endbr 
-fasynchronous-unwind-tables" } */
 
 /* Test the placement of the .LPFE1 label.  */
diff --git a/gcc/testsuite/gcc.target/i386/pr93492-3.c 
b/gcc/testsuite/gcc.target/i386/pr93492-3.c
index 1f03c627120..52a19e51513 100644
--- a/gcc/testsuite/gcc.target/i386/pr93492-3.c
+++ b/gcc/testsuite/gcc.target/i386/pr93492-3.c
@@ -1,4 +1,4 @@
-/* { dg-do "compile" } */
+/* { dg-do "compile" { target *-*-linux* } } */
 /* { dg-require-effective-target mfentry } */
 /* { dg-options "-O1 -fcf-protection -mmanual-endbr -mfentry -pg 
-fasynchronous-unwind-tables" } */
 
diff --git a/gcc/testsuite/gcc.target/i386/pr93492-4.c 
b/gcc/testsuite/gcc.target/i386/pr93492-4.c
index d193df8e66d..8f205c345b8 100644
--- a/gcc/testsuite/gcc.target/i386/pr93492-4.c
+++ b/gcc/testsuite/gcc.target/i386/pr93492-4.c
@@ -1,4 +1,4 @@
-/* { dg-do "compile" } */
+/* { dg-do "compile" { target *-*-linux* } } */
 /* { dg-options "-O1 -fpatchable-function-entry=1 
-fasynchronous-unwind-tables" } */
 
 /* Test the placement of the .LPFE1 label.  */
diff --git a/gcc/testsuite/gcc.target/i386/pr93492-5.c 
b/gcc/testsuite/gcc.target/i386/pr93492-5.c
index d04077c6007..fcf4ad43aa2 100644
--- a/gcc/testsuite/gcc.target/i386/pr93492-5.c
+++ b/gcc/testsuite/gcc.target/i386/pr93492-5.c
@@ -1,5 +1,4 @@
-/* { dg-do "compile" } */
-/* { dg-require-effective-target mfentry } */
+/* { dg-do "compile" { target *-*-linux* } } */
 /* { dg-options "-O1 -fpatchable-function-entry=1 -mfentry -pg 
-fasynchronous-unwind-tables" } */
 
 /* Test the placement of the .LPFE1 label.  */
-- 
2.26.2



Re: Ping Re: c: Add C2X BOOL_MAX and BOOL_WIDTH to limits.h

2020-07-10 Thread Jeff Law via Gcc-patches
On Thu, 2020-07-09 at 15:40 +, Joseph Myers wrote:
> Ping for this limits.h patch 
> ;.
OK.

jeff



Re: [PATCH] rs6000: Add execution tests for mma builtins [v4]

2020-07-10 Thread Segher Boessenkool
Hi!

On Fri, Jul 10, 2020 at 03:49:02PM -0500, Aaron Sawdey via Gcc-patches wrote:
> This patch adds execution tests that use the MMA builtins and
> check for the right answer, and new tests that checks whether
> __builtin_cpu_supports and __builtin_cpu_is return sane
> answers for power10.

> 2020-06-30  Rajalakshmi Srinivasaraghavan  
>   Aaron Sawdey  
> 
> gcc/testsuite/
>   * gcc.target/powerpc/p10-identify.c: New file.
>   * gcc.target/powerpc/p10-arch31.c: New file.
>   * gcc.target/powerpc/mma-single-test.c: New file.
>   * gcc.target/powerpc/mma-double-test.c: New file.

Okay for trunk, and for GCC 10 backport as well.  Thanks!


Segher


Re: [PATCH 4/6] Testsuite: Make it easier to debug environment setting functions

2020-07-10 Thread Jeff Law via Gcc-patches
On Thu, 2020-07-09 at 10:56 +0100, Tamar Christina wrote:
> Hi All,
> 
> This adds verbose output to dg-set-compiler-env-var and dg-set-target-env-var
> so you can actually see what they're setting when you add -v -v.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
> 
> Ok for master?
> 
> Thanks,
> Tamar
> 
> gcc/testsuite/ChangeLog:
> 
>   * lib/gcc-dg.exp (dg-set-compiler-env-var, dg-set-target-env-var): Add
>   verbose output.
OK
jeff



Re: [PATCH 5/6] Docs: Document environment setting directives for testsuite

2020-07-10 Thread Jeff Law via Gcc-patches
On Thu, 2020-07-09 at 10:57 +0100, Tamar Christina wrote:
> Hi All,
> 
> This document some of the existing DejaGnu directives to modify
> environment variables before test or compiler invocations.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
> 
> Ok for master?
> 
> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
>   * doc/sourcebuild.texi (dg-set-compiler-env-var,
>   dg-set-target-env-var): Document.
OK
jeff



[PATCH] rs6000: Add execution tests for mma builtins [v4]

2020-07-10 Thread Aaron Sawdey via Gcc-patches
This patch adds execution tests that use the MMA builtins and
check for the right answer, and new tests that checks whether
__builtin_cpu_supports and __builtin_cpu_is return sane
answers for power10.

I've now cleaned up and separated things out so there are 4 test cases:
* MMA single precision execution test
* MMA double precision execution test
* test that if effective-target is power10_hw, __builtin_cpu_is("power10")
  is also true.
* test that if effective-target is power10_hw,
  __builtin_cpu_supports("arch_3_1") is also true.

This establishes that the test environment correctly identifies itself,
and that it can execute MMA code and get the right answer.

A future patch will add an effective-target test for powerpc_mma_hw,
which these mma tests will also need to check for.

OK for trunk and backport to 10?

2020-06-30  Rajalakshmi Srinivasaraghavan  
Aaron Sawdey  

gcc/testsuite/
* gcc.target/powerpc/p10-identify.c: New file.
* gcc.target/powerpc/p10-arch31.c: New file.
* gcc.target/powerpc/mma-single-test.c: New file.
* gcc.target/powerpc/mma-double-test.c: New file.
---
 .../gcc.target/powerpc/mma-double-test.c  | 185 +
 .../gcc.target/powerpc/mma-single-test.c  | 193 ++
 gcc/testsuite/gcc.target/powerpc/p10-arch31.c |  25 +++
 .../gcc.target/powerpc/p10-identify.c |  26 +++
 4 files changed, 429 insertions(+)
 create mode 100755 gcc/testsuite/gcc.target/powerpc/mma-double-test.c
 create mode 100755 gcc/testsuite/gcc.target/powerpc/mma-single-test.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/p10-arch31.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/p10-identify.c

diff --git a/gcc/testsuite/gcc.target/powerpc/mma-double-test.c 
b/gcc/testsuite/gcc.target/powerpc/mma-double-test.c
new file mode 100755
index 000..9ba0010978f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/mma-double-test.c
@@ -0,0 +1,185 @@
+/* { dg-do run } */
+/* { dg-require-effective-target power10_hw } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+#include 
+#include 
+#include 
+
+typedef unsigned char vec_t __attribute__ ((vector_size (16)));
+typedef double v4sf_t __attribute__ ((vector_size (16)));
+#define SAVE_ACC(ACC, ldc, J)  \
+ __builtin_mma_disassemble_acc (result, ACC); \
+ rowC = (v4sf_t *) [0*ldc+J]; \
+  rowC[0] += result[3] ; \
+  rowC = (v4sf_t *) [1*ldc+J]; \
+  rowC[0] += result[2] ; \
+  rowC = (v4sf_t *) [2*ldc+J]; \
+  rowC[0] += result[1] ; \
+  rowC = (v4sf_t *) [3*ldc+J]; \
+ rowC[0] += result[0] ;
+
+void
+MMA (int m, int n, int k, double *A, double *B, double *C)
+{
+  __vector_quad acc0, acc1, acc2, acc3, acc4, acc5, acc6, acc7;
+  v4sf_t result[4];
+  v4sf_t *rowC;
+  for (int l = 0; l < n; l += 4)
+{
+  double *CO;
+  double *AO;
+  AO = A;
+  CO = C;
+  C += m * 4;
+  for (int j = 0; j < m; j += 16)
+   {
+ double *BO = B;
+ __builtin_mma_xxsetaccz ();
+ __builtin_mma_xxsetaccz ();
+ __builtin_mma_xxsetaccz ();
+ __builtin_mma_xxsetaccz ();
+ __builtin_mma_xxsetaccz ();
+ __builtin_mma_xxsetaccz ();
+ __builtin_mma_xxsetaccz ();
+ __builtin_mma_xxsetaccz ();
+ unsigned long i;
+
+ for (i = 0; i < k; i++)
+   {
+ vec_t *rowA = (vec_t *) & AO[i * 16];
+ __vector_pair rowB;
+ vec_t *rb = (vec_t *) & BO[i * 4];
+ __builtin_mma_assemble_pair (, rb[1], rb[0]);
+ __builtin_mma_xvf64gerpp (, rowB, rowA[0]);
+ __builtin_mma_xvf64gerpp (, rowB, rowA[1]);
+ __builtin_mma_xvf64gerpp (, rowB, rowA[2]);
+ __builtin_mma_xvf64gerpp (, rowB, rowA[3]);
+ __builtin_mma_xvf64gerpp (, rowB, rowA[4]);
+ __builtin_mma_xvf64gerpp (, rowB, rowA[5]);
+ __builtin_mma_xvf64gerpp (, rowB, rowA[6]);
+ __builtin_mma_xvf64gerpp (, rowB, rowA[7]);
+   }
+ SAVE_ACC (, m, 0);
+ SAVE_ACC (, m, 4);
+ SAVE_ACC (, m, 2);
+ SAVE_ACC (, m, 6);
+ SAVE_ACC (, m, 8);
+ SAVE_ACC (, m, 12);
+ SAVE_ACC (, m, 10);
+ SAVE_ACC (, m, 14);
+ AO += k * 16;
+ BO += k * 4;
+ CO += 16;
+   }
+  B += k * 4;
+}
+}
+
+void
+init (double *matrix, int row, int column)
+{
+  for (int j = 0; j < column; j++)
+{
+  for (int i = 0; i < row; i++)
+   {
+ matrix[j * row + i] = (i * 16 + 2 + j) / 0.123;
+   }
+}
+}
+
+void
+init0 (double *matrix, double *matrix1, int row, int column)
+{
+  for (int j = 0; j < column; j++)
+for (int i = 0; i < row; i++)
+  matrix[j * row + i] = matrix1[j * row + i] = 0;
+}
+
+
+void
+print (const char *name, const double *matrix, int row, int column)
+{
+  printf ("Matrix %s has %d rows and %d columns:\n", name, row, 

Re: [PATCH] Improve shrink-wrapping debug output

2020-07-10 Thread Jeff Law via Gcc-patches
On Sat, 2020-07-04 at 16:07 +0300, Alexander Popov wrote:
> Currently if requires_stack_frame_p() returns true for some insn,
> the shrink-wrapping debug output contains only the number of a block
> containing that insn.
> 
> But it is very useful to see the particular insn that requires the
> prologue. Let's call print_rtl_single to display that insn in the
> following pass dump.
> 
> 2020-07-04 Alexander Popov 
> 
> gcc/ChangeLog:
> 
>   * shrink-wrap.c (try_shrink_wrapping): Improve debug output.
Thanks.  I've installed this on the trunk.

jeff
> 



Re: [PATCH, part 2] PR fortran/95980 - ICE in get_unique_type_string, at fortran/class.c:485

2020-07-10 Thread Thomas Koenig via Gcc-patches

Hi Harald,


This is not a regression, so I don't think we will need a backport.


understood.

On the downside, another patch I was working on unfortunately partially overlaps
with the present one in resolve.c.  At some point, there will be a conflict
between the work involved in either producing a clean but incomplete backport or
not backporting at all.


That, I think, would be a good reason for backporting.


(I know, I've reverted already a bad backport to 8/9 because some other 
backports
were missing.  But that's life^Wfun.)


And don't we all know it! :-)

Regards

Thomas



Re: [PATCH] contrib: Don't pass wget options to curl

2020-07-10 Thread Jeff Law via Gcc-patches
On Tue, 2020-07-07 at 18:44 -0400, Mike Nolta via Gcc-patches wrote:
> This is a harmless bug, as the script still works, but curl's '-O'
> option isn't the same as wget's.
> 
> contrib/ChangeLog:
> 
>   * download_prerequisites: Don't pass wget options to curl.
THanks.  I've pushed this to the trunk.

jeff
> 



Aw: Re: [PATCH, part 2] PR fortran/95980 - ICE in get_unique_type_string, at fortran/class.c:485

2020-07-10 Thread Harald Anlauf
Hi Thomas,

> This is not a regression, so I don't think we will need a backport.

understood.

On the downside, another patch I was working on unfortunately partially overlaps
with the present one in resolve.c.  At some point, there will be a conflict
between the work involved in either producing a clean but incomplete backport or
not backporting at all.

(I know, I've reverted already a bad backport to 8/9 because some other 
backports
were missing.  But that's life^Wfun.)

Thanks,
Harald



libgo patch committed: Update to Go 1.14.4 release

2020-07-10 Thread Ian Lance Taylor via Gcc-patches
This patch updates libgo to the Go 1.14.4 release.  Bootstrapped and
ran Go testsuite on x86_64-pc-linux-gnu.  Committed to trunk and GCC
10 branch.

Ian
2b6d99468d4d988fd5f5ea3e9be41a3dc95a1291
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index ecef60400cc..64b13f410e0 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-30674246ef60ab74566a21f362a7de7a09b99955
+2ad0970e9da95024110cd3244e9e21313af70a5f
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/MERGE b/libgo/MERGE
index 8cae45f6b8e..07547d064a1 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-96745b980cfde139e8611772e2bc0c59a8e6cdf7
+83b181c68bf332ac7948f145f33d128377a09c42
 
 The first line of this file holds the git revision number of the
 last merge done from the master library sources.
diff --git a/libgo/VERSION b/libgo/VERSION
index 864916ef499..d8281a2e996 100644
--- a/libgo/VERSION
+++ b/libgo/VERSION
@@ -1 +1 @@
-go1.14.2
+go1.14.4
diff --git a/libgo/go/cmd/cgo/gcc.go b/libgo/go/cmd/cgo/gcc.go
index 310316bdda4..e38972913be 100644
--- a/libgo/go/cmd/cgo/gcc.go
+++ b/libgo/go/cmd/cgo/gcc.go
@@ -2082,6 +2082,10 @@ var goIdent = make(map[string]*ast.Ident)
 // that may contain a pointer. This is used for cgo pointer checking.
 var unionWithPointer = make(map[ast.Expr]bool)
 
+// anonymousStructTag provides a consistent tag for an anonymous struct.
+// The same dwarf.StructType pointer will always get the same tag.
+var anonymousStructTag = make(map[*dwarf.StructType]string)
+
 func (c *typeConv) Init(ptrSize, intSize int64) {
c.ptrSize = ptrSize
c.intSize = intSize
@@ -2430,8 +2434,12 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos 
token.Pos, parent string) *Typ
break
}
if tag == "" {
-   tag = "__" + strconv.Itoa(tagGen)
-   tagGen++
+   tag = anonymousStructTag[dt]
+   if tag == "" {
+   tag = "__" + strconv.Itoa(tagGen)
+   tagGen++
+   anonymousStructTag[dt] = tag
+   }
} else if t.C.Empty() {
t.C.Set(dt.Kind + " " + tag)
}
diff --git a/libgo/go/encoding/json/decode.go b/libgo/go/encoding/json/decode.go
index b43484692e1..b60e2bb0b2c 100644
--- a/libgo/go/encoding/json/decode.go
+++ b/libgo/go/encoding/json/decode.go
@@ -1217,6 +1217,11 @@ func (d *decodeState) unquoteBytes(s []byte) (t []byte, 
ok bool) {
if r == -1 {
return s, true
}
+   // Only perform up to one safe unquote for each re-scanned string
+   // literal. In some edge cases, the decoder unquotes a literal a second
+   // time, even after another literal has been re-scanned. Thus, only the
+   // first unquote can safely use safeUnquote.
+   d.safeUnquote = 0
 
b := make([]byte, len(s)+2*utf8.UTFMax)
w := copy(b, s[0:r])
diff --git a/libgo/go/encoding/json/decode_test.go 
b/libgo/go/encoding/json/decode_test.go
index 498bd97b46e..a49181e9823 100644
--- a/libgo/go/encoding/json/decode_test.go
+++ b/libgo/go/encoding/json/decode_test.go
@@ -2419,7 +2419,7 @@ func (m *textUnmarshalerString) UnmarshalText(text 
[]byte) error {
return nil
 }
 
-// Test unmarshal to a map, with map key is a user defined type.
+// Test unmarshal to a map, where the map key is a user defined type.
 // See golang.org/issues/34437.
 func TestUnmarshalMapWithTextUnmarshalerStringKey(t *testing.T) {
var p map[textUnmarshalerString]string
@@ -2428,6 +2428,35 @@ func TestUnmarshalMapWithTextUnmarshalerStringKey(t 
*testing.T) {
}
 
if _, ok := p["foo"]; !ok {
-   t.Errorf(`Key "foo" is not existed in map: %v`, p)
+   t.Errorf(`Key "foo" does not exist in map: %v`, p)
+   }
+}
+
+func TestUnmarshalRescanLiteralMangledUnquote(t *testing.T) {
+   // See golang.org/issues/38105.
+   var p map[textUnmarshalerString]string
+   if err := Unmarshal([]byte(`{"开源":"12345开源"}`), ); err != nil {
+   t.Fatalf("Unmarshal unexpected error: %v", err)
+   }
+   if _, ok := p["开源"]; !ok {
+   t.Errorf(`Key "开源" does not exist in map: %v`, p)
+   }
+
+   // See golang.org/issues/38126.
+   type T struct {
+   F1 string `json:"F1,string"`
+   }
+   t1 := T{"aaa\tbbb"}
+
+   b, err := Marshal(t1)
+   if err != nil {
+   t.Fatalf("Marshal unexpected error: %v", err)
+   }
+   var t2 T
+   if err := Unmarshal(b, ); err != nil {
+   t.Fatalf("Unmarshal unexpected error: %v", err)
+   }
+   if t1 != t2 {
+   t.Errorf("Marshal and Unmarshal roundtrip mismatch: want %q got 
%q", t1, t2)
}
 }
diff --git 

Re: [PATCH] aarch64: Change costs for TX2 to expose more vectorization opportunities

2020-07-10 Thread Richard Sandiford
Anton Youdkevitch  writes:
> Richard,
>
> Can you approve the backporting of the patch to GCC10?
> Also, since I don't have the commit permission can you push
> it if approved?

Yeah, that's fine.  Now pushed there too.

Thanks,
Richard


Re: [PATCH] implement pre-c++20 contracts

2020-07-10 Thread Jeff Chapman via Gcc-patches
Hello again :)

Attached is a new squashed revision of the patch sans ChangeLogs. The
current work is now being done on github:
https://github.com/lock3/gcc/tree/contracts-jac-alt

Please let me know if there's a better way to share revisions.

>>> +  /* Check that assertions are null statements.  */
>>> +  if (attribute_contract_assert_p (contract_attrs))
>>> +if (token->type != CPP_SEMICOLON)
>>> +  error_at (token->location, "assertions must be followed by
>>> %<;%>");
>>
>> Better I think to handle this further down where [[fallthrough]] has the
>> same requirement.
>>
>
> I'm wondering if it would be better to move [[fallthrough]] up, since
> the later check is not always executed and in the case of [[assert]] we
> actually need to error.
>
>   [[fallthrough]] int x;
>
> for instance just gets a generic 'attribute ignored' warning. I'm not
> entirely happy with how we prevent assert/pre/post from appearing in
> invalid locations in general which I'll try to improve. If you have
> concrete suggestions please let me know.

Improvements have been made to handling contract attributes appearing in
places they don't belong. Any feedback about moving the logic dealing
with [[fallthrough]]?


>> Why not leave the function the user declared as the unchecked function
>> (just changing some linkage properties) and create a new function for
>> the checked wrapper?
>>
>
> This revision of the patch does not include changes to the
> checked/unchecked function split. We're exploring an alternative rewrite
> that leaves the original function declaration alone and should address
> or sidestep a number of these comments.
>
> Specifically, we're exploring generating pre and post functions with
> calls to them in the correct places (upon entering a guarded function,
> wrapping the return value):
>
>   int f(int n) [[ pre: n > 0 ]] [[ post r: r < 0 ]] { return -n; }
>
> turns into
>
>   void __pre_f(int n) { [[ assert: n > 0 ]]; }
>   int __post_f(int r) { [[ assert: r < 0 ]]; return r; }
>   int f(int n) {
> __pre_f(n);
> return __post_f(-n);
>   }
>
> with whatever hints we can give to optimize this as much as possible.

This is the main change since the last submission. We now leave the
original decl intact and instead generate a pre and post function.
Naming and mangling of these pre/post functions needs addressed.

Beyond that, more cleanup has been done. There's still outstanding
cleanup work, mostly around investigating and improving performance.
Feedback on the main direction of the patch would be appreciated, and
any specific commentary or directions of investigation would be helpful.


>>> +/* Return the source text between two locations.  */
>>> +
>>> +static char *
>>> +get_source (location_t start, location_t end)
>>
>> This seems like it belongs in libcpp.  It also needs to
>>
>
> This has been moved to input since it uses input functions, but needs
> more work. Was there another comment you had that cutoff?
>
> ...snip...
>
>>> +  /* We never want to accidentally instantiate templates.  */
>>> +  if (code == TEMPLATE_DECL)
>>> +return *tp; /* FIXME? */
>>
>> This seems unlikely to have the desired effect; we should see template
>> instantiations as FUNCTION_DECL or VAR_DECL.  I'm also not sure what the
>> cp_tree_defined_p check is trying to do; surely using defined functions
>> and variables can also lead to runtime code?
>>
>
> This is an result of the transform we do for axioms when they're enabled
> that you may know of a better way to do. Essentially we turn this:
>
>   [[ assert axiom: f() > 0 ]];
>
> into this:
>
>   if (!(f() > 0))
> __builtin_unreachable ();
>
> but we potentially run into issues later if f isn't (yet) defined or is
> defined in a different translation unit, such as constexpr time. We're
> avoiding those errors by generating a nop if there's any chance can't be
> evaluated. We'd prefer something like
>
>   __builtin_assume (f() > 0);
>
> where the condition is simply ignored if enough information isn't
> present to affect codegen. Is there a better way to handle this?
>
> I should mention that there are likely significant further changes
> around axiom coming down the pike that may tie into or replace the
> "is defined" check. Specifically for expressions that _cannot_ be
> defined rather than ones that are simply not yet defined.
>

Not much has changed yet regarding axiom, but if you have any
suggestions for handling any of the above then I'm all ears.


0001-Implement-pre-c-20-contracts.patch.gz
Description: GNU Zip compressed data


Re: [PATCH][RFC] vector creation from two parts of two vectors produces TBL rather than ins (PR93720)

2020-07-10 Thread Dmitrij Pochepko
Hi,

thank you for reviewing it.

Please check updated version(attached) with all comments addressed.

Thanks,
Dmitrij

On Tue, Jun 23, 2020 at 06:10:52PM +0100, Richard Sandiford wrote:
...
> 
> I think it would be better to test this as part of the loop below.
> 
done

...
> I think it'd be better to generate the target instruction directly.
> We can do that by replacing:
> 
> (define_insn "*aarch64_simd_vec_copy_lane"
> 
> with:
> 
> (define_insn "@aarch64_simd_vec_copy_lane"
> 
> then using the expand_insn interface to create an instance of
> code_for_aarch64_simd_vec_copy_lane (mode).
done

...
> 
> > +/* { dg-final { scan-assembler-times "\[ \t\]*ins\[ \t\]+v\[0-9\]+\.s" 4 } 
> > } */
> 
> Same comment as the other patch about using {…} regexp quoting.
> 
done
>From 8e7cfa2da407171a30d1e152f0e0f4be399d571e Mon Sep 17 00:00:00 2001
From: Dmitrij Pochepko 
Date: Fri, 10 Jul 2020 20:37:17 +0300
Subject: [PATCH] vector creation from two parts of two vectors produces TBL
 rather than ins (PR 93720)

The following patch enables vector permutations optimization by trying to use ins instruction instead of slow and generic tbl.

example:

vector float f0(vector float a, vector float b)
{
  return __builtin_shuffle (a, a, (vector int){3, 1, 2, 3});
}

was compiled into:
...
	adrpx0, .LC0
	ldr q1, [x0, #:lo12:.LC0]
	tbl v0.16b, {v0.16b}, v1.16b
...

and after patch:
...
	ins v0.s[0], v0.s[3]
...

bootstrapped and tested on aarch64-linux-gnu with no regressions

gcc/ChangeLog:

2020-07-10 Andrew Pinski   

	PR gcc/93720

	* gcc/config/aarch64/aarch64.c (aarch64_evpc_ins): New function
	* gcc/config/aarch64/aarch64-simd.md (aarch64_simd_vec_copy_lane): changed name prefix

gcc/testsuite/ChangeLog:

2020-07-10  Andrew Pinski   

	PR gcc/93720

	* gcc/testsuite/gcc.target/aarch64/vins-1.c: New test
	* gcc/testsuite/gcc.target/aarch64/vins-2.c: New test
	* gcc/testsuite/gcc.target/aarch64/vins-3.c: New test

Co-Authored-By: Dmitrij Pochepko
---
 gcc/config/aarch64/aarch64-simd.md|  2 +-
 gcc/config/aarch64/aarch64.c  | 82 +++
 gcc/testsuite/gcc.target/aarch64/vins-1.c | 23 +
 gcc/testsuite/gcc.target/aarch64/vins-2.c | 23 +
 gcc/testsuite/gcc.target/aarch64/vins-3.c | 23 +
 5 files changed, 152 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/vins-1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/vins-2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/vins-3.c

diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 9f0e2bd..11ebf5b 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -958,7 +958,7 @@
   [(set_attr "type" "neon_ins, neon_from_gp, neon_load1_one_lane")]
 )
 
-(define_insn "*aarch64_simd_vec_copy_lane"
+(define_insn "@aarch64_simd_vec_copy_lane"
   [(set (match_operand:VALL_F16 0 "register_operand" "=w")
 	(vec_merge:VALL_F16
 	(vec_duplicate:VALL_F16
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 9b31743..7544fd8 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -20594,6 +20594,86 @@ aarch64_evpc_sel (struct expand_vec_perm_d *d)
   return true;
 }
 
+/* Recognize patterns suitable for the INS instructions.  */
+static bool
+aarch64_evpc_ins (struct expand_vec_perm_d *d)
+{
+  machine_mode mode = d->vmode;
+  unsigned HOST_WIDE_INT nelt;
+
+  if (d->vec_flags != VEC_ADVSIMD)
+return false;
+
+  unsigned int encoded_nelts = d->perm.encoding ().encoded_nelts ();
+  for (unsigned int i = 0; i < encoded_nelts; ++i)
+if (!d->perm[i].is_constant ())
+  return false;
+
+  /* to_constant is safe since this routine is specific to Advanced SIMD
+ vectors.  */
+  nelt = d->perm.length ().to_constant ();
+  rtx insv = d->op0;
+
+  HOST_WIDE_INT idx = -1;
+
+  for (unsigned HOST_WIDE_INT i = 0; i < nelt; i ++)
+{
+  poly_int64 elt = d->perm[i];
+  if (!elt.is_constant ())
+	return false;
+  if (elt.to_constant () == (HOST_WIDE_INT) i)
+	continue;
+  if (idx != -1)
+	{
+	  idx = -1;
+	  break;
+	}
+  idx = i;
+}
+
+  if (idx == -1)
+{
+  insv = d->op1;
+  for (unsigned HOST_WIDE_INT i = 0; i < nelt; i ++)
+	{
+	  if (d->perm[i].to_constant () == (HOST_WIDE_INT) (i + nelt))
+	continue;
+	  if (idx != -1)
+	return false;
+	  idx = i;
+	}
+
+  if (idx == -1)
+	return false;
+}
+
+  if (d->testing_p)
+return true;
+
+  gcc_assert (idx != -1);
+
+  unsigned extractindex = d->perm[idx].to_constant ();
+  rtx extractv = d->op0;
+  if (extractindex >= nelt)
+{
+  extractv = d->op1;
+  extractindex -= nelt;
+}
+  gcc_assert (extractindex < nelt);
+
+  emit_move_insn (d->target, insv);
+  insn_code icode = code_for_aarch64_simd_vec_copy_lane (mode);
+  expand_operand ops[5];
+  create_output_operand ([0], d->target, mode);
+  create_input_operand 

Re: [PATCH] Fortran : ICE in gfc_find_array_ref(): No ref found PR95981

2020-07-10 Thread Thomas Koenig via Gcc-patches

Hi Mark,


Fortran  :  ICE in gfc_find_array_ref(): No ref found PR95981


OK for master.  With regards to backporting, copy & paste my
remarks from the previous e-mails :-)

Best regards

Thomas


Re: [PATCH] Fortran : Implicitly type parameter causes an invalid error, PR96038

2020-07-10 Thread Thomas Koenig via Gcc-patches

Am 09.07.20 um 10:00 schrieb Mark Eggleston:
Please find attached patch for fix PR.  The original patch was provided 
by Steve Kargl in the initial problem report.



OK to commit to master and backport?


OK for master.  Same remark as just - not a regression, so if you
decide to backport, please wait until 10.2 is safe :-)

Best regards

Thomas


Re: [PATCH] Fortran : accepts pointer initialization of DT dummy args, PR45337

2020-07-10 Thread Thomas Koenig via Gcc-patches

Am 09.07.20 um 09:51 schrieb Mark Eggleston:

Please find attached a fix for this PR.

I think the discussion of intent muddied the waters for this PR. As I 
understand it initialisation of variables implies the save attribute. 
The save attribute is incompatible with the dummy attribute so an error 
should be output when initialisation is attempted for dummy variables.


Is this correct?


Yes, this is correct; this is C808:

# (R803) An initialization shall not appear if object-name is a dummy
# argument, a function result, an object in a named common block unless
#+ the type declaration is in a block data program unit, an object in
# blank common, an allocatable variable, or an automatic data object.


If so OK to commit and backport?


OK for master.  This is not a regression, so a backport is not needed.

If you do decide to backport, please wait until gcc 10 has reopened
after the release of 10.2, on the off chance that this does introduce
a regression.

Thanks for the patch!  It is always good to see the removal
of code result in a bug fix :-)

Best regards

Thomas


RE: [PATCH] arm: Treat GNU and Advanced SIMD vectors as distinct [PR92789, PR95726]

2020-07-10 Thread Kyrylo Tkachov


> -Original Message-
> From: Richard Sandiford 
> Sent: 10 July 2020 17:54
> To: gcc-patches@gcc.gnu.org
> Cc: ni...@redhat.com; Richard Earnshaw ;
> Ramana Radhakrishnan ; Kyrylo
> Tkachov 
> Subject: [PATCH] arm: Treat GNU and Advanced SIMD vectors as distinct
> [PR92789, PR95726]
> 
> This is an arm version of aarch64 patch r11-1741.  The approach
> is essentially identical, not much more than s/aarch64/arm/.
> 
> To recap, PR95726 is about template look-up for things like:
> 
> foo
> foo
> 
> The immediate cause of the problem is that the hash function usually
> returns different hashes for these types, yet the equality function
> thinks they are equal.  This then raises the question of how the types
> are supposed to be treated.
> 
> The answer we chose for AArch64 was that the GNU vector type should
> be treated as distinct from float32x4_t, but that each type should
> implicitly convert to the other.
> 
> This would mean that, as far as the PR is concerned, the hashing
> function is right to (sometimes) treat the types differently and
> the equality function is wrong to treat them as the same.
> 
> The most obvious way to enforce the type difference is to use a
> target-specific type attribute.  That on its own is enough to fix
> the PR.  The difficulty is deciding whether the knock-on effects
> are acceptable.
> 
> One obvious effect is that GCC then rejects:
> 
> typedef float vecf __attribute__((vector_size(16)));
> vecf x;
> float32x4_t  = x;
> 
> on the basis that the types are no longer reference-compatible.
> For AArch64 we took the approach that this was the correct behaviour.
> It is also consistent with current Clang.
> 
> A trickier question is whether:
> 
> vecf x;
> float32x4_t y;
> … c ? x : y …
> 
> should be valid, and if so, what its type should be [PR92789].
> As explained in the comment in the testcase, GCC and Clang both
> accepted this, but GCC chose the “then” type while Clang chose
> the “else” type.  This can lead to different mangling for (probably
> artificial) corner cases, as seen for “sel1” and “sel2” in the
> testcase.
> 
> Adding the attribute makes GCC reject the conditional expression
> as ambiguous.  For AArch64 we took the approach that this too is
> the correct behaviour, for the reasons described in the testcase.
> However, it does seem to have the potential to break existing code.
> 
> Tested on arm-linux-gnueabihf.  OK for master?  The backport will
> involve an arm version of:
> 
>   https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549614.html
> 

Ok. I'd like arm gcc to be consistent with aarch64 gcc for sure.
Thanks,
Kyrill

> Richard
> 
> 
> gcc/
>   PR target/92789
>   PR target/95726
>   * config/arm/arm.c (arm_attribute_table): Add
>   "Advanced SIMD type".
>   (arm_comp_type_attributes): Check that the "Advanced SIMD type"
>   attributes are equal.
>   * config/arm/arm-builtins.c: Include stringpool.h and
>   attribs.h.
>   (arm_mangle_builtin_vector_type): Use the mangling recorded
>   in the "Advanced SIMD type" attribute.
>   (arm_init_simd_builtin_types): Add an "Advanced SIMD type"
>   attribute to each Advanced SIMD type, using the mangled type
>   as the attribute's single argument.
> 
> gcc/testsuite/
>   PR target/92789
>   PR target/95726
>   * g++.target/arm/pr95726.C: New test.
> ---
>  gcc/config/arm/arm-builtins.c  | 35 ++
>  gcc/config/arm/arm.c   | 10 ++
>  gcc/testsuite/g++.target/arm/pr95726.C | 49
> ++
>  3 files changed, 79 insertions(+), 15 deletions(-)
>  create mode 100644 gcc/testsuite/g++.target/arm/pr95726.C
> 
> diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
> index f64742e6447..33e8015b140 100644
> --- a/gcc/config/arm/arm-builtins.c
> +++ b/gcc/config/arm/arm-builtins.c
> @@ -43,6 +43,8 @@
>  #include "sbitmap.h"
>  #include "stringpool.h"
>  #include "arm-builtins.h"
> +#include "stringpool.h"
> +#include "attribs.h"
> 
>  #define SIMD_MAX_BUILTIN_ARGS 7
> 
> @@ -1457,18 +1459,12 @@ arm_mangle_builtin_scalar_type (const_tree
> type)
>  static const char *
>  arm_mangle_builtin_vector_type (const_tree type)
>  {
> -  int i;
> -  int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
> -
> -  for (i = 0; i < nelts; i++)
> -if (arm_simd_types[i].mode ==  TYPE_MODE (type)
> - && TYPE_NAME (type)
> - && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
> - && DECL_NAME (TYPE_NAME (type))
> - && !strcmp
> -  (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
> -   arm_simd_types[i].name))
> -  return arm_simd_types[i].mangle;
> +  tree attrs = TYPE_ATTRIBUTES (type);
> +  if (tree attr = lookup_attribute ("Advanced SIMD type", attrs))
> +{
> +  tree mangled_name = TREE_VALUE (TREE_VALUE (attr));
> +  return IDENTIFIER_POINTER (mangled_name);
> +}
> 
>return NULL;
> 

Re: [PATCH] PR fortran/96086 - ICE in gfc_match_select_rank, at fortran/match.c:6645

2020-07-10 Thread Thomas Koenig via Gcc-patches

Am 06.07.20 um 22:11 schrieb Harald Anlauf:

More NULL pointer dereferences on invalid code, detected by Gerhard.

Regtested on x86_64-pc-linux-gnu.

OK for master?


OK.

This is actually a regression (does not occur with gcc-8), so if you
feel like it, feel free to backport this.  However, if you do that,
I would appreciate if you could wait until gcc10 is again in
normal regression fixing mode.

Thanks for the patch!

Best regards

Thomas


Re: [PATCH, part 2] PR fortran/95980 - ICE in get_unique_type_string, at fortran/class.c:485

2020-07-10 Thread Thomas Koenig via Gcc-patches

Hi Harald,


As Dominique pointed out in the PR, the committed patch (part 1) fixed only
one of the provided testcases, but not the original one.  That turned out
to be a long and winding road, requiring further checks for NULL pointer
dereferences.

The resulting attached changes have been regtested on x86_64-pc-linux-gnu
and confirmed on Darwin by Dominique (thanks!), see PR.

OK for master / where appropriate?


OK for master.

This is not a regression, so I don't think we will need a backport.

Best regards

Thomas


[patch, fortran] Fix PR 96018, wrong code caused by implicit_pure

2020-07-10 Thread Thomas Koenig via Gcc-patches

Hello world,

the attached patch fixes a 9/10/11 regression where we left over
an implicit_pure attribute when a non-implicit_pure procedure was
called.

The fix is explained in the ChangeLog.

If there is a quick review, please also indicate if you think it is
still suitable for gcc 10.2.  If the review comes later, then
it obviously will not be :-)  On the code side, this should be
fairly safe, because all we are doing is to be more defensive
about our optimizations.

OK for trunk/backporting?  This is not something I want to commit
without a review because it is not quite obvious and simple :-)

Best regards

Thomas

Fix handling of implicit_pure by checking if non-pure procedures are called.

Procedures are marked as implicit_pure if they fulfill the criteria of
pure procedures.  In this case, a procedure was not marked as not being
implicit_pure which called another procedure, which had not yet been
marked as not being implicit_impure.

Fixed by iterating over all procedures, setting callers of procedures
which are non-pure and non-implicit_pure as non-implicit_pure and
doing this until no more procedure has been changed.


gcc/fortran/ChangeLog:

2020-07-10  Thomas Koenig  

PR fortran/96018
* frontend-passes.c (gfc_check_externals): Adjust formatting.
(implicit_pure_call): New function.
(implicit_pure_expr): New function.
(gfc_fix_implicit_pure): New function.
* gfortran.h (gfc_fix_implicit_pure): New prototype.
* parse.c (translate_all_program_units): Call gfc_fix_implicit_pure.
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index 69f9ca64c97..4b1d3f2feda 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -5550,7 +5550,8 @@ gfc_check_externals0 (gfc_namespace *ns)
 
 /* Called routine.  */
 
-void gfc_check_externals (gfc_namespace *ns)
+void
+gfc_check_externals (gfc_namespace *ns)
 {
   gfc_clear_error ();
 
@@ -5565,3 +5566,76 @@ void gfc_check_externals (gfc_namespace *ns)
   gfc_errors_to_warnings (false);
 }
 
+/* Callback function. If there is a call to a subroutine which is
+   neither pure nor implicit_pure, unset the implicit_pure flag for
+   the caller and return -1.  */
+
+static int
+implicit_pure_call (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
+		void *sym_data)
+{
+  gfc_code *co = *c;
+  gfc_symbol *caller_sym;
+  symbol_attribute *a;
+
+  if (co->op != EXEC_CALL || co->resolved_sym == NULL)
+return 0;
+
+  a = >resolved_sym->attr;
+  if (a->intrinsic || a->pure || a->implicit_pure)
+return 0;
+
+  caller_sym = (gfc_symbol *) sym_data;
+  gfc_unset_implicit_pure (caller_sym);
+  return 1;
+}
+
+/* Callback function. If there is a call to a function which is
+   neither pure nor implicit_pure, unset the implicit_pure flag for
+   the caller and return 1.  */
+
+static int
+implicit_pure_expr (gfc_expr **e, int *walk ATTRIBUTE_UNUSED, void *sym_data)
+{
+  gfc_expr *expr = *e;
+  gfc_symbol *caller_sym;
+  gfc_symbol *sym;
+  symbol_attribute *a;
+
+  if (expr->expr_type != EXPR_FUNCTION || expr->value.function.isym)
+return 0;
+
+  sym = expr->symtree->n.sym;
+  a = >attr;
+  if (a->pure || a->implicit_pure)
+return 0;
+
+  caller_sym = (gfc_symbol *) sym_data;
+  gfc_unset_implicit_pure (caller_sym);
+  return 1;
+}
+
+/* Go through all procedures in the namespace and unset the
+   implicit_pure attribute for any procedure that calls something not
+   pure or implicit pure.  */
+
+bool
+gfc_fix_implicit_pure (gfc_namespace *ns)
+{
+  bool changed = false;
+  gfc_symbol *proc = ns->proc_name;
+
+  if (proc && proc->attr.flavor == FL_PROCEDURE && proc->attr.implicit_pure
+  && ns->code
+  && gfc_code_walker (>code, implicit_pure_call, implicit_pure_expr,
+			  (void *) ns->proc_name))
+changed = true;
+
+  for (ns = ns->contained; ns; ns = ns->sibling)
+{
+  if (gfc_fix_implicit_pure (ns))
+	changed = true;
+}
+
+  return changed;
+}
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 24c5101c4cb..264822ef9f8 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3623,6 +3623,7 @@ int gfc_expr_walker (gfc_expr **, walk_expr_fn_t, void *);
 int gfc_code_walker (gfc_code **, walk_code_fn_t, walk_expr_fn_t, void *);
 bool gfc_has_dimen_vector_ref (gfc_expr *e);
 void gfc_check_externals (gfc_namespace *);
+bool gfc_fix_implicit_pure (gfc_namespace *);
 
 /* simplify.c */
 
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 36715134a2c..d30208febb1 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -6447,6 +6447,11 @@ loop:
 
   gfc_resolve (gfc_current_ns);
 
+  /* Fix the implicit_pure attribute for those procedures who should
+ not have it.  */
+  while (gfc_fix_implicit_pure (gfc_current_ns))
+;
+
   /* Dump the parse tree if requested.  */
   if (flag_dump_fortran_original)
 gfc_dump_parse_tree (gfc_current_ns, stdout);
@@ -6492,6 +6497,23 @@ 

[PATCH] arm: Treat GNU and Advanced SIMD vectors as distinct [PR92789, PR95726]

2020-07-10 Thread Richard Sandiford
This is an arm version of aarch64 patch r11-1741.  The approach
is essentially identical, not much more than s/aarch64/arm/.

To recap, PR95726 is about template look-up for things like:

foo
foo

The immediate cause of the problem is that the hash function usually
returns different hashes for these types, yet the equality function
thinks they are equal.  This then raises the question of how the types
are supposed to be treated.

The answer we chose for AArch64 was that the GNU vector type should
be treated as distinct from float32x4_t, but that each type should
implicitly convert to the other.

This would mean that, as far as the PR is concerned, the hashing
function is right to (sometimes) treat the types differently and
the equality function is wrong to treat them as the same.

The most obvious way to enforce the type difference is to use a
target-specific type attribute.  That on its own is enough to fix
the PR.  The difficulty is deciding whether the knock-on effects
are acceptable.

One obvious effect is that GCC then rejects:

typedef float vecf __attribute__((vector_size(16)));
vecf x;
float32x4_t  = x;

on the basis that the types are no longer reference-compatible.
For AArch64 we took the approach that this was the correct behaviour.
It is also consistent with current Clang.

A trickier question is whether:

vecf x;
float32x4_t y;
… c ? x : y …

should be valid, and if so, what its type should be [PR92789].
As explained in the comment in the testcase, GCC and Clang both
accepted this, but GCC chose the “then” type while Clang chose
the “else” type.  This can lead to different mangling for (probably
artificial) corner cases, as seen for “sel1” and “sel2” in the
testcase.

Adding the attribute makes GCC reject the conditional expression
as ambiguous.  For AArch64 we took the approach that this too is
the correct behaviour, for the reasons described in the testcase.
However, it does seem to have the potential to break existing code.

Tested on arm-linux-gnueabihf.  OK for master?  The backport will
involve an arm version of:

  https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549614.html

Richard


gcc/
PR target/92789
PR target/95726
* config/arm/arm.c (arm_attribute_table): Add
"Advanced SIMD type".
(arm_comp_type_attributes): Check that the "Advanced SIMD type"
attributes are equal.
* config/arm/arm-builtins.c: Include stringpool.h and
attribs.h.
(arm_mangle_builtin_vector_type): Use the mangling recorded
in the "Advanced SIMD type" attribute.
(arm_init_simd_builtin_types): Add an "Advanced SIMD type"
attribute to each Advanced SIMD type, using the mangled type
as the attribute's single argument.

gcc/testsuite/
PR target/92789
PR target/95726
* g++.target/arm/pr95726.C: New test.
---
 gcc/config/arm/arm-builtins.c  | 35 ++
 gcc/config/arm/arm.c   | 10 ++
 gcc/testsuite/g++.target/arm/pr95726.C | 49 ++
 3 files changed, 79 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/arm/pr95726.C

diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index f64742e6447..33e8015b140 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -43,6 +43,8 @@
 #include "sbitmap.h"
 #include "stringpool.h"
 #include "arm-builtins.h"
+#include "stringpool.h"
+#include "attribs.h"
 
 #define SIMD_MAX_BUILTIN_ARGS 7
 
@@ -1457,18 +1459,12 @@ arm_mangle_builtin_scalar_type (const_tree type)
 static const char *
 arm_mangle_builtin_vector_type (const_tree type)
 {
-  int i;
-  int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
-
-  for (i = 0; i < nelts; i++)
-if (arm_simd_types[i].mode ==  TYPE_MODE (type)
-   && TYPE_NAME (type)
-   && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
-   && DECL_NAME (TYPE_NAME (type))
-   && !strcmp
-(IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
- arm_simd_types[i].name))
-  return arm_simd_types[i].mangle;
+  tree attrs = TYPE_ATTRIBUTES (type);
+  if (tree attr = lookup_attribute ("Advanced SIMD type", attrs))
+{
+  tree mangled_name = TREE_VALUE (TREE_VALUE (attr));
+  return IDENTIFIER_POINTER (mangled_name);
+}
 
   return NULL;
 }
@@ -1642,9 +1638,18 @@ arm_init_simd_builtin_types (void)
   if (eltype == NULL)
continue;
   if (arm_simd_types[i].itype == NULL)
-   arm_simd_types[i].itype =
- build_distinct_type_copy
-   (build_vector_type (eltype, GET_MODE_NUNITS (mode)));
+   {
+ tree type = build_vector_type (eltype, GET_MODE_NUNITS (mode));
+ type = build_distinct_type_copy (type);
+ SET_TYPE_STRUCTURAL_EQUALITY (type);
+
+ tree mangled_name = get_identifier (arm_simd_types[i].mangle);
+ tree value = tree_cons (NULL_TREE, 

Patch RFA: In C++ demangler don't treat lambda as substitution candidate

2020-07-10 Thread Ian Lance Taylor via Gcc-patches
As discussed in PR 96143, the C++ frontend and the demangler disagree
as to whether a lambda is a substitution candidate.  According to the
ABI, the C++ frontend is behaving correctly.  This patch changes the
demangler accordingly.

This caused the demangling of several existing test cases to change.
These test cases are long and complicated, and I frankly did not try
to understand whether the change is correct or not.  I believe that
the change is correct, and at least these symbols continue to
demangle.

Did a full bootstrap and testsuite run on x86_64-pc-linux-gnu.

OK for mainline?

Ian

2020-07-10  Ian Lance Taylor  

PR demangler/96143
* cp-demangle.c (d_lambda): Don't add substitution candidate.
* testsuite/demangle-expected: Update a few existing test cases
accordingly, and add a new test case.
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index cbfb2f937ca..08e5ec3c964 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -3764,9 +3764,6 @@ d_lambda (struct d_info *di)
   ret->u.s_unary_num.num = num;
 }
 
-  if (! d_add_substitution (di, ret))
-return NULL;
-
   return ret;
 }
 
diff --git a/libiberty/testsuite/demangle-expected 
b/libiberty/testsuite/demangle-expected
index d8e50951f84..11aa5e7fc38 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -1114,7 +1114,7 @@ DFA
 # http://sourceware.org/bugzilla/show_bug.cgi?id=11572
 --format=auto
 
_ZN3Psi7VariantIIcPKcEE5visitIIRZN11VariantTest9TestVisit11test_methodEvEUlS2_E0_RZNS6_11test_methodEvEUlcE1_RZNS6_11test_methodEvEUlNS_4NoneEE_EEENS_13VariantDetail19SelectVisitorResultIIDpT_EE4typeEDpOSG_
-Psi::VariantDetail::SelectVisitorResult::type 
Psi::Variant::visit((VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&)...)
+Psi::VariantDetail::SelectVisitorResult::type 
Psi::Variant::visit(VariantTest::TestVisit::test_method()::{lambda(char
 const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, 
VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&)
 #
 # Clone suffix tests
 #
@@ -1170,7 +1170,7 @@ f
 #
 --format=gnu-v3
 
_ZN4modc6parser8sequenceINS_9astParser13LocatedParserINS0_9ParserRefINS2_UlRNS2_16TokenParserInputEE_EINS0_14OptionalParserINS2_18ListParserTemplateILNS_6tokens5Token4TypeE4EXadL_ZNSD_Ut_13parenthesized6ParserINS4_INS0_6ParserIS5_NS_3ast10ExpressionENSA_INS4_INS2_22OneOfKeywordsToTParserINSJ_5StyleEEENS0_14SequenceParserIS5_INS0_18ExactElementParserIS5_EENSA_ISM_ENS0_14RepeatedParserINS4_INS0_15TransformParserINSU_IS5_INS4_INSP_INSJ_10Annotation12RelationshipESX_EEENS2_UlNS2_3LocES12_ONS_5MaybeISK_EEE19_ELb0EENSU_INS0_17ExtractParserTypeIT_E9InputTypeEINS0_8MaybeRefIS1F_E4TypeEDpNS1I_IT0_E4TypeOS1F_DpOS1L_
-modc::parser::ParserRef::Parser::Style> 
>
 > >::InputType, 
modc::parser::MaybeRef&&)#21}>::Type, 
modc::parser::RepeatedParser::Parser::Style> 
>::Parser > 
>::Parser::Annotation::Relationship> >, 
modc::parser::ExactElementParser> >, 
modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, 
modc::Maybe&&)#21}> >, 
false>::Parser > > > >::Type, 
modc::parser::RepeatedParser::Parser::Style> 
>::Parser > 
>::Parser::Annotation::Relationship> >, 
modc::parser::ExactElementParser> >, 
modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, 
modc::Maybe&&)#21}> >, 
false>
 
>::Parser::Style> > > >::Type, 
modc::parser::RepeatedParser::Parser::Style> 
>::Parser > 
>::Parser::Annotation::Relationship> >, 
modc::parser::ExactElementParser> >, 
modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, 
modc::Maybe&&)#21}> >, 
false>,
 
modc::astParser::LocatedParser
 > > > >::Type, 
modc::parser::RepeatedParser::Parser::Style> 
>::Parser > 
>::Parser::Annotation::Relationship> >, 
modc::parser::ExactElementParser> >, 
modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, 
modc::Maybe&&)#21}> >, 
false>::Parser::Style> 
>::Parser > 
>::Parser::Annotation::Relationship> >, 
modc::parser::ExactElementParser> >, 
modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, 
modc::Maybe&&)#21}> >, false> >::Type> 
modc::parser::sequence
 >, 
modc::parser::OptionalParser::Parser > > >, 
modc::astParser::LocatedParser
 
>::Parser::Style> > >, 
modc::parser::SequenceParser,
 
modc::astParser::LocatedParser
 > > >, 
modc::parser::RepeatedParser::Parser::Style> 
>::Parser > 
>::Parser::Annotation::Relationship> >, 
modc::parser::ExactElementParser> >, 
modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, 
modc::Maybe&&)#21}> >, false> 
>(modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, 
modc::Maybe&&)#21}&&, 
(modc::parser::ExtractParserType
 > >&&)...)
+modc::parser::OptionalParser
 > 
>
 > >::InputType, 
modc::parser::MaybeRef
 > 
>::Parser > > > 
>, modc::parser::ExactElementParser > >, 

Re: [PATCH] expr: Move reduce_bit_field target mode check [PR96151]

2020-07-10 Thread Aaron Sawdey via Gcc-patches
This fixed the ICE I was seeing, thanks.

Aaron Sawdey, Ph.D. saw...@linux.ibm.com
IBM Linux on POWER Toolchain
 

> On Jul 10, 2020, at 10:40 AM, Richard Sandiford  
> wrote:
> 
> In some cases, expand_expr_real_2 prefers to use the mode of the
> caller-suggested target instead of the mode of the expression when
> passing values to reduce_to_bit_field_precision.  E.g.:
> 
>  else if (target == 0)
>op0 = convert_to_mode (mode, op0,
>   TYPE_UNSIGNED (TREE_TYPE
>  (treeop0)));
>  else
>{
>  convert_move (target, op0,
>TYPE_UNSIGNED (TREE_TYPE (treeop0)));
>  op0 = target;
>}
> 
> where “op0” might not have “mode” for the “else” branch,
> but does for all the others.
> 
> reduce_to_bit_field_precision discards the suggested target if it
> has the wrong mode.  This patch moves that to expand_expr_real_2
> instead (conditional on reduce_bit_field).
> 
> Sorry for the breakage.  This is what I'd done in the original
> version of the patch, after checking all uses of REDUCE_BIT_FIELD.
> I then forgot why it was necessary and tried to “simplify” the
> patch for backports.
> 
> Tested on arm-linux-gnueabihf, where it restores bootstrap.
> Other tests still ongoing.  OK to install if it passes?
> 
> Richard
> 
> 
> gcc/
>   PR middle-end/96151
>   * expr.c (expand_expr_real_2): When reducing bit fields,
>   clear the target if it has a different mode from the expression.
>   (reduce_to_bit_field_precision): Don't do that here.  Instead
>   assert that the target already has the correct mode.
> ---
> gcc/expr.c | 9 +
> 1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/gcc/expr.c b/gcc/expr.c
> index 715edae819a..c7c3e9fd655 100644
> --- a/gcc/expr.c
> +++ b/gcc/expr.c
> @@ -8664,7 +8664,9 @@ expand_expr_real_2 (sepops ops, rtx target, 
> machine_mode tmode,
>   reduce_bit_field = (INTEGRAL_TYPE_P (type)
> && !type_has_mode_precision_p (type));
> 
> -  if (reduce_bit_field && modifier == EXPAND_STACK_PARM)
> +  if (reduce_bit_field
> +  && (modifier == EXPAND_STACK_PARM
> +   || (target && GET_MODE (target) != mode)))
> target = 0;
> 
>   /* Use subtarget as the target for operand 0 of a binary operation.  */
> @@ -11527,9 +11529,8 @@ reduce_to_bit_field_precision (rtx exp, rtx target, 
> tree type)
> {
>   scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
>   HOST_WIDE_INT prec = TYPE_PRECISION (type);
> -  gcc_assert (GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode);
> -  if (target && GET_MODE (target) != mode)
> -target = 0;
> +  gcc_assert ((GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode)
> +   && (!target || GET_MODE (target) == mode));
> 
>   /* For constant values, reduce using wide_int_to_tree. */
>   if (poly_int_rtx_p (exp))



[PATCH] ipa-fnsummary: Fix ICE with switch predicates [PR96130]

2020-07-10 Thread Jakub Jelinek via Gcc-patches
Hi!

The following testcase ICEs since r10-3199.
There is a switch with default label, where the controlling expression has
range just 0..7 and there are case labels for all those 8 values, but
nothing has yet optimized away the default.
Since r10-3199, set_switch_stmt_execution_predicate sets the switch to
default label's edge's predicate to a false predicate and then
compute_bb_predicates propagates the predicates through the cfg, but false
predicates aren't really added.  The caller of compute_bb_predicates
in one place handles NULL bb->aux as false predicate:
  if (fbi.info)
{
  if (bb->aux)
bb_predicate = *(predicate *) bb->aux;
  else
bb_predicate = false;
}
  else
bb_predicate = true;
but then in two further spots that the patch below is changing
it assumes bb->aux must be non-NULL.  Those two spots are guarded by a
condition that is only true if fbi.info is non-NULL, so I think the right
fix is to treat NULL aux as false predicate in those spots too.

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

2020-07-10  Jakub Jelinek  

PR ipa/96130
* ipa-fnsummary.c (analyze_function_body): Treat NULL bb->aux
as false predicate.

* gcc.dg/torture/pr96130.c: New test.

--- gcc/ipa-fnsummary.c.jj  2020-04-05 00:27:26.0 +0200
+++ gcc/ipa-fnsummary.c 2020-07-10 16:12:59.155168850 +0200
@@ -2766,7 +2766,10 @@ analyze_function_body (struct cgraph_nod
  edge ex;
  unsigned int j;
  class tree_niter_desc niter_desc;
- bb_predicate = *(predicate *) loop->header->aux;
+ if (loop->header->aux)
+   bb_predicate = *(predicate *) loop->header->aux;
+ else
+   bb_predicate = false;
 
  exits = get_loop_exit_edges (loop);
  FOR_EACH_VEC_ELT (exits, j, ex)
@@ -2799,7 +2802,10 @@ analyze_function_body (struct cgraph_nod
  for (unsigned i = 0; i < loop->num_nodes; i++)
{
  gimple_stmt_iterator gsi;
- bb_predicate = *(predicate *) body[i]->aux;
+ if (body[i]->aux)
+   bb_predicate = *(predicate *) body[i]->aux;
+ else
+   bb_predicate = false;
  for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);
   gsi_next ())
{
--- gcc/testsuite/gcc.dg/torture/pr96130.c.jj   2020-07-10 16:15:28.794082127 
+0200
+++ gcc/testsuite/gcc.dg/torture/pr96130.c  2020-07-10 16:14:49.273633241 
+0200
@@ -0,0 +1,26 @@
+/* PR ipa/96130 */
+/* { dg-do compile } */
+
+struct S { unsigned j : 3; };
+int k, l, m;
+
+void
+foo (struct S x)
+{
+  while (l != 5)
+switch (x.j)
+  {
+  case 1:
+  case 3:
+  case 4:
+  case 6:
+  case 2:
+  case 5:
+   l = m;
+  case 7:
+  case 0:
+   k = 0;
+  default:
+   break;
+  }
+}

Jakub



Re: [PATCH] c++: Fix tentative parsing of enum-specifier [PR96077]

2020-07-10 Thread Marek Polacek via Gcc-patches
On Fri, Jul 10, 2020 at 05:53:21PM +0200, Jakub Jelinek wrote:
> On Fri, Jul 10, 2020 at 11:43:59AM -0400, Marek Polacek via Gcc-patches wrote:
> > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> > index 528b41b7170..ee6a956aea9 100644
> > --- a/gcc/cp/parser.c
> > +++ b/gcc/cp/parser.c
> > @@ -19412,7 +19412,12 @@ cp_parser_enum_specifier (cp_parser* parser)
> >  "ISO C++ forbids empty unnamed enum");
> > }
> >else
> > -   cp_parser_enumerator_list (parser, type);
> > +   {
> > + /* We've seen a '}' so we know we're in an enum-specifier.
> 
> Shouldn't that be '{' instead?

Yes, fixed in my local branch.  Thanks!

Marek



Re: [PATCH] expr: Move reduce_bit_field target mode check [PR96151]

2020-07-10 Thread Jeff Law via Gcc-patches
On Fri, 2020-07-10 at 16:40 +0100, Richard Sandiford wrote:
> In some cases, expand_expr_real_2 prefers to use the mode of the
> caller-suggested target instead of the mode of the expression when
> passing values to reduce_to_bit_field_precision.  E.g.:
> 
>   else if (target == 0)
> op0 = convert_to_mode (mode, op0,
>TYPE_UNSIGNED (TREE_TYPE
>   (treeop0)));
>   else
> {
>   convert_move (target, op0,
> TYPE_UNSIGNED (TREE_TYPE (treeop0)));
>   op0 = target;
> }
> 
> where “op0” might not have “mode” for the “else” branch,
> but does for all the others.
> 
> reduce_to_bit_field_precision discards the suggested target if it
> has the wrong mode.  This patch moves that to expand_expr_real_2
> instead (conditional on reduce_bit_field).
> 
> Sorry for the breakage.  This is what I'd done in the original
> version of the patch, after checking all uses of REDUCE_BIT_FIELD.
> I then forgot why it was necessary and tried to “simplify” the
> patch for backports.
> 
> Tested on arm-linux-gnueabihf, where it restores bootstrap.
> Other tests still ongoing.  OK to install if it passes?
> 
> Richard
> 
> 
> gcc/
>   PR middle-end/96151
>   * expr.c (expand_expr_real_2): When reducing bit fields,
>   clear the target if it has a different mode from the expression.
>   (reduce_to_bit_field_precision): Don't do that here.  Instead
>   assert that the target already has the correct mode.
OK.  Note I think this is also affecting csky and mips too.

Jeff
> 



Re: [PATCH] c++: Fix tentative parsing of enum-specifier [PR96077]

2020-07-10 Thread Jakub Jelinek via Gcc-patches
On Fri, Jul 10, 2020 at 11:43:59AM -0400, Marek Polacek via Gcc-patches wrote:
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index 528b41b7170..ee6a956aea9 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -19412,7 +19412,12 @@ cp_parser_enum_specifier (cp_parser* parser)
>"ISO C++ forbids empty unnamed enum");
>   }
>else
> - cp_parser_enumerator_list (parser, type);
> + {
> +   /* We've seen a '}' so we know we're in an enum-specifier.

Shouldn't that be '{' instead?

> +  Commit to any tentative parse to get syntax errors.  */
> +   cp_parser_commit_to_tentative_parse (parser);
> +   cp_parser_enumerator_list (parser, type);
> + }

Jakub



[PATCH] c++: Fix tentative parsing of enum-specifier [PR96077]

2020-07-10 Thread Marek Polacek via Gcc-patches
Here's an interesting issue: in this code a ) is missing:

  enum { E = (2 } e;

but we compile the code anyway, and E is set to 0 in build_enumerator,
which is sneaky.

The problem is that cp_parser_enum_specifier parses tentatively, because
when we see the enum keyword, we don't know yet if we'll find an
enum-specifier, opaque-enum-declaration, or elaborated-enum-specifier.

In this test when we call cp_parser_enumerator_list we're still parsing
tentatively, and as a consequence, parens.require_close (parser) in
cp_parser_primary_expression doesn't report any errors.  But we only go
on to parse the enumerator-list after we've seen a {, at which point we
might as well commit -- we know we're dealing with an enum-specifier.

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

gcc/cp/ChangeLog:

PR c++/96077
* parser.c (cp_parser_enum_specifier): Commit to tentative parse
after we've seen an opening brace.

gcc/testsuite/ChangeLog:

PR c++/96077
* g++.dg/parse/enum14.C: New test.
---
 gcc/cp/parser.c | 7 ++-
 gcc/testsuite/g++.dg/parse/enum14.C | 7 +++
 2 files changed, 13 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/parse/enum14.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 528b41b7170..ee6a956aea9 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -19412,7 +19412,12 @@ cp_parser_enum_specifier (cp_parser* parser)
 "ISO C++ forbids empty unnamed enum");
}
   else
-   cp_parser_enumerator_list (parser, type);
+   {
+ /* We've seen a '}' so we know we're in an enum-specifier.
+Commit to any tentative parse to get syntax errors.  */
+ cp_parser_commit_to_tentative_parse (parser);
+ cp_parser_enumerator_list (parser, type);
+   }
 
   /* Consume the final '}'.  */
   braces.require_close (parser);
diff --git a/gcc/testsuite/g++.dg/parse/enum14.C 
b/gcc/testsuite/g++.dg/parse/enum14.C
new file mode 100644
index 000..be09cca5211
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/enum14.C
@@ -0,0 +1,7 @@
+// PR c++/96077
+
+int main ()
+{
+  enum { E = (2 } e; // { dg-error "expected" }
+  enum { F = true ? 2 : (3 /* missing ")" here */ } f; // { dg-error 
"expected" }
+}

base-commit: c6b7ba5de624f2a17d799bac5ff017cd065ce035
-- 
2.26.2



[PATCH] expr: Move reduce_bit_field target mode check [PR96151]

2020-07-10 Thread Richard Sandiford
In some cases, expand_expr_real_2 prefers to use the mode of the
caller-suggested target instead of the mode of the expression when
passing values to reduce_to_bit_field_precision.  E.g.:

  else if (target == 0)
op0 = convert_to_mode (mode, op0,
   TYPE_UNSIGNED (TREE_TYPE
  (treeop0)));
  else
{
  convert_move (target, op0,
TYPE_UNSIGNED (TREE_TYPE (treeop0)));
  op0 = target;
}

where “op0” might not have “mode” for the “else” branch,
but does for all the others.

reduce_to_bit_field_precision discards the suggested target if it
has the wrong mode.  This patch moves that to expand_expr_real_2
instead (conditional on reduce_bit_field).

Sorry for the breakage.  This is what I'd done in the original
version of the patch, after checking all uses of REDUCE_BIT_FIELD.
I then forgot why it was necessary and tried to “simplify” the
patch for backports.

Tested on arm-linux-gnueabihf, where it restores bootstrap.
Other tests still ongoing.  OK to install if it passes?

Richard


gcc/
PR middle-end/96151
* expr.c (expand_expr_real_2): When reducing bit fields,
clear the target if it has a different mode from the expression.
(reduce_to_bit_field_precision): Don't do that here.  Instead
assert that the target already has the correct mode.
---
 gcc/expr.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/gcc/expr.c b/gcc/expr.c
index 715edae819a..c7c3e9fd655 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8664,7 +8664,9 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode 
tmode,
   reduce_bit_field = (INTEGRAL_TYPE_P (type)
  && !type_has_mode_precision_p (type));
 
-  if (reduce_bit_field && modifier == EXPAND_STACK_PARM)
+  if (reduce_bit_field
+  && (modifier == EXPAND_STACK_PARM
+ || (target && GET_MODE (target) != mode)))
 target = 0;
 
   /* Use subtarget as the target for operand 0 of a binary operation.  */
@@ -11527,9 +11529,8 @@ reduce_to_bit_field_precision (rtx exp, rtx target, 
tree type)
 {
   scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
   HOST_WIDE_INT prec = TYPE_PRECISION (type);
-  gcc_assert (GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode);
-  if (target && GET_MODE (target) != mode)
-target = 0;
+  gcc_assert ((GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode)
+ && (!target || GET_MODE (target) == mode));
 
   /* For constant values, reduce using wide_int_to_tree. */
   if (poly_int_rtx_p (exp))


Re: [PATCH] rs6000: Allow MMA built-in initialization regardless of compiler options

2020-07-10 Thread Peter Bergner via Gcc-patches
On 7/9/20 4:10 PM, Peter Bergner wrote:
> I verified the updated test case passes on both LE and BE, so I've
> pushed this now.  I'll let Bill Seurer's nightly testing try this
> on a wider variety of builds before backporting this to GCC10.
> I'll try and do that tomorrow.

Bill's nightly testsuite runs didn't show any regressions due to
my patch, so I pushed this to the GCC10 branch.

Peter




Re: [PATCH] middle-end: Call get_constant_section with DECL not EXP.

2020-07-10 Thread David Edelsohn via Gcc-patches
On Fri, Jul 10, 2020 at 2:55 AM Richard Biener
 wrote:
>
> On Thu, Jul 9, 2020 at 8:29 PM David Edelsohn  wrote:
> >
> > output_constant_def_contents() can call get_constant_section() with an
> > EXP that is a CONSTRUCTOR, which is not a declaration.  This can hit
> > asserts in GCC machinery to choose a named section for the initialization
> > data that expects the parameters to be DECLs.
> >
> > get_constant_section() is a wrapper around TARGET_ASM_SELECT_SECTION,
> > which is documented as:
> >
> > Return the section into which @var{exp} should be placed.  You can
> > assume that @var{exp} is either a @code{VAR_DECL} node or a constant of
> > some sort.
> >
> > A CONSTRUCTOR initializer is a "constant of some sort", but isn't
> > consistent with DECL_SECTION_NAME, etc.
> >
> > This patch changes get_constant_section() and its callers to pass the
> > DECL within the EXP instead of the EXP, and to explicitly pass the reloc
> > information that must be determined from the EXP.
> >
> > Another option is to remove get_constant_section() completely, replace
> > it with direct calls to targetm.asm_out.select_section() (for which it
> > now is a complete pass-through), and update the Target Hook
> > documentation.
> >
> > What's the preferred path forward?
>
> Given we can always pass a decl - in the cases you change the former
> parameter is simply DECL_INITIAL of the now passed decl - this is
> a welcome cleanup of the TARGET_ASM_SELECT_SECTION
> interface and it should be amended with adjusting its documentation.
>
> That in turn might be an opportunity to cleanup target code.
>
> I think we cannot rule out that targets special-case say STRING_CST
> but not DECL_INITIAL (decl) == STRING_CST so some kind of
> auditing is probably required.

A quick check shows that target implementations believe that they
should receive a DECL, but some are prepared for non-DECLs.

rl78 explicitly handles CONSTRUCTOR.

c6x explicitly handles the STRING_CST.

msp430 explicitly handles both CONSTRUCTOR and TREE_CONSTANT cases.

v850 explicitly handles TREE_CONSTANT.

i386 explicitly handles SECCAT_RODATA_MERGE_STR.

Also, categorize_decl_for_section() is used by
default_elf_select_section() and explicitly tests

  else if (TREE_CODE (decl) == STRING_CST)

and

  else if (TREE_CODE (decl) == CONSTRUCTOR)

>
> David - I know you need this for AIX - I think the target hook implementation
> is supposed to assume that if it doesn't get passed a decl then it's
> a "random constant" without any special attributes attached.  What's
> your requirement that can possibly only be fulfilled with seeing a decl?

BIGGEST_ALIGNMENT on AIX is defined as 128.  The vector in the
testcase requests an alignment of 256.  GCC generates a pseudo-op in
the assembly for an alignment of 256, but the initializer is placed in
a section with weaker alignment.

For AIX XCOFF object files, MAXOFILE_ALIGNMENT is 32768.  I was
attempting to have GCC generate a special, named section that
specifies the stricter, requested alignment into which the
appropriately aligned initizer would be placed.

The named section machinery of GCC uses DECL_SECTION_NAME, which is
unhappy when handed an EXP.

I was attempting to implement something more correct for GCC
implicitly specified or user-specified stricter alignment, but Power
hardware doesn't require stricter alignment, so maybe it's better to
just punt for CONSTRUCTOR in the AIX implementation.

Thanks, David


Re: testsuite: missed testcase

2020-07-10 Thread Nathan Sidwell

On 7/10/20 10:28 AM, Christophe Lyon wrote:

Hi,


On Tue, 7 Jul 2020 at 20:47, Nathan Sidwell  wrote:


I discovered I'd missed applying a testcase when fixing up the EOF token
location a while back.

  gcc/testsuite/
  * c-c++-common/cpp/pragma-eof.c: New



The new testcase fails on targets that do not support openmp (I saw
problems on arm-eabi and aarch64-elf using newlib, where -lpthread was
failing).

I'm pushing the attached patch as obvious.


Thanks!


--
Nathan Sidwell


Re: [PATCH 2/2] openacc: Adjust dynamic reference count semantics

2020-07-10 Thread Thomas Schwinge
Hi Julian!

On 2020-07-09T17:06:59-0700, Julian Brown  wrote:
> This patch adjusts how dynamic reference counts work so that they match
> the semantics of the source program more closely, instead of representing
> "excess" reference counts beyond those that represent pointers in the
> internal libgomp splay-tree data structure. This allows some corner
> cases to be handled more gracefully.

Thanks!

> OK?

Please squeeze in the incremental patch attached; don't need to re-test,
I've done that.  With that, OK for master and releases/gcc-10 branches.

A few comments (for later reference etc.):

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

> @@ -1067,18 +1072,144 @@ goacc_enter_data_internal (struct gomp_device_descr 
> *acc_dev, size_t mapnum,
>  void **hostaddrs, size_t *sizes,
>  unsigned short *kinds, goacc_aq aq)
>  {
> +  gomp_mutex_lock (_dev->lock);
> +
>for (size_t i = 0; i < mapnum; i++)
>  {
> -  int group_last = find_group_last (i, mapnum, sizes, kinds);
> +  splay_tree_key n;
> +  size_t group_last = find_group_last (i, mapnum, sizes, kinds);
> +  bool struct_p = false;
> +  size_t size, groupnum = (group_last - i) + 1;
> +
> +  switch (kinds[i] & 0xff)
> + {
> + case GOMP_MAP_STRUCT:
> +   {
> + size = (uintptr_t) hostaddrs[group_last] + sizes[group_last]
> +- (uintptr_t) hostaddrs[i];
> + struct_p = true;
> +   }
> +   break;
> +
> + case GOMP_MAP_ATTACH:
> +   size = sizeof (void *);
> +   break;
> +
> + default:
> +   size = sizes[i];
> + }
>
> -  gomp_map_vars_async (acc_dev, aq,
> -(group_last - i) + 1,
> -[i], NULL,
> -[i], [i], true,
> -GOMP_MAP_VARS_OPENACC_ENTER_DATA);

> +  n = lookup_host (acc_dev, hostaddrs[i], size);
> +
> +  if (n && struct_p)
> + {
> +   for (size_t j = i + 1; j <= group_last; j++)
> + {
> +   struct splay_tree_key_s cur_node;
> +   cur_node.host_start = (uintptr_t) hostaddrs[j];
> +   cur_node.host_end = cur_node.host_start + sizes[j];
> +   splay_tree_key n2
> + = splay_tree_lookup (_dev->mem_map, _node);
> +   if (!n2
> +   || n2->tgt != n->tgt
> +   || n2->host_start - n->host_start
> +  != n2->tgt_offset - n->tgt_offset)
> + {
> +   gomp_mutex_unlock (_dev->lock);
> +   gomp_fatal ("Trying to map into device [%p..%p) structure "
> +   "element when other mapped elements from the "
> +   "same structure weren't mapped together with "
> +   "it", (void *) cur_node.host_start,
> +   (void *) cur_node.host_end);
> + }
> + }

Ah, OK, that was missing before, thanks.  (There obviously is overlap
with 'libgomp/target.c:gomp_map_fields_existing'; maybe we can
de-duplicate that later.)

This checking fixes the issue I'd raised with the new
'libgomp.oacc-c-c++-common/struct-3-1-1.c': "after '#pragma acc enter
data create(s.a)' we're no longer refusing '#pragma acc enter data
create(s.b)'".

> +   /* This is a special case because we must increment the refcount by
> +  the number of mapped struct elements, rather than by one.  */

Thanks.

> +   if (n->refcount != REFCOUNT_INFINITY)
> + n->refcount += groupnum - 1;
> +   n->dynamic_refcount += groupnum - 1;
> + }

> +  else if (n && groupnum == 1)
> + {
> +   void *h = hostaddrs[i];
> +   size_t s = sizes[i];
> +
> +   /* A standalone attach clause.  */
> +   if ((kinds[i] & 0xff) == GOMP_MAP_ATTACH)
> + gomp_attach_pointer (acc_dev, aq, _dev->mem_map, n,
> +  (uintptr_t) h, s, NULL);
> +
> +   goacc_map_var_existing (acc_dev, h, s, aq, n);

ACK.  Just also need to remove 'aq' (see incremental patch attached).

> + }

> +  else if (n && groupnum > 1)
> + {
> +   assert (n->refcount != REFCOUNT_INFINITY
> +   && n->refcount != REFCOUNT_LINK);
> +
> +   for (size_t j = i + 1; j <= group_last; j++)
> + if ((kinds[j] & 0xff) == GOMP_MAP_ATTACH)
> +   {
> + splay_tree_key m
> +   = lookup_host (acc_dev, hostaddrs[j], sizeof (void *));
> + gomp_attach_pointer (acc_dev, aq, _dev->mem_map, m,
> +  (uintptr_t) hostaddrs[j], sizes[j], NULL);
> +   }

(For possibly later reference, quoting my earlier comment: "Per the
earlier '[OpenACC] GOMP_MAP_ATTACH handling in find_group_last', we
should never have more than one 'GOMP_MAP_ATTACH' following something
else (right?), but it's still OK to leave this in this generic form --
unless you want to add some 'assert'ing here.")

> +
> +   bool 

Re: testsuite: missed testcase

2020-07-10 Thread Christophe Lyon via Gcc-patches
Hi,


On Tue, 7 Jul 2020 at 20:47, Nathan Sidwell  wrote:
>
> I discovered I'd missed applying a testcase when fixing up the EOF token
> location a while back.
>
>  gcc/testsuite/
>  * c-c++-common/cpp/pragma-eof.c: New
>

The new testcase fails on targets that do not support openmp (I saw
problems on arm-eabi and aarch64-elf using newlib, where -lpthread was
failing).

I'm pushing the attached patch as obvious.

Thanks

Christophe

> --
> Nathan Sidwell
From 2f06fb713845dd4777f8b659cbe008a2a131cd80 Mon Sep 17 00:00:00 2001
From: Christophe Lyon 
Date: Fri, 10 Jul 2020 12:42:47 +
Subject: [PATCH 1/1] testsuite: Fix c-c++-common/cpp/pragma-eof.c

Add missing fopenmp effective-target.

2020-07-10  Christophe Lyon  

gcc/testsuite/ChangeLog:
	* c-c++-common/cpp/pragma-eof.c: Add missing fopenmp
	effective-target.
---
 gcc/testsuite/c-c++-common/cpp/pragma-eof.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/c-c++-common/cpp/pragma-eof.c b/gcc/testsuite/c-c++-common/cpp/pragma-eof.c
index c72be80..c109435 100644
--- a/gcc/testsuite/c-c++-common/cpp/pragma-eof.c
+++ b/gcc/testsuite/c-c++-common/cpp/pragma-eof.c
@@ -1,6 +1,7 @@
 /* { dg-additional-options -fopenmp }  */
+/* { dg-require-effective-target fopenmp } */
 
-/* { dg-error "expected" "" { target *-*-* } 6 } */
+/* { dg-error "expected" "" { target *-*-* } 7 } */
 /* Make sure we see pragma_eol even though lacking new line.  *
 /* no newline at end of file.  */
 #pragma omp parallel
\ No newline at end of file
-- 
2.7.4



Re: [PATCH 1/2] openacc: Helper functions for enter/exit data using single mapping

2020-07-10 Thread Thomas Schwinge
Hi Julian!

On 2020-07-09T17:06:58-0700, Julian Brown  wrote:
> This patch factors out the parts of goacc_enter_datum and
> goacc_exit_datum that can be shared with goacc_enter_data_internal
> and goacc_exit_data_internal respectively (in the next patch),
> without overloading function return values or complicating code paths
> unnecessarily.

Thanks!

> OK?

Just one comment (incremental patch attached; don't need to re-test, I've
done that).  With that, OK for master and releases/gcc-10 branches.

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

> +/* Helper function to map a single dynamic data item, represented by a single
> +   mapping.  The acc_dev->lock should be held on entry, and remains locked on
> +   exit.  */
> +
> +static void *
> +goacc_map_var_existing (struct gomp_device_descr *acc_dev, void *hostaddr,
> + size_t size, goacc_aq aq, splay_tree_key n)

Given that this deals only with existing mappings, for which we're never
going to do any host/device data copying etc., this cannot ever make any
use of 'aq', so we shouldn't include it here (see incremental patch
attached).

> +{
> +  assert (n);
> +
> +  /* Present. */
> +  void *d = (void *) (n->tgt->tgt_start + n->tgt_offset + hostaddr
> + - n->host_start);
> +
> +  if (hostaddr + size > (void *) n->host_end)
> +{
> +  gomp_mutex_unlock (_dev->lock);
> +  gomp_fatal ("[%p,+%d] not mapped", hostaddr, (int) size);
> +}
> +
> +  assert (n->refcount != REFCOUNT_LINK);
> +  if (n->refcount != REFCOUNT_INFINITY)
> +{
> +  n->refcount++;
> +  n->virtual_refcount++;
> +}
> +
> +  return d;
> +}


Grüße
 Thomas


-
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
>From f397602baa8116b31dc11ea1f63c3e582d2e5ba7 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge 
Date: Fri, 10 Jul 2020 12:46:47 +0200
Subject: [PATCH] into "openacc: Helper functions for enter/exit data using
 single mapping"

---
 libgomp/oacc-mem.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/libgomp/oacc-mem.c b/libgomp/oacc-mem.c
index 6f9043bf5b1..34f519a2045 100644
--- a/libgomp/oacc-mem.c
+++ b/libgomp/oacc-mem.c
@@ -504,7 +504,7 @@ acc_unmap_data (void *h)
 
 static void *
 goacc_map_var_existing (struct gomp_device_descr *acc_dev, void *hostaddr,
-			size_t size, goacc_aq aq, splay_tree_key n)
+			size_t size, splay_tree_key n)
 {
   assert (n);
 
@@ -559,10 +559,9 @@ goacc_enter_datum (void **hostaddrs, size_t *sizes, void *kinds, int async)
   gomp_mutex_lock (_dev->lock);
 
   n = lookup_host (acc_dev, hostaddrs[0], sizes[0]);
-  goacc_aq aq = get_goacc_asyncqueue (async);
   if (n)
 {
-  d = goacc_map_var_existing (acc_dev, hostaddrs[0], sizes[0], aq, n);
+  d = goacc_map_var_existing (acc_dev, hostaddrs[0], sizes[0], n);
   gomp_mutex_unlock (_dev->lock);
 }
   else
@@ -571,6 +570,8 @@ goacc_enter_datum (void **hostaddrs, size_t *sizes, void *kinds, int async)
 
   gomp_mutex_unlock (_dev->lock);
 
+  goacc_aq aq = get_goacc_asyncqueue (async);
+
   struct target_mem_desc *tgt
 	= gomp_map_vars_async (acc_dev, aq, mapnum, hostaddrs, NULL, sizes,
 			   kinds, true, GOMP_MAP_VARS_OPENACC_ENTER_DATA);
-- 
2.17.1



[PATCH] RISC-V: Fix regular expression in target-specific test

2020-07-10 Thread Simon Cook
Some square brackets were missing escape characters, causing DejaGnu to
try and call a proc with the name "at".

gcc/testsuite/ChangeLog:

* gcc.target/riscv/read-thread-pointer.c: Fix escaping on
regular expression.
---
 gcc/testsuite/gcc.target/riscv/read-thread-pointer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/riscv/read-thread-pointer.c
b/gcc/testsuite/gcc.target/riscv/read-thread-pointer.c
index 760f8eafb40..401fb421129 100644
--- a/gcc/testsuite/gcc.target/riscv/read-thread-pointer.c
+++ b/gcc/testsuite/gcc.target/riscv/read-thread-pointer.c
@@ -4,4 +4,4 @@ void *get_tp()
 {
 return __builtin_thread_pointer ();
 }
-/* { dg-final { scan-assembler "mv\[ \t\]*[at][0-9]+,tp" } } */
+/* { dg-final { scan-assembler "mv\[ \t\]*\[at\]\[0-9\]+,tp" } } */
--
2.17.1


Ping: [PATCH] diagnostics: Add options to control the column units [PR49973] [PR86904]

2020-07-10 Thread Lewis Hyatt via Gcc-patches
Hello-

May I please ping you about this patch? Thanks!
https://gcc.gnu.org/pipermail/gcc-patches/2020-June/547900.html

-Lewis

On Thu, Jun 11, 2020 at 11:26:28AM -0400, Lewis Hyatt wrote:
> On Wed, Jun 10, 2020 at 12:11:00PM -0400, David Malcolm wrote:
> > Thanks for the patch; sorry about the delay in reviewing it.
> > 
> > Some high-level review points
> > 
> > - I like the patch overall
> > 
> > - This will deserve an item in the release notes
> > 
> > - I don't like adding "global_tabstop" (I don't like global
> > variables).  Is there nowhere else we can handle this? I believe
> > there's a cluster of functions in the callgraph that make use of
> > it; can we simply pass around the tabstop value instead?  "tabstop"
> > seems to have several meanings.  If I'm reading the patch correctly
> >   * "tabstop > 0" means to expand tabs so that column numbers are a
> > multiple of tabstop
> >   * "tabstop == 0" means "don't expand tabs"
> >   * "tabstop < 0" in some places means: use the global_tabstop value
> > Is it possible to eliminate global_tabstop value?  Or is there some
> > deep reason I'm missing?
> > 
> > I'll do a more thorough review once that's addressed/resolved (since
> > eliminating global_tabstop might touch a few places).
> >
> 
> Thanks for the feedback! The attached updated patch addresses these
> concerns. Regarding tabstop, I have removed the new static variable
> global_tabstop in charset.c. FWIW, the usage of "tabstop" arguments in the
> various new APIs did previously work a bit more consistently than you
> described. In all cases "tabstop <= 0" meant to use the default value,
> otherwise it specified the tabstop to use (with tabstop=1 naturally
> restoring the old behavior of changing tabs to a single space). In order
> for libcpp to provide this feature (callers can pass tabstop <= 0 to get a
> default, and the default can in turn by configured when processing the
> -ftabstop option), it does need to remember the default, and this has to
> be a file-level static variable because the routines need to work
> independent of any cpp_reader instance. (Some frontends don't use
> libcpp to read their input, for instance.) Anyway, I see the point that
> this file-level static, being accessible with cpp_set_tabstop() and
> cpp_get_tabstop(), is effectively just a global variable, so I have
> removed this feature, which just means that all callers need to pass the
> tabstop they want to use. I am now rather using the diagnostic_context
> object to remember the value passed to -ftabstop. The only place this
> involves global variables is now in c-family/c-indentation.c, where if I
> understood correctly, the only diagnostic_context available is global_dc,
> so I am getting the tabstop value from there. Please let me know if
> there's a better way to handle that? Prior to my patch, the tabstop was
> obtained from a different global variable (extern cpp_options *cpp_opts),
> so at least conservation of total globals is maintained. :)
> 
> Compared to the previous version, this one is a bit longer, since 25 or
> so call sites had to be modified to know the value of -ftabstop. Most of
> the churn is in diagnostic-show-locus.c, because there are a fair number of
> static helper functions and helper classes there, which just needed to
> receive the diagnostic_context object from their callers. I could
> have made this simpler by letting the tabstop argument default to
> something like 8 in all functions that require it... this would remove the
> need to pass it in all the selftests that are indifferent to it. I figured
> it would be better to force this argument to be passed, though, or else in
> the future it may be easy to forget to pass it where it is needed. 
> 
> > Thanks for adding docs; some nits on them:
> > 
> > > --- a/gcc/doc/invoke.texi
> > > +++ b/gcc/doc/invoke.texi
> > 
> > [...snip...]
> > 
> > > +@item -fdiagnostics-column-unit=@var{UNIT}
> > > +@opindex fdiagnostics-column-unit
> > > +Select the units for the column number.  This affects traditional 
> > > diagnostics
> > > +(in the absence of @option{-fno-show-column}), as well as JSON format
> > > +diagnostics if requested.
> > > +
> > > +The default @var{UNIT}, @samp{display}, considers the number of display 
> > > columns
> > > +occupied by each character.  This may be larger than the number of bytes
> > > +occupied, in the case of tab characters, or it may be smaller, in the 
> > > case of
> > > +multibyte characters.  For example, the UTF-8 character ``@U{03C0}'' 
> > > occupies
> > > +two bytes and one display column, while the character ``@U{1F642}'' 
> > > occupies
> > > +four bytes and two display columns.
> > 
> > This is imprecise.  A unicode code point occupies some number of display 
> > columns,
> > and its *UTF-8 encoding* occupies some number of bytes.
> > 
> > [and my inner pedant is now thinking: what about combining diacritics? 
> > But I don't think we can ever issue a diagnostic on a diacritic; I
> > 

Re: [PATCH] rs6000: Refine RTL unroll adjust hook

2020-07-10 Thread Jiufu Guo via Gcc-patches
Hi Segher,

Thanks a lot for your time and helpful comments!

Segher Boessenkool  writes:

> Hi Jiufu,
>
> On Thu, Jul 09, 2020 at 04:01:38PM +0800, Jiufu Guo wrote:
>> Segher Boessenkool  writes:
...
> If the generic code decides to unroll big loops with calls *and* jumps,
> there is a big problem there?
>
> On most targets, it should not unroll loops with calls *at all*, for
> example.
>

>> >
>
> But there are a few cases where we *do* want to unroll, you say?  What
> is special about those cases, what do they do differently?
Here are loops with early exit, but could be unroll.
while (s < end && *s != '>') s++;
 IF ( setinitval .EQ. 1 .OR. setinitval .EQ. 3 ) grid%evbxy=initial_data_value
I will recheck to indendify/confirm which loops we want to unroll but
contains call or early exit.

BR.
Jiufu,
>
>
> Segher


Re: [PATCH] rs6000: Refine RTL unroll adjust hook

2020-07-10 Thread Jiufu Guo via Gcc-patches


Hi,

Segher Boessenkool  writes:

> Hi Jiufu,
>
> On Thu, Jul 09, 2020 at 04:01:38PM +0800, Jiufu Guo wrote:
>> Segher Boessenkool  writes:
>> >> But for each single condition, loop unrolling may still be helpful.
>> >> While, if these conditions are all occur in a loop, it would be more
>> >> possible to get negative impacts after unrolled.
>> >
>> > Yes, but how many loops have *all* these conditions?  That is my problem
>> > with it: it is only tested with one specific loop, and only benefits
>> > that loop.
>> 
>> I also encounter a few of this kind of loops, some in hot path of leela
>> and perlbench, and had negative impact leelar_r (~2%), perlbench(>0.5%),
>> and also gcc_r.  I had a quick count, there are ~500 this kind of loops
>> occur in specint build.
>
> If the generic code decides to unroll big loops with calls *and* jumps,
> there is a big problem there?
>
> On most targets, it should not unroll loops with calls *at all*, for
> example.
>
>> >> While, actually, here we would need condition to define *complex* loop,
>> >> where contains call exist (may just 1), branch exist(may 2) and early
>> >> exit(may 1) at the same time, but each number is not large.
>> >> Any sugguestions? Thanks.
>> >
>> > How many loops have you seen where all those conditions are true, but
>> > the generic code still decides to unroll things?
>> Some occur as above said.  I use -fopt-info to compare the changed
>> unroll_adjust_hook to check loops of this kind.
>
> But there are a few cases where we *do* want to unroll, you say?  What
> is special about those cases, what do they do differently?
During tests, if avoid unroll loops if there is call (or early exit).
As I remember there are performance downgrade on 1 or 2 benchmarks, but
I forget which ones. I check and confirm.

BR.
Jiufu,

>
>
> Segher


Re: [PATCH V2] PING^2 correct COUNT and PROB for unrolled loop

2020-07-10 Thread Jiufu Guo via Gcc-patches


Hi Martin,

Martin Liška  writes:

> On 7/10/20 4:14 AM, Jiufu Guo wrote:
>> Thanks so much for your time and kindly help!!!
>
> And I run your patch on SPEC2006 with:
> https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549728.html
>
> Doing that I see just few changes:
>
> diff -qr /tmp/before /tmp/after
> Files /tmp/before/Meat.fppized.f90.000i.profile-report and 
> /tmp/after/Meat.fppized.f90.000i.profile-report differ
> Files /tmp/before/bezier.cpp.000i.profile-report and 
> /tmp/after/bezier.cpp.000i.profile-report differ
> Files 
> /tmp/before/module_big_step_utilities_em.fppized.f90.000i.profile-report and 
> /tmp/after/module_big_step_utilities_em.fppized.f90.000i.profile-report differ
> Files /tmp/before/module_cu_bmj.fppized.f90.000i.profile-report and 
> /tmp/after/module_cu_bmj.fppized.f90.000i.profile-report differ
> Files /tmp/before/momx2.f.000i.profile-report and 
> /tmp/after/momx2.f.000i.profile-report differ
> Files /tmp/before/momx3.f.000i.profile-report and 
> /tmp/after/momx3.f.000i.profile-report differ
> Files /tmp/before/tml.f.000i.profile-report and 
> /tmp/after/tml.f.000i.profile-report differ
> Files /tmp/before/tranx2.f.000i.profile-report and 
> /tmp/after/tranx2.f.000i.profile-report differ
> Files /tmp/before/tranx3.f.000i.profile-report and 
> /tmp/after/tranx3.f.000i.profile-report differ
>
> But I see few regression, e.g.:
>
> $ cat bezier.ii
> int bezier_value_t, bezier_value_du_1;
> int bezier_value_u[4], bezier_value_du[4];
> void bezier_value() {
>   int i = 1;
>   for (; i < 4; i++) {
> bezier_value_u[i] = 1;
> bezier_value_du[i] = i * bezier_value_u[i - 1];
> bezier_value_t = bezier_value_du_1;
>   }
> }
>
> $ g++ bezier.ii -c -march=native -O3 -Wno-multichar 
> -Wno-aggressive-loop-optimizations -fdump-tree-pcom=/tmp/bad.txt
> ...
>
> And your patch changed:
>
> -   [local count: 134217728]:
> +   [local count: 89478486]:
>
> where the function looks like:
>
>[local count: 268435456]:
> ...
>   if (ivtmp_45 > 1)
> goto ; [50.00%]
>   else
> goto ; [50.00%]
>
>[local count: 89478486]:
>   goto ; [100.00%]
>
> So 89478486 != 268435456 / 2. That seems a regression caused by your patch.
>
> Can you please check it?
Thanks a lot for your tests and findings!
Sure, I will have a check.

BR.
Jiufu,

> Martin


Re: [PATCH][RFC] __builtin_shuffle sometimes should produce zip1 rather than TBL (PR82199)

2020-07-10 Thread Dmitrij Pochepko
Hi,

please take a look at updated version (attached).

Thanks,
Dmitrij

On Wed, Jul 08, 2020 at 03:48:39PM +0100, Richard Sandiford wrote:
...
> 
> maybe s/use bigger size up/combines odd and even elements/

done

> It should be possible to do this without the to_constants, e.g.:
> 
>   poly_int64 elt0 = d->perm[i];
>   poly_int64 elt1 = d->perm[i + 1];
>   poly_int64 newelt;
>   if (!multiple_p (elt0, 2, ) || maybe_ne (elt0 + 1, elt1))
> return false;
> 
> (The coding conventions require spaces around “+”, even though I agree
> “[i+1]” looks better.)

done

>From 34b6b0803111609ec5a0a615a8f03b78921e8412 Mon Sep 17 00:00:00 2001
From: Dmitrij Pochepko 
Date: Fri, 10 Jul 2020 15:42:40 +0300
Subject: [PATCH] __builtin_shuffle sometimes should produce zip1 rather than
 TBL (PR82199)

The following patch enables vector permutations optimization by using another vector element size when applicable.
It allows usage of simpler instructions in applicable cases.

example:

vector float f(vector float a, vector float b)
{
  return __builtin_shuffle  (a, b, (vector int){0, 1, 4,5});
}

was compiled into:
...
	adrpx0, .LC0
	ldr q2, [x0, #:lo12:.LC0]
	tbl v0.16b, {v0.16b - v1.16b}, v2.16b
...

and after patch:
...
zip1v0.2d, v0.2d, v1.2d
...

bootstrapped and tested on aarch64-linux-gnu with no regressions

gcc/ChangeLog:

2020-07-10 Andrew Pinski   

	PR gcc/82199

	* gcc/config/aarch64/aarch64.c (aarch64_evpc_reencode): New function

gcc/testsuite/ChangeLog:

2020-07-10  Andrew Pinski   

	PR gcc/82199

	* gcc.target/aarch64/vdup_n_3.c: New test
	* gcc.target/aarch64/vzip_1.c: New test
	* gcc.target/aarch64/vzip_2.c: New test
	* gcc.target/aarch64/vzip_3.c: New test
	* gcc.target/aarch64/vzip_4.c: New test

Co-Authored-By: Dmitrij Pochepko
---
 gcc/config/aarch64/aarch64.c| 57 +
 gcc/testsuite/gcc.target/aarch64/vdup_n_3.c | 16 
 gcc/testsuite/gcc.target/aarch64/vzip_1.c   | 11 ++
 gcc/testsuite/gcc.target/aarch64/vzip_2.c   | 12 ++
 gcc/testsuite/gcc.target/aarch64/vzip_3.c   | 12 ++
 gcc/testsuite/gcc.target/aarch64/vzip_4.c   | 12 ++
 6 files changed, 120 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/vdup_n_3.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/vzip_1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/vzip_2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/vzip_3.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/vzip_4.c

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 17dbe67..9b31743 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -19991,6 +19991,8 @@ struct expand_vec_perm_d
   bool testing_p;
 };
 
+static bool aarch64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d);
+
 /* Generate a variable permutation.  */
 
 static void
@@ -20176,6 +20178,59 @@ aarch64_evpc_trn (struct expand_vec_perm_d *d)
   return true;
 }
 
+/* Try to re-encode the PERM constant so it combines odd and even elements.
+   This rewrites constants such as {0, 1, 4, 5}/V4SF to {0, 2}/V2DI.
+   We retry with this new constant with the full suite of patterns.  */
+static bool
+aarch64_evpc_reencode (struct expand_vec_perm_d *d)
+{
+  expand_vec_perm_d newd;
+  unsigned HOST_WIDE_INT nelt;
+
+  if (d->vec_flags != VEC_ADVSIMD)
+return false;
+
+  /* Get the new mode.  Always twice the size of the inner
+ and half the elements.  */
+  poly_uint64 vec_bits = GET_MODE_BITSIZE (d->vmode);
+  unsigned int new_elt_bits = GET_MODE_UNIT_BITSIZE (d->vmode) * 2;
+  auto new_elt_mode = int_mode_for_size (new_elt_bits, false).require ();
+  machine_mode new_mode = aarch64_simd_container_mode (new_elt_mode, vec_bits);
+
+  if (new_mode == word_mode)
+return false;
+
+  /* to_constant is safe since this routine is specific to Advanced SIMD
+ vectors.  */
+  nelt = d->perm.length ().to_constant ();
+
+  vec_perm_builder newpermconst;
+  newpermconst.new_vector (nelt / 2, nelt / 2, 1);
+
+  /* Convert the perm constant if we can.  Require even, odd as the pairs.  */
+  for (unsigned int i = 0; i < nelt; i += 2)
+{
+  poly_int64 elt0 = d->perm[i];
+  poly_int64 elt1 = d->perm[i + 1];
+  poly_int64 newelt;
+  if (!multiple_p (elt0, 2, ) || maybe_ne (elt0 + 1, elt1))
+	return false;
+  newpermconst.quick_push (elt0.to_constant () / 2);
+}
+  newpermconst.finalize ();
+
+  newd.vmode = new_mode;
+  newd.vec_flags = VEC_ADVSIMD;
+  newd.target = d->target ? gen_lowpart (new_mode, d->target) : NULL;
+  newd.op0 = d->op0 ? gen_lowpart (new_mode, d->op0) : NULL;
+  newd.op1 = d->op1 ? gen_lowpart (new_mode, d->op1) : NULL;
+  newd.testing_p = d->testing_p;
+  newd.one_vector_p = d->one_vector_p;
+
+  newd.perm.new_vector (newpermconst, newd.one_vector_p ? 1 : 2, nelt / 2);
+  return aarch64_expand_vec_perm_const_1 ();
+}
+
 /* Recognize patterns suitable for the UZP instructions.  */
 

[PATCH] testsuite: Fix WPA scanning.

2020-07-10 Thread Martin Liška

Installed to master.

Martin

gcc/testsuite/ChangeLog:

PR gcov-profile/96148
* lib/scanwpaipa.exp: Fix wpa dump file suffix the same way
as other in the file.
---
 gcc/testsuite/lib/scanwpaipa.exp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/lib/scanwpaipa.exp b/gcc/testsuite/lib/scanwpaipa.exp
index cc50cc4c9c4..c0706ff28d2 100644
--- a/gcc/testsuite/lib/scanwpaipa.exp
+++ b/gcc/testsuite/lib/scanwpaipa.exp
@@ -60,11 +60,11 @@ proc scan-pgo-wpa-ipa-dump { args } {
 }
 if { [llength $args] >= 3 } {
scan-dump "pgo-wpa-ipa" [lindex $args 0] \
- "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".x02.wpa" \
+ "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" \
  [lindex $args 2]
 } else {
scan-dump "pgo-wpa-ipa" [lindex $args 0] \
- "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".x02.wpa"
+ "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa"
 }
 }
 
--

2.27.0



[pushed] c++: Support non-type template parms of union type.

2020-07-10 Thread Jason Merrill via Gcc-patches
Another thing newly allowed by P1907R1.  The ABI group has discussed
representing unions with designated initializers, and has separately
specified how to represent designators; this patch implements both.

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

gcc/cp/ChangeLog:

* tree.c (structural_type_p): Allow unions.
* mangle.c (write_expression): Express unions with a designator.

libiberty/ChangeLog:

* cp-demangle.c (cplus_demangle_operators): Add di, dx, dX.
(d_expression_1): Handle di and dX.
(is_designated_init, d_maybe_print_designated_init): New.
(d_print_comp_inner): Use d_maybe_print_designated_init.
* testsuite/demangle-expected: Add designator tests.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/nontype-class-union1.C: New test.
---
 gcc/cp/mangle.c   | 11 ++-
 gcc/cp/tree.c |  7 --
 .../g++.dg/cpp2a/nontype-class-union1.C   | 25 ++
 libiberty/cp-demangle.c   | 77 ++-
 libiberty/testsuite/demangle-expected |  9 +++
 5 files changed, 119 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class-union1.C

diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 090fb529a98..ab2d8ecf2f2 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -3189,6 +3189,7 @@ write_expression (tree expr)
{
  vec *elts = CONSTRUCTOR_ELTS (expr);
  unsigned last_nonzero = UINT_MAX, i;
+ constructor_elt *ce;
  tree val;
 
  if (!nontriv)
@@ -3197,12 +3198,18 @@ write_expression (tree expr)
last_nonzero = i;
 
  if (nontriv || last_nonzero != UINT_MAX)
-   FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val)
+   for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, ); ++i)
  {
if (i > last_nonzero)
  break;
/* FIXME handle RANGE_EXPR */
-   write_expression (val);
+   if (TREE_CODE (etype) == UNION_TYPE)
+ {
+   /* Express the active member as a designator.  */
+   write_string ("di");
+   write_unqualified_name (ce->index);
+ }
+   write_expression (ce->value);
  }
}
  else
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 9effd27f587..1fcba55313a 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -4534,13 +4534,6 @@ structural_type_p (tree t, bool explain)
structural types or (possibly multi-dimensional) array thereof.  */
   if (!CLASS_TYPE_P (t))
 return false;
-  if (TREE_CODE (t) == UNION_TYPE)
-{
-  /* FIXME allow (and mangle) unions.  */
-  if (explain)
-   inform (location_of (t), "%qT is a union", t);
-  return false;
-}
   if (!literal_type_p (t))
 {
   if (explain)
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class-union1.C 
b/gcc/testsuite/g++.dg/cpp2a/nontype-class-union1.C
new file mode 100644
index 000..038d46fdac8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class-union1.C
@@ -0,0 +1,25 @@
+// { dg-do compile { target c++20 } }
+
+template  struct A {};
+template  struct assert_same;
+template  struct assert_same {};
+
+#define TEQ(X,Y) static_assert(__is_same(A<(X)>,A<(Y)>))
+#define TNEQ(X,Y) static_assert(!__is_same(A<(X)>,A<(Y)>))
+
+union U {
+  int i; int j;
+  constexpr U(int i): i(i) {}
+  constexpr U(unsigned u): j(u) {}
+};
+
+TEQ(U(0),U(0));
+
+// Calling the other constructor initializes a different member with the same
+// value.  We need to distinguish these.
+TNEQ(U(0),U(0u));
+
+// { dg-final { scan-assembler "_Z1f1AIXtl1Udi1iLi0" } }
+void f(A) { }
+// { dg-final { scan-assembler "_Z1g1AIXtl1Udi1jLi0" } }
+void g(A) { }
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index cbfb2f937ca..b413ba2be5f 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -1809,13 +1809,16 @@ const struct demangle_operator_info 
cplus_demangle_operators[] =
   { "cm", NL (","), 2 },
   { "co", NL ("~"), 1 },
   { "dV", NL ("/="),2 },
+  { "dX", NL ("[...]="), 3 }, /* [expr...expr] = expr */
   { "da", NL ("delete[] "), 1 },
   { "dc", NL ("dynamic_cast"), 2 },
   { "de", NL ("*"), 1 },
+  { "di", NL ("="), 2 }, /* .name = expr */
   { "dl", NL ("delete "),   1 },
   { "ds", NL (".*"),2 },
   { "dt", NL ("."), 2 },
   { "dv", NL ("/"), 2 },
+  { "dx", NL ("]="),2 }, /* [expr] = expr */
   { "eO", NL ("^="),2 },
   { "eo", NL ("^"), 2 },
   { "eq", NL ("=="),2 },
@@ -3291,6 +3294,12 @@ op_is_new_cast (struct demangle_component *op)
 ::= sr  
 ::= sr   
 ::= 
+
+   ::= 
+ ::= di 

[pushed] c++: Allow floating-point template parms in C++20.

2020-07-10 Thread Jason Merrill via Gcc-patches
P1907R1 made various adjustments to non-type template parameters, notably
introducing the notion of "structural type".  I implemented an early version
of that specification in r10-4426, but it was adjusted in the final paper to
allow more.  This patch implements allowing template parameters of
floating-point type; still to be implemented are unions and subobjects.

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

gcc/cp/ChangeLog:

* pt.c (convert_nontype_argument): Handle REAL_TYPE.
(invalid_nontype_parm_type_p): Allow all structural types.
* tree.c (structural_type_p): Use SCALAR_TYPE_P.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/pr81246.C: No error in C++20.
* g++.dg/cpp0x/variadic74.C: No error in C++20.
* g++.dg/cpp1z/nontype-auto3.C: No error in C++20.
* g++.dg/template/crash106.C: No error in C++20.
* g++.dg/template/crash119.C: No error in C++20.
* g++.dg/template/nontype12.C: No error in C++20.
* g++.dg/template/void3.C: Don't require follow-on message.
* g++.dg/template/void7.C: Don't require follow-on message.
* g++.dg/template/void9.C: Don't require follow-on message.
---
 gcc/cp/pt.c   | 47 ++-
 gcc/cp/tree.c | 34 --
 gcc/testsuite/g++.dg/cpp0x/pr81246.C  |  2 +-
 gcc/testsuite/g++.dg/cpp0x/variadic74.C   |  2 +-
 gcc/testsuite/g++.dg/cpp1z/nontype-auto3.C|  2 +-
 .../g++.dg/cpp2a/nontype-class-equiv1.C   | 25 ++
 gcc/testsuite/g++.dg/template/crash106.C  |  8 ++--
 gcc/testsuite/g++.dg/template/crash119.C  |  2 +-
 gcc/testsuite/g++.dg/template/nontype12.C | 20 
 gcc/testsuite/g++.dg/template/void3.C |  2 +-
 gcc/testsuite/g++.dg/template/void7.C |  2 +-
 gcc/testsuite/g++.dg/template/void9.C |  2 +-
 12 files changed, 89 insertions(+), 59 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class-equiv1.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b6423f7432b..61f22733858 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7257,7 +7257,8 @@ convert_nontype_argument (tree type, tree expr, 
tsubst_flags_t complain)
  For a non-type template-parameter of integral or enumeration type,
  integral promotions (_conv.prom_) and integral conversions
  (_conv.integral_) are applied.  */
-  if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+  if (INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+  || TREE_CODE (type) == REAL_TYPE)
 {
   if (cxx_dialect < cxx11)
{
@@ -7272,7 +7273,7 @@ convert_nontype_argument (tree type, tree expr, 
tsubst_flags_t complain)
 
   /* Notice that there are constant expressions like '4 % 0' which
 do not fold into integer constants.  */
-  if (TREE_CODE (expr) != INTEGER_CST && !val_dep_p)
+  if (!CONSTANT_CLASS_P (expr) && !val_dep_p)
{
  if (complain & tf_error)
{
@@ -7287,7 +7288,7 @@ convert_nontype_argument (tree type, tree expr, 
tsubst_flags_t complain)
return NULL_TREE;
  /* else cxx_constant_value complained but gave us
 a real constant, so go ahead.  */
- if (TREE_CODE (expr) != INTEGER_CST)
+ if (!CONSTANT_CLASS_P (expr))
{
  /* Some assemble time constant expressions like
 (intptr_t)& - (intptr_t)& or
@@ -7297,7 +7298,7 @@ convert_nontype_argument (tree type, tree expr, 
tsubst_flags_t complain)
 compile time.  Refuse them here.  */
  gcc_checking_assert (reduced_constant_expression_p (expr));
  error_at (loc, "template argument %qE for type %qT not "
-"a constant integer", expr, type);
+"a compile-time constant", expr, type);
  return NULL_TREE;
}
}
@@ -26127,31 +26128,31 @@ invalid_nontype_parm_type_p (tree type, 
tsubst_flags_t complain)
   else if (cxx_dialect >= cxx11
   && TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
 return false;
-  else if (CLASS_TYPE_P (type))
+  else if (VOID_TYPE_P (type))
+/* Fall through.  */;
+  else if (cxx_dialect >= cxx20)
 {
-  if (cxx_dialect < cxx20)
-   {
- if (complain & tf_error)
-   error ("non-type template parameters of class type only available "
-  "with %<-std=c++20%> or %<-std=gnu++20%>");
- return true;
-   }
   if (dependent_type_p (type))
return false;
-  if (!complete_type_or_else (type, NULL_TREE))
+  if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
return true;
-  if (!structural_type_p (type))
+  if (structural_type_p (type))
+   return false;
+  if (complain & tf_error)
{
- if (complain & tf_error)
-   {
- auto_diagnostic_group d;
-  

[pushed] c++: [[no_unique_address]] fixes. [PR96105]

2020-07-10 Thread Jason Merrill via Gcc-patches
We were wrongly checking is_empty_class on the result of strip_array_types
rather than the actual field type.  We weren't considering the alignment of
the data member.  We needed to handle unions the same way as
layout_nonempty_base_or_field.

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

gcc/cp/ChangeLog:

PR c++/96105
PR c++/96052
PR c++/95976
* class.c (check_field_decls): An array of empty classes is not an
empty data member.
(layout_empty_base_or_field): Handle explicit alignment.
Fix union handling.

gcc/testsuite/ChangeLog:

PR c++/96105
PR c++/96052
PR c++/95976
* g++.dg/cpp2a/no_unique_address4.C: New test.
* g++.dg/cpp2a/no_unique_address5.C: New test.
* g++.dg/cpp2a/no_unique_address6.C: New test.
---
 gcc/cp/class.c| 27 ++-
 .../g++.dg/cpp2a/no_unique_address4.C | 22 +++
 .../g++.dg/cpp2a/no_unique_address5.C | 25 +
 .../g++.dg/cpp2a/no_unique_address6.C | 25 +
 4 files changed, 92 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/no_unique_address4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/no_unique_address5.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/no_unique_address6.C

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 7b5f1669d04..14380c7a08c 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3718,7 +3718,8 @@ check_field_decls (tree t, tree *access_decls,
/* We don't treat zero-width bitfields as making a class
   non-empty.  */
;
-  else if (field_poverlapping_p (field) && is_empty_class (type))
+  else if (field_poverlapping_p (field)
+  && is_empty_class (TREE_TYPE (field)))
/* Empty data members also don't make a class non-empty.  */
CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
   else
@@ -4385,15 +4386,20 @@ layout_empty_base_or_field (record_layout_info rli, 
tree binfo_or_decl,
 
   /* This routine should only be used for empty classes.  */
   gcc_assert (is_empty_class (type));
-  alignment = size_int (CLASSTYPE_ALIGN_UNIT (type));
+
+  if (decl && DECL_USER_ALIGN (decl))
+alignment = size_int (DECL_ALIGN_UNIT (decl));
+  else
+alignment = size_int (CLASSTYPE_ALIGN_UNIT (type));
 
   /* This is an empty base class.  We first try to put it at offset
  zero.  */
   tree offset = size_zero_node;
-  if (layout_conflict_p (type,
-offset,
-offsets,
-/*vbases_p=*/0))
+  if (TREE_CODE (rli->t) != UNION_TYPE
+  && layout_conflict_p (type,
+   offset,
+   offsets,
+   /*vbases_p=*/0))
 {
   /* That didn't work.  Now, we move forward from the next
 available spot in the class.  */
@@ -4413,7 +4419,14 @@ layout_empty_base_or_field (record_layout_info rli, tree 
binfo_or_decl,
}
 }
 
-  if (CLASSTYPE_USER_ALIGN (type))
+  if (decl && DECL_USER_ALIGN (decl))
+{
+  rli->record_align = MAX (rli->record_align, DECL_ALIGN (decl));
+  if (warn_packed)
+   rli->unpacked_align = MAX (rli->unpacked_align, DECL_ALIGN (decl));
+  TYPE_USER_ALIGN (rli->t) = 1;
+}
+  else if (CLASSTYPE_USER_ALIGN (type))
 {
   rli->record_align = MAX (rli->record_align, CLASSTYPE_ALIGN (type));
   if (warn_packed)
diff --git a/gcc/testsuite/g++.dg/cpp2a/no_unique_address4.C 
b/gcc/testsuite/g++.dg/cpp2a/no_unique_address4.C
new file mode 100644
index 000..2fe44e37163
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/no_unique_address4.C
@@ -0,0 +1,22 @@
+// PR c++/96105
+// { dg-do compile { target c++20 } }
+
+struct Empty {};
+
+struct A {
+  Empty emp [[no_unique_address]][3];
+};
+
+struct B : A {
+  float f;
+};
+
+struct C {
+  Empty emp [[no_unique_address]][3];
+  float f;
+};
+
+extern char szc[sizeof(C)];
+extern char szc[sizeof(float) * 2];  // GCC likes this
+extern char szb[sizeof(B)];
+extern char szb[sizeof(float) * 2];  // GCC does not like this
diff --git a/gcc/testsuite/g++.dg/cpp2a/no_unique_address5.C 
b/gcc/testsuite/g++.dg/cpp2a/no_unique_address5.C
new file mode 100644
index 000..5fca35dbd81
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/no_unique_address5.C
@@ -0,0 +1,25 @@
+// PR c++/96052
+// { dg-do compile { target c++20 } }
+
+struct Q {
+  struct {
+  } emp alignas(8) [[no_unique_address]];
+  char x;
+};
+struct QQ {
+  char x;
+  Q q;
+};
+
+struct Z {
+  char x alignas(8) [[no_unique_address]];
+};
+struct ZZ {
+  char x;
+  Z z;
+};
+
+extern char qx[sizeof(QQ)];
+extern char qx[16];
+extern char qz[sizeof(ZZ)];
+extern char qz[16];
diff --git a/gcc/testsuite/g++.dg/cpp2a/no_unique_address6.C 
b/gcc/testsuite/g++.dg/cpp2a/no_unique_address6.C
new file mode 100644
index 000..427db4439dd
--- /dev/null
+++ 

Re: [PATCH v2]: Optimize a >= 0 && b >= 0 to (a | b) >= 0 [PR95731]

2020-07-10 Thread Marc Glisse

On Fri, 10 Jul 2020, Joe Ramsay wrote:


adds a new pattern to simplify a >= 0 && b >= 0 to (a | b) >= 0.


We should probably add the symmetric simplification of a<0|b<0 to (a|b)<0


   * match.pd: New simplication.


I think Jakub was suggesting something slightly mode detailed.

It would be nice to put the transformation next to "(x == 0 & y == 0) -> 
(x | typeof(x)(y)) == 0." in the file, since they work similarly.


+(for and (truth_and truth_andif)

I think the most important one here is bit_and.

+  (and (ge @0 integer_zerop) (ge @1 integer_zerop))

I was expecting some :s on the ge, but I notice that we don't have them 
for the similar transformation, so I don't know...


+   If one type is wider then the narrower type is sign-extended

Is that necessarily a sign-extension? True, for an unsigned type, we 
usually replace >=0 with !=0 IIRC, but it wouldn't hurt to add an explicit 
check for that.


+  (if (   INTEGRAL_TYPE_P (TREE_TYPE (@0))
+   && INTEGRAL_TYPE_P (TREE_TYPE (@1)))

I like indenting to align things, but I don't think that matches the 
official style used in gcc.


I am always afraid that this kind of transformation may hurt if it happens 
too early (does VRP know how to get ranges for a and b from (a|b)>=0?) but 
I guess this isn't the first transformation in this direction, so we can 
see all of them later if it causes trouble...


If the types are int128_t and int64_t, is extending the right thing to do? 
Will it eventually simplify to ((int64_t)(i128>>64)|i64)>=0


--
Marc Glisse


Re: [PATCH 3/9] [OpenACC] Adjust dynamic reference count semantics

2020-07-10 Thread Julian Brown
On Fri, 3 Jul 2020 17:41:12 +0200
Thomas Schwinge  wrote:

> Hi Julian!
> 
> On 2020-06-30T15:51:14+0200, I wrote:
> > On 2020-06-16T15:38:33-0700, Julian Brown 
> > wrote:  
> >> This is a new version of the patch last sent here:
> >>
> >> https://gcc.gnu.org/pipermail/gcc-patches/2020-May/546332.html
> >>
> >> Minus the bits that Thomas has committed already (thanks!), and
> >> with adjustments to allow for GOMP_MAP_ATTACH being grouped
> >> together with a preceding clause.
> >>
> >> OK?  
> >
> > Please also update the "virtual refcount" comment in
> > 'libgomp.oacc-c-c++-common/structured-dynamic-lifetimes-4.c'.
> >
> > Your patch now makes the
> > 'libgomp.oacc-fortran/mdc-refcount-1-1-1.f90',
> > 'libgomp.oacc-fortran/mdc-refcount-1-2-1.f90',
> > 'libgomp.oacc-fortran/mdc-refcount-1-2-2.f90',
> > 'libgomp.oacc-fortran/mdc-refcount-1-3-1.f90' test cases PASS (did
> > you not see that?)  
> 
> Ah, you said "Tested (as a series)", so that's probably why I saw this
> intermediate step but you didn't.
> 
> > so we have to remove all XFAILing, 'print'/'dg-output'
> > etc. from these, and it changes the error reporting in
> > 'libgomp.oacc-fortran/mdc-refcount-1-4-1.f90', so we have to adjust
> > that. See attached patch "into Adjust dynamic reference count
> > semantics".  
> 
> Given my recent "[OpenACC] Revert always-copyfrom behavior for
> 'GOMP_MAP_FORCE_FROM' in
> 'libgomp/oacc-mem.c:goacc_exit_data_internal'",
> <87wo3ky5vn.fsf@euler.schwinge.homeip.net">http://mid.mail-archive.com/87wo3ky5vn.fsf@euler.schwinge.homeip.net>,
> please also include the attached "into 'Adjust dynamic reference
> count semantics': un-XFAIL 'libgomp.oacc-c-c++-common/pr92843-1.c'".
> 
> 
> > Your patch regresses the attached
> > 'libgomp.oacc-c-c++-common/struct-3-1-1.c'  
> 
> That was confusing: that's a new test case, not yet in tree.

I've posted a new version of the patch here that (hopefully!) addresses
all review comments:

https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549774.html

Thanks,

Julian


Re: [PATCH 3/7] [OpenACC] Don't pass kind array via pointer to goacc_enter_datum

2020-07-10 Thread Julian Brown
On Thu, 25 Jun 2020 12:52:23 +0200
Thomas Schwinge  wrote:

> Hi Julian!
> 
> On 2020-05-22T15:16:06-0700, Julian Brown 
> wrote:
> > Since goacc_enter_datum only maps a single data item now, there is
> > no need to pass "kinds" as an array.  Passing as a scalar allows
> > for some simplification in the function's callers.  
> 
> You'd hope (didn't verify) that the compiler can do the same
> transformation/optimization.  ;-)
> 
> But, au contraire: in my opinion (but please tell if you disagree), we
> should instead get (back) to the state where the runtime API and the
> pragma variants of the respective OpenACC functionality map to the
> same libgomp implementation.

It's a little ugly for "enter data" because the API routines return the
device pointer, but the directive implementation may involve several
mappings and a single "device pointer" return doesn't really make sense
in that case. I didn't much like the previous approach of returning
NULL.

We can still try to factor out the duplicated code though. I've posted a
new approach here (see the parent "0/2" patch also):

https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549773.html

Julian


Re: [PATCH] x86: Check TARGET_AVX512VL when enabling FMA

2020-07-10 Thread H.J. Lu via Gcc-patches
On Fri, Jul 10, 2020 at 4:19 AM Jakub Jelinek  wrote:
>
> On Thu, Jul 09, 2020 at 03:02:35PM -0700, H.J. Lu via Gcc-patches wrote:
> --- a/gcc/config/i386/i386-expand.c
> +++ b/gcc/config/i386/i386-expand.c
> @@ -15540,7 +15540,11 @@ void ix86_emit_swsqrtsf (rtx res, rtx a, 
> machine_mode mode, bool recip)
>/* e0 = x0 * a */
>emit_insn (gen_rtx_SET (e0, gen_rtx_MULT (mode, x0, a)));
>
> -  if (TARGET_FMA || TARGET_AVX512F)
> +  unsigned vector_size = GET_MODE_SIZE (mode);
> +  if (TARGET_FMA
> +  || (TARGET_AVX512F && vector_size == 64)
> +  || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16)))
> +
>  emit_insn (gen_rtx_SET (e2,
>
> Why the empty line in there?
> Ok for trunk with that fixed.
>
> gen_rtx_FMA (mode, e0, x0, mthree)));
>else

This is the patch I am checking in.

Thanks.

-- 
H.J.
From 2bcd21b9142cdf75fc166a73206518b8754f5b6a Mon Sep 17 00:00:00 2001
From: "H.J. Lu" 
Date: Thu, 9 Jul 2020 14:56:48 -0700
Subject: [PATCH] x86: Check TARGET_AVX512VL when enabling FMA

Check TARGET_AVX512VL when enabling FMA to avoid

gcc.target/i386/avx512er-vrsqrt28ps-3.c:25:1: error: unrecognizable insn:
(insn 29 28 30 6 (set (reg:V8SF 108)
(fma:V8SF (reg:V8SF 106)
(reg:V8SF 105)
(reg:V8SF 110)))

when TARGET_AVX512VL isn't enabled.

	PR target/96144
	* config/i386/i386-expand.c (ix86_emit_swsqrtsf): Check
	TARGET_AVX512VL when enabling FMA.
---
 gcc/config/i386/i386-expand.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index 49718b7a41c..e194214804b 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -15540,7 +15540,10 @@ void ix86_emit_swsqrtsf (rtx res, rtx a, machine_mode mode, bool recip)
   /* e0 = x0 * a */
   emit_insn (gen_rtx_SET (e0, gen_rtx_MULT (mode, x0, a)));
 
-  if (TARGET_FMA || TARGET_AVX512F)
+  unsigned vector_size = GET_MODE_SIZE (mode);
+  if (TARGET_FMA
+  || (TARGET_AVX512F && vector_size == 64)
+  || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16)))
 emit_insn (gen_rtx_SET (e2,
 			gen_rtx_FMA (mode, e0, x0, mthree)));
   else
-- 
2.26.2



[PATCH v2]: Optimize a >= 0 && b >= 0 to (a | b) >= 0 [PR95731]

2020-07-10 Thread Joe Ramsay
Hi!

Apologies, resending as I previously attached the wrong patch file. This is a 
fix for PR95731, which adds a new pattern to simplify a >= 0 && b >= 0 to (a | 
b) >= 0. Bootstrapped and tested on x86_linux and aarch64_linux. Any comments 
are appreciated.

Thanks,
Joe

gcc/ChangeLog:

2020-05-20  Joe Ramsay  mailto:joe.ram...@arm.com>>

* match.pd: New simplication.

gcc/testsuite/ChangeLog:

2020-05-20  Joe Ramsay  mailto:joe.ram...@arm.com>>

* gcc.dg/tree-ssa/pr95731-1.c: New test.
* gcc.dg/tree-ssa/pr95731-2.c: New test.



pr95731.diff
Description: pr95731.diff


Re: [PATCH] x86: Check TARGET_AVX512VL when enabling FMA

2020-07-10 Thread Jakub Jelinek via Gcc-patches
On Thu, Jul 09, 2020 at 03:02:35PM -0700, H.J. Lu via Gcc-patches wrote:
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -15540,7 +15540,11 @@ void ix86_emit_swsqrtsf (rtx res, rtx a, machine_mode 
mode, bool recip)
   /* e0 = x0 * a */
   emit_insn (gen_rtx_SET (e0, gen_rtx_MULT (mode, x0, a)));
 
-  if (TARGET_FMA || TARGET_AVX512F)
+  unsigned vector_size = GET_MODE_SIZE (mode);
+  if (TARGET_FMA
+  || (TARGET_AVX512F && vector_size == 64)
+  || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16)))
+
 emit_insn (gen_rtx_SET (e2,

Why the empty line in there?
Ok for trunk with that fixed.

gen_rtx_FMA (mode, e0, x0, mthree)));
   else
-- 
2.26.2



Jakub



Re: [PATCH v4] arm: Implement Armv8.1-M low overhead loops

2020-07-10 Thread Andrea Corallo
Kyrylo Tkachov  writes:

[...]

>
> Ok.
> Thanks for doing this.
> Kyrill

Hi Kyrill,

installed into trunk as d2ed233cb940.

Thanks

  Andrea


Re: [PATCH] x86: Check TARGET_AVX512VL when enabling FMA

2020-07-10 Thread H.J. Lu via Gcc-patches
On Thu, Jul 9, 2020 at 3:02 PM H.J. Lu  wrote:
>
> On Thu, Jul 9, 2020 at 6:35 AM H.J. Lu  wrote:
> >
> > On Thu, Jul 9, 2020 at 5:04 AM Kirill Yukhin  
> > wrote:
> > >
> > > On 07 июл 09:06, H.J. Lu wrote:
> > > > On Tue, Jul 7, 2020 at 8:56 AM Kirill Yukhin  
> > > > wrote:
> > > > >
> > > > > Hello HJ,
> > > > >
> > > > > On 28 июн 07:19, H.J. Lu via Gcc-patches wrote:
> > > > > > Enable FMA in rsqrt2 expander and fold rsqrtv16sf2 expander 
> > > > > > into
> > > > > > rsqrt2 expander which expands to UNSPEC_RSQRT28 for 
> > > > > > TARGET_AVX512ER.
> > > > > > Although it doesn't show performance change in our workloads, FMA 
> > > > > > can
> > > > > > improve other workloads.
> > > > > >
> > > > > > gcc/
> > > > > >
> > > > > >   PR target/88713
> > > > > >   * config/i386/i386-expand.c (ix86_emit_swsqrtsf): Enable FMA.
> > > > > >   * config/i386/sse.md (VF_AVX512VL_VF1_128_256): New.
> > > > > >   (rsqrt2): Replace VF1_128_256 with 
> > > > > > VF_AVX512VL_VF1_128_256.
> > > > > >   (rsqrtv16sf2): Removed.
> > > > > >
> > > > > > gcc/testsuite/
> > > > > >
> > > > > >   PR target/88713
> > > > > >   * gcc.target/i386/pr88713-1.c: New test.
> > > > > >   * gcc.target/i386/pr88713-2.c: Likewise.
> > > > >
> > > > > So, you've introduced new rsqrt expanders for DF vectors and relaxed
> > > > > condition for V16SF. What I didn't get is why did you change unspec
> > > > > type from RSQRT to RSQRT28 for V16SF expander?
> > > > >
> > > >
> > > > UNSPEC in define_expand is meaningless when the pattern is fully
> > > > expanded by ix86_emit_swsqrtsf.  I believe that UNSPEC in rsqrt2
> > > > expander can be removed.
> > >
> > > Agree.
> >
> > I will leave UNSPEC alone here.
> >
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.target/i386/pr88713-1.c
> > > @@ -0,0 +1,13 @@
> > > +/* { dg-do compile } */
> > > +/* { dg-options "-O2 -Ofast -mno-avx512f -mfma" } */
> > >
> > > I gues -O2 is useless here (and in -2.c test).
> >
> > Fixed.
> >
> > > Othwerwise LGTM.
> > >
> >
> > This is the patch I am checking in.
> >
>
> This patch is needed for
>
> FAIL: gcc.target/i386/avx512er-vrsqrt28ps-3.c (internal compiler error)
> FAIL: gcc.target/i386/avx512er-vrsqrt28ps-3.c (test for excess errors)
> FAIL: gcc.target/i386/avx512er-vrsqrt28ps-4.c (internal compiler error)
> FAIL: gcc.target/i386/avx512er-vrsqrt28ps-4.c (test for excess errors)
> FAIL: gcc.target/i386/avx512er-vrsqrt28ps-5.c (internal compiler error)
> FAIL: gcc.target/i386/avx512er-vrsqrt28ps-5.c (test for excess errors)
> FAIL: gcc.target/i386/avx512er-vrsqrt28ps-6.c (internal compiler error)
> FAIL: gcc.target/i386/avx512er-vrsqrt28ps-6.c (test for excess errors)
>

This fixed:

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

-- 
H.J.


Re: [PATCH]: Optimize a >= 0 && b >= 0 to (a | b) >= 0 [PR95731]

2020-07-10 Thread Jakub Jelinek via Gcc-patches
On Fri, Jul 10, 2020 at 10:50:22AM +, Joe Ramsay wrote:
> gcc/ChangeLog:
> 
> 2020-05-20  Joe Ramsay  
> 
> * match.pd: New pattern to optimize a >= 0 && b >= 0 to (a | b) >= 0

Better
* match.pd (a >= 0 && b >= 0 to (a | b) >= 0): New simplification.
(and note the period at the end).

> gcc/testsuite/ChangeLog:
> 
> 2020-05-20  Joe Ramsay  
> 
> * gcc.dg/tree-ssa/pr95731-1.c: New test.
> * gcc.dg/tree-ssa/pr95731-2.c: New test.
> 

The attached patch is unrelated to that though.

Jakub



[PATCH]: Optimize a >= 0 && b >= 0 to (a | b) >= 0 [PR95731]

2020-07-10 Thread Joe Ramsay
Hi!

This is a fix for PR95731, which adds a new pattern to simplify a >= 0 && b >= 
0 to (a | b) >= 0. Bootstrapped and tested on x86_linux and aarch64_linux. Any 
comments are appreciated.

Thanks,
Joe

gcc/ChangeLog:

2020-05-20  Joe Ramsay  

* match.pd: New pattern to optimize a >= 0 && b >= 0 to (a | b) >= 0

gcc/testsuite/ChangeLog:

2020-05-20  Joe Ramsay  

* gcc.dg/tree-ssa/pr95731-1.c: New test.
* gcc.dg/tree-ssa/pr95731-2.c: New test.



pr95731.diff
Description: pr95731.diff


Re: [PATCH] middle-end: Improve RTL expansion in expand_mul_overflow,

2020-07-10 Thread Richard Sandiford
"Roger Sayle"  writes:
> Hi Richard,
>
>> On Thu, Jul 09, 2020 at 09:17:46AM +0100, Richard Sandiford wrote:
>>> > +   res = force_reg (mode, res);
>>> 
>>> In general, this can be dangerous performance-wise on targets where 
>>> subregs are free.  If the move survives to the register allocators, 
>>> it increases the risk that the move will become a machine insn.
>>> (The RA will prefer to tie the registers, but that isn't guaranteed.)
>
> I believe I can use exactly the same test case, but compiled on ARM, to
> demonstrate that placing reused intermediate values in pseudo registers
> instead of SUBREGs is potentially preferable and at least no worse
> (certainly not "dangerous").

OK.  Sorry for the noise then, please go ahead with the patch.

Thanks,
Richard


Re: [PATCH] remove premature vect_verify_datarefs_alignment

2020-07-10 Thread Kewen.Lin via Gcc-patches
on 2020/7/9 下午7:22, Richard Biener wrote:
> On Thu, 9 Jul 2020, Kewen.Lin wrote:
> 
>> on 2020/7/9 上午10:48, Kewen.Lin via Gcc-patches wrote:
>>> Hi Richi,
>>>
>>> on 2020/7/8 下午10:45, Richard Biener wrote:
 This followup removes vect_verify_datarefs_alignment and its
 premature cancellation of vectorization leaving the actual
 decision whether alignment is supported to the functions
 deciding whether we can vectorize a load or store.

 I'll see whether to find a suitable machine to test !hw_misalign_supported
 (altivec-only ppc I think?  hints welcome...), but maybe I'm lazy...

>>>
>>> Thanks for caring about this!  As my limited experience, Power7 machine
>>> is qualified for this even with explicit configuration -mcpu=power7,
>>
>> Oops, sorry I meant --with-cpu=power7.
>>
>>> most of vector test cases will go with -mno-allow-movmisalign there.
>>>
>>> cfarm gcc110 looks fine to use.
>>>
> 
> OK, so that showed a few testcases to adjust, thus I committed the
> following.  In particular gcc.dg/vect/slp-45.c shows we can very
> well vectorize the loops and prematurely failed to.

Thanks for testing!  It sounds nice!

BR,
Kewen


RE: [PATCH v4] arm: Implement Armv8.1-M low overhead loops

2020-07-10 Thread Kyrylo Tkachov
Hi Andrea,

Sorry for the delay

> -Original Message-
> From: Gcc-patches  On Behalf Of
> Andrea Corallo
> Sent: 24 June 2020 11:04
> To: gcc-patches@gcc.gnu.org
> Cc: Richard Earnshaw ; nd ;
> Kyrill Tkachov 
> Subject: Re: [PATCH v4] arm: Implement Armv8.1-M low overhead loops
> 
> Andrea Corallo  writes:
> 
> > Hi all,
> >
> > here the latest version of the patch to enable Armv8.1-M Mainline
> > LOB (low overhead branch) extension low overhead loops (LOL) feature
> > using the 'loop-doloop' pass.
> >
> > I posted a previous version of it during stage 4.
> >
> > Given the following function:
> >
> > void
> > loop (int *a)
> > {
> >   for (int i = 0; i < 1000; i++)
> > a[i] = i;
> > }
> >
> > 'doloop_begin' and 'doloop_end' patterns translates into 'dls' and 'le'
> > giving:
> >
> >  loop:
> >  movwr2, #1
> >  movsr3, #0
> >  subsr0, r0, #4
> >  push{lr}
> >  dls lr, r2
> >  .L2:
> >  str r3, [r0, #4]!
> >  addsr3, r3, #1
> >  le  lr, .L2
> >  ldr pc, [sp], #4
> >
> > bootstrapped arm-none-linux-gnueabihf, does not introduce testsuite
> regressions.
> >
> > Andrea
> 
> Hi,
> 
> double checking I spotted another test impacted by the patch that I
> missed as first.
> 
> Here the updated patch waving the check.
> 
>   Andrea
> 
> gcc/ChangeLog
> 
> 2020-06-18  Andrea Corallo  
> Mihail-Calin Ionescu  
> Iain Apreotesei  
> 
>   * config/arm/arm-protos.h (arm_target_insn_ok_for_lob): New
>   prototype.
> * config/arm/arm.c (TARGET_INVALID_WITHIN_DOLOOP): Define.
> (arm_invalid_within_doloop): Implement invalid_within_doloop hook.
>   (arm_target_insn_ok_for_lob): New function.
> * config/arm/arm.h (TARGET_HAVE_LOB): Define macro.
> * config/arm/thumb2.md (*doloop_end_internal, doloop_begin)
>   (dls_insn): Add new patterns.
>   (doloop_end): Modify to select LR when LOB is available.
> * config/arm/unspecs.md: Add new unspec.
> * doc/sourcebuild.texi (arm_v8_1_lob_ok)
>   (arm_thumb2_ok_no_arm_v8_1_lob): Document new target
> supports
>   options.
> 
> gcc/testsuite/ChangeLog
> 
> 2020-06-18  Andrea Corallo  
> Mihail-Calin Ionescu  
> Iain Apreotesei  
> 
> * gcc.target/arm/lob.h: New header.
> * gcc.target/arm/lob1.c: New testcase.
> * gcc.target/arm/lob2.c: Likewise.
> * gcc.target/arm/lob3.c: Likewise.
> * gcc.target/arm/lob4.c: Likewise.
> * gcc.target/arm/lob5.c: Likewise.
> * gcc.target/arm/lob6.c: Likewise.
>   * gcc.target/arm/unsigned-extend-2.c: Do not run when generating
>   low loop overhead.
>   * gcc.target/arm/ivopts.c: Fix check for low loop overhead.
> * lib/target-supports.exp (check_effective_target_arm_v8_1_lob)
>   (check_effective_target_arm_thumb2_ok_no_arm_v8_1_lob): New
> procs.

Ok.
Thanks for doing this.
Kyrill




RE: [PATCH] middle-end: Improve RTL expansion in expand_mul_overflow,

2020-07-10 Thread Roger Sayle


Hi Richard,

> On Thu, Jul 09, 2020 at 09:17:46AM +0100, Richard Sandiford wrote:
>> > +res = force_reg (mode, res);
>> 
>> In general, this can be dangerous performance-wise on targets where 
>> subregs are free.  If the move survives to the register allocators, 
>> it increases the risk that the move will become a machine insn.
>> (The RA will prefer to tie the registers, but that isn't guaranteed.)

I believe I can use exactly the same test case, but compiled on ARM, to
demonstrate that placing reused intermediate values in pseudo registers
instead of SUBREGs is potentially preferable and at least no worse
(certainly not "dangerous").

The minimal test case for t120_smul is:

void bar(void);
int t120_1smul (int x, int y)
{
  int r;
  if (__builtin_smul_overflow (x, y, ))
bar ();
  return r;
}

which when compiled on arm-linux-gnueabihf generates, both with and
without my patch, the very impressive, near optimal sequence:

t120_1smul:
mov r3, r0
smull   r0, r2, r3, r1
cmp r2, r0, asr #31
bxeqlr
str lr, [sp, #-4]!
sub sp, sp, #12
str r0, [sp, #4]
bl  bar
ldr r0, [sp, #4]
add sp, sp, #12
ldr pc, [sp], #4

Notice that the first argument (output) of smul, r0, is used multiple
times, but thanks to fwprop both the SUBREG and the pseudo forms
are equivalent to the result register, r0, which reload respects.  That
GCC puts the lopart of the widening multiplication directly in the
result register is  awesome.  The use of force_reg in my patch clearly
doesn't hurt.

In fact, the use of a pseudo helps insulate some dubious code
expanded by the ARM backend, the previous assignment to the register
that is forced into a pseudo register actually looks like:

(insn 10 9 11 2 (set (subreg:SI (reg:DI 120) 0)
(ashiftrt:SI (subreg:SI (reg:DI 119) 4)
(const_int 0 [0]))) "t120_1smul.c":5:7 -1
 (nil))

Fortunately this cryptic move instruction eventually gets cleaned up
by the middle-end.

[Minor aside this shift by zero can be avoided by following patch]
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index e15d286..5225df6 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -31324,7 +31324,10 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx 
out, rtx in,

  if (REG_P (out) && REG_P (in) && REGNO (out) != REGNO (in))
emit_insn (SET (out, const0_rtx));
- emit_insn (SET (out_down, SHIFT (code, in_up, adj_amount)));
+ if (adj_amount != const0_rtx)
+   emit_insn (SET (out_down, SHIFT (code, in_up, adj_amount)));
+ else
+   emit_insn (SET (out_down, in_up));
  if (code == ASHIFTRT)
emit_insn (gen_ashrsi3 (out_up, in_up,
GEN_INT (31)));

But to (perhaps) convince you (folks) that pseudo registers are preferable to 
SUBREGs, we need
to take a look at the first two instructions generated in the above test case.

Instead of the current:
mov r3, r0
smull   r0, r2, r3, r1

The optimal sequence on ARM (if my understanding of the ARM documentation on 
register
constraints is correct) would be the single instruction:

smull   r0, r2, r1, r0

As the first three argument registers must be different, but the fourth and 
final register doesn't
conflict with the first three.  We know that we require the first output to be 
r0, but we can use
the commutativity of multiplication to swap r0 and r1 in the third and fourth 
positions, saving
both an instruction and a register!

Alas my attempts to convince GCC to generate this sequence have been 
unsuccessful.
The closest I can get is by using something like:

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index a6a31f8..ece9175 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -2409,11 +2409,11 @@
 )

 (define_insn "mull"
-  [(set (match_operand:SI 0 "s_register_operand" "=r,")
+  [(set (match_operand:SI 0 "s_register_operand" "=r,,,")
(mult:SI
-(match_operand:SI 2 "s_register_operand" "%r,r")
-(match_operand:SI 3 "s_register_operand" "r,r")))
-   (set (match_operand:SI 1 "s_register_operand" "=r,")
+(match_operand:SI 2 "s_register_operand" "%r,r,r,r")
+(match_operand:SI 3 "s_register_operand" "r,r,0,1")))
+   (set (match_operand:SI 1 "s_register_operand" "=r,,,")
(truncate:SI
 (lshiftrt:DI
  (mult:DI (SE:DI (match_dup 2)) (SE:DI (match_dup 3)))
@@ -2422,7 +2422,7 @@
   "mull%?\\t%0, %1, %2, %3"
   [(set_attr "type" "umull")
(set_attr "predicable" "yes")
-   (set_attr "arch" "v6,nov6")]
+   (set_attr "arch" "v6,nov6,nov6,nov6")]
 )

Which is one step closer, with reload/GCC now generating:

mov r3, r1
smull   r0, r1, r3, r0

This has the correct form, with r0 as the first and fourth arguments, and 
requires
one less register but notice mysteriously 

[PATCH 7/7 v2] rs6000/testsuite: Vector with length test cases

2020-07-10 Thread Kewen.Lin via Gcc-patches
Hi,

v2 changes:
  - Updated param from vect-with-length-scope to
vect-partial-vector-usage
  - Add *-7*/*-8* to cover peeling alignment and gaps. 

All cases passed on powerpc64le-linux-gnu P9.

BR,
Kewen
-
gcc/testsuite/ChangeLog:

* gcc.target/powerpc/p9-vec-length-1.h: New test.
* gcc.target/powerpc/p9-vec-length-2.h: New test.
* gcc.target/powerpc/p9-vec-length-3.h: New test.
* gcc.target/powerpc/p9-vec-length-4.h: New test.
* gcc.target/powerpc/p9-vec-length-5.h: New test.
* gcc.target/powerpc/p9-vec-length-6.h: New test.
* gcc.target/powerpc/p9-vec-length-7.h: New test.
* gcc.target/powerpc/p9-vec-length-8.h: New test.
* gcc.target/powerpc/p9-vec-length-epil-1.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-2.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-3.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-4.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-5.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-6.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-7.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-8.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-run-1.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-run-2.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-run-3.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-run-4.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-run-5.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-run-6.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-run-7.c: New test.
* gcc.target/powerpc/p9-vec-length-epil-run-8.c: New test.
* gcc.target/powerpc/p9-vec-length-full-1.c: New test.
* gcc.target/powerpc/p9-vec-length-full-2.c: New test.
* gcc.target/powerpc/p9-vec-length-full-3.c: New test.
* gcc.target/powerpc/p9-vec-length-full-4.c: New test.
* gcc.target/powerpc/p9-vec-length-full-5.c: New test.
* gcc.target/powerpc/p9-vec-length-full-6.c: New test.
* gcc.target/powerpc/p9-vec-length-full-7.c: New test.
* gcc.target/powerpc/p9-vec-length-full-8.c: New test.
* gcc.target/powerpc/p9-vec-length-full-run-1.c: New test.
* gcc.target/powerpc/p9-vec-length-full-run-2.c: New test.
* gcc.target/powerpc/p9-vec-length-full-run-3.c: New test.
* gcc.target/powerpc/p9-vec-length-full-run-4.c: New test.
* gcc.target/powerpc/p9-vec-length-full-run-5.c: New test.
* gcc.target/powerpc/p9-vec-length-full-run-6.c: New test.
* gcc.target/powerpc/p9-vec-length-full-run-7.c: New test.
* gcc.target/powerpc/p9-vec-length-full-run-8.c: New test.
* gcc.target/powerpc/p9-vec-length-run-1.h: New test.
* gcc.target/powerpc/p9-vec-length-run-2.h: New test.
* gcc.target/powerpc/p9-vec-length-run-3.h: New test.
* gcc.target/powerpc/p9-vec-length-run-4.h: New test.
* gcc.target/powerpc/p9-vec-length-run-5.h: New test.
* gcc.target/powerpc/p9-vec-length-run-6.h: New test.
* gcc.target/powerpc/p9-vec-length-run-7.h: New test.
* gcc.target/powerpc/p9-vec-length-run-8.h: New test.
* gcc.target/powerpc/p9-vec-length.h: New test.
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-vec-length-1.h 
b/gcc/testsuite/gcc.target/powerpc/p9-vec-length-1.h
new file mode 100644
index 000..50da5817013
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-vec-length-1.h
@@ -0,0 +1,18 @@
+#include "p9-vec-length.h"
+
+/* Test the case loop iteration is known.  */
+
+#define N 127
+
+#define test(TYPE) 
\
+  extern TYPE a_##TYPE[N]; 
\
+  extern TYPE b_##TYPE[N]; 
\
+  extern TYPE c_##TYPE[N]; 
\
+  void __attribute__ ((noinline, noclone)) test##TYPE ()   
\
+  {
\
+unsigned int i = 0;
\
+for (i = 0; i < N; i++)
\
+  c_##TYPE[i] = a_##TYPE[i] + b_##TYPE[i]; 
\
+  }
+
+TEST_ALL (test)
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-vec-length-2.h 
b/gcc/testsuite/gcc.target/powerpc/p9-vec-length-2.h
new file mode 100644
index 000..b275dba0fde
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-vec-length-2.h
@@ -0,0 +1,17 @@
+#include "p9-vec-length.h"
+
+/* Test the case loop iteration is unknown.  */
+#define N 255
+
+#define test(TYPE) 
\
+  extern TYPE a_##TYPE[N]; 
\
+  extern TYPE 

[PATCH 5/7 v7] vect: Support vector load/store with length in vectorizer

2020-07-10 Thread Kewen.Lin via Gcc-patches
Hi Richard,

The new version v7 is attached which has addressed your review comments
on v6.  Could you have a further look?  Many thanks in advance!

Bootstrapped/regtested on aarch64-linux-gnu and powerpc64le-linux-gnu P9.
Even with explicit vect-partial-vector-usage settings 1/2 on Power target,
I didn't find any remarkable failures (only some trivial test case issues).

BR,
Kewen

gcc/ChangeLog:

* config/rs6000/rs6000.c (rs6000_option_override_internal):
Set param_vect_partial_vector_usage to 0 explicitly.
* doc/invoke.texi (vect-partial-vector-usage): Document new option.
* optabs-query.c (get_len_load_store_mode): New function.
* optabs-query.h (get_len_load_store_mode): New declare.
* params.opt (vect-partial-vector-usage): New.
* tree-vect-loop-manip.c (vect_set_loop_controls_directly): Add the
handlings for vectorization using length-based partial vectors, call
vect_gen_len for length generation, and rename some variables with
items instead of scalars.
(vect_set_loop_condition_partial_vectors): Add the handlings for
vectorization using length-based partial vectors.
(vect_do_peeling): Allow remaining eiters less than epilogue vf for
LOOP_VINFO_USING_PARTIAL_VECTORS_P.
* tree-vect-loop.c (_loop_vec_info::_loop_vec_info): Init
epil_using_partial_vectors_p.
(_loop_vec_info::~_loop_vec_info): Call release_vec_loop_controls
for lengths destruction.
(vect_verify_loop_lens): New function.
(vect_analyze_loop): Add handlings for epilogue of loop when it's
marked to use vectorization using partial vectors.
(vect_analyze_loop_2): Add the check to allow only one vectorization
approach using partial vectorization at the same time.  Check param
vect-partial-vector-usage for partial vectors decision.  Mark
LOOP_VINFO_EPIL_USING_PARTIAL_VECTORS_P if the epilogue is
considerable to use partial vectors.  Call release_vec_loop_controls
for lengths destruction.
(vect_estimate_min_profitable_iters): Adjust for loop vectorization
using length-based partial vectors.
(vect_record_loop_mask): Init factor to 1 for vectorization using
mask-based partial vectors.
(vect_record_loop_len): New function.
(vect_get_loop_len): Likewise.
* tree-vect-stmts.c (check_load_store_for_partial_vectors): Add
checks for vectorization using length-based partial vectors.  Factor
some code to lambda function get_valid_nvectors.
(vectorizable_store): Add handlings when using length-based partial
vectors.
(vectorizable_load): Likewise.
(vect_gen_len): New function.
* tree-vectorizer.h (struct rgroup_controls): Add field factor
mainly for length-based partial vectors.
(vec_loop_lens): New typedef.
(_loop_vec_info): Add lens and epil_using_partial_vectors_p.
(LOOP_VINFO_EPIL_USING_PARTIAL_VECTORS_P): New macro.
(LOOP_VINFO_LENS): Likewise.
(LOOP_VINFO_FULLY_WITH_LENGTH_P): Likewise.
(vect_record_loop_len): New declare.
(vect_get_loop_len): Likewise.
(vect_gen_len): Likewise.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 58f5d780603..af1271ef85a 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4554,6 +4554,11 @@ rs6000_option_override_internal (bool global_init_p)
   SET_OPTION_IF_UNSET (_options, _options_set,
   param_max_completely_peeled_insns, 400);
 
+  /* Temporarily disable it for now since lxvl/stxvl on the default
+supported hardware Power9 has unexpected performance behaviors. */
+  SET_OPTION_IF_UNSET (_options, _options_set,
+  param_vect_partial_vector_usage, 0);
+
   /* Use the 'model' -fsched-pressure algorithm by default.  */
   SET_OPTION_IF_UNSET (_options, _options_set,
   param_sched_pressure_algorithm,
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 06a04e3d7dd..719f5a1ee4d 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13389,6 +13389,15 @@ by the copy loop headers pass.
 @item vect-epilogues-nomask
 Enable loop epilogue vectorization using smaller vector size.
 
+@item vect-partial-vector-usage
+Controls when the loop vectorizer considers using partial vector loads
+and stores as an alternative to falling back to scalar code.  0 stops
+the vectorizer from ever using partial vector loads and stores.  1 allows
+partial vector loads and stores if vectorization removes the need for the
+code to iterate.  2 allows partial vector loads and stores in all loops.
+The parameter only has an effect on targets that support partial
+vector loads and stores.
+
 @item slp-max-insns-in-bb
 Maximum number of instructions in basic block to be
 considered for SLP 

[Ada] Revert mistaken negation related to references to labels

2020-07-10 Thread Pierre-Marie de Rodat
Commit titled "Update handling of assigned value/unreferenced warnings"
added a comment "... *unless* this is an actual parameter" and at the
same time removed a "not" operator from the corresponding condition.
This is now reverted to match both the previous code and the current
comment.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch8.adb (Find_Direct_Name): Fix code to match the comment.diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -6047,9 +6047,9 @@ package body Sem_Ch8 is
 
begin
   --  Generate reference unless this is an actual parameter
-  --  (see comment below)
+  --  (see comment below).
 
-  if Reference_OK and then Is_Actual_Parameter then
+  if Reference_OK and then not Is_Actual_Parameter then
  Generate_Reference (E, N);
  Set_Referenced (E, R);
   end if;




[Ada] Preserve casing of output files

2020-07-10 Thread Pierre-Marie de Rodat
Windows is case insensitive but also case preserving, so we don't want to
generate a file in lower case if the input file wasn't.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* osint-c.adb (Set_File_Name): Preserve casing of file.
* osint.adb (File_Names_Equal): New.
(Executable_Name): Use File_Equal instead of
Canonical_Case_File_Name.diff --git a/gcc/ada/osint-c.adb b/gcc/ada/osint-c.adb
--- a/gcc/ada/osint-c.adb
+++ b/gcc/ada/osint-c.adb
@@ -412,22 +412,23 @@ package body Osint.C is
  --  Remove extension preparing to replace it
 
  declare
-Name  : String  := Name_Buffer (1 .. Dot_Index);
-First : Positive;
+Name   : String  := Name_Buffer (1 .. Dot_Index);
+Output : String  := Output_Object_File_Name.all;
+First  : Positive;
 
  begin
-Name_Buffer (1 .. Output_Object_File_Name'Length) :=
-  Output_Object_File_Name.all;
+Name_Buffer (1 .. Output_Object_File_Name'Length) := Output;
 
 --  Put two names in canonical case, to allow object file names
 --  with upper-case letters on Windows.
+--  Do it with a copy (Output) and keep Name_Buffer as is since we
+--  want to preserve the original casing.
 
 Canonical_Case_File_Name (Name);
-Canonical_Case_File_Name
-  (Name_Buffer (1 .. Output_Object_File_Name'Length));
+Canonical_Case_File_Name (Output);
 
 Dot_Index := 0;
-for J in reverse Output_Object_File_Name'Range loop
+for J in reverse Output'Range loop
if Name_Buffer (J) = '.' then
   Dot_Index := J;
   exit;
@@ -451,7 +452,7 @@ package body Osint.C is
 
 --  Check name of object file is what we expect
 
-if Name /= Name_Buffer (First .. Dot_Index) then
+if Name /= Output (First .. Dot_Index) then
Fail ("incorrect object file name");
 end if;
  end;


diff --git a/gcc/ada/osint.adb b/gcc/ada/osint.adb
--- a/gcc/ada/osint.adb
+++ b/gcc/ada/osint.adb
@@ -100,6 +100,10 @@ package body Osint is
--  executable is stored in directory "/foo/bar/bin", this routine returns
--  "/foo/bar/". Return "" if location is not recognized as described above.
 
+   function File_Names_Equal (File1, File2 : String) return Boolean;
+   --  Compare File1 and File2 taking into account the case insensitivity
+   --  of the OS.
+
function Update_Path (Path : String_Ptr) return String_Ptr;
--  Update the specified path to replace the prefix with the location where
--  GNAT is installed. See the file prefix.c in GCC for details.
@@ -852,30 +856,22 @@ package body Osint is
  end if;
 
  if Add_Suffix then
-declare
-   Buffer : String := Name_Buffer (1 .. Name_Len);
-
-begin
-   --  Get the file name in canonical case to accept as is. Names
-   --  end with ".EXE" on Windows.
-
-   Canonical_Case_File_Name (Buffer);
-
-   --  If Executable doesn't end with the executable suffix, add it
-
-   if Buffer'Length <= Exec_Suffix'Length
- or else
-   Buffer (Buffer'Last - Exec_Suffix'Length + 1 .. Buffer'Last)
- /= Exec_Suffix.all
-   then
-  Name_Buffer
-(Name_Len + 1 .. Name_Len + Exec_Suffix'Length) :=
-  Exec_Suffix.all;
-  Name_Len := Name_Len + Exec_Suffix'Length;
-  Free (Exec_Suffix);
-  return Name_Find;
-   end if;
-end;
+--  If Executable doesn't end with the executable suffix, add it
+
+if Name_Len <= Exec_Suffix'Length
+  or else not
+File_Names_Equal
+  (Name_Buffer
+(Name_Len - Exec_Suffix'Length + 1 .. Name_Len),
+   Exec_Suffix.all)
+then
+   Name_Buffer
+ (Name_Len + 1 .. Name_Len + Exec_Suffix'Length) :=
+   Exec_Suffix.all;
+   Name_Len := Name_Len + Exec_Suffix'Length;
+   Free (Exec_Suffix);
+   return Name_Find;
+end if;
  end if;
   end if;
 
@@ -889,7 +885,6 @@ package body Osint is
is
   Exec_Suffix: String_Access;
   Add_Suffix : Boolean;
-  Canonical_Name : String := Name;
 
begin
   if Executable_Extension_On_Target = No_Name then
@@ -909,25 +904,26 @@ package body Osint is
 
  begin
 Free (Exec_Suffix);
-Canonical_Case_File_Name (Canonical_Name);
-
 Add_Suffix := True;
+
 if Only_If_No_Suffix then
-   for J in reverse Canonical_Name'Range loop
-  

[Ada] Potentially unevaluated nested expressions

2020-07-10 Thread Pierre-Marie de Rodat
This patch fixes the general problem in the detection of potentially
unevaluated nested expressions.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_util.adb
(Immediate_Context_Implies_Is_Potentially_Unevaluated): New
subprogram.
(Is_Potentially_Unevaluated): Do not stop climbing the tree on
the first candidate subexpression; required to handle nested
expressions.diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -17752,6 +17752,13 @@ package body Sem_Util is
   --  return True if the others choice of the given array aggregate does
   --  not cover any component (i.e. is null).
 
+  function Immediate_Context_Implies_Is_Potentially_Unevaluated
+(Expr : Node_Id) return Boolean;
+  --  Return True if the *immediate* context of this expression tells us
+  --  that it is potentially unevaluated; return False if the *immediate*
+  --  context doesn't provide an answer to this question and we need to
+  --  keep looking.
+
   function Non_Static_Or_Null_Range (N : Node_Id) return Boolean;
   --  Return True if the given range is nonstatic or null
 
@@ -17789,6 +17796,99 @@ package body Sem_Util is
 return False;
   end Has_Null_Others_Choice;
 
+  --
+  -- Immediate_Context_Implies_Is_Potentially_Unevaluated --
+  --
+
+  function Immediate_Context_Implies_Is_Potentially_Unevaluated
+(Expr : Node_Id) return Boolean
+  is
+ Par : constant Node_Id := Parent (Expr);
+
+  begin
+ if Nkind (Par) = N_If_Expression then
+return Is_Elsif (Par) or else Expr /= First (Expressions (Par));
+
+ elsif Nkind (Par) = N_Case_Expression then
+return Expr /= Expression (Par);
+
+ elsif Nkind_In (Par, N_And_Then, N_Or_Else) then
+return Expr = Right_Opnd (Par);
+
+ elsif Nkind_In (Par, N_In, N_Not_In) then
+
+--  If the membership includes several alternatives, only the first
+--  is definitely evaluated.
+
+if Present (Alternatives (Par)) then
+   return Expr /= First (Alternatives (Par));
+
+--  If this is a range membership both bounds are evaluated
+
+else
+   return False;
+end if;
+
+ elsif Nkind (Par) = N_Quantified_Expression then
+return Expr = Condition (Par);
+
+ elsif Nkind (Par) = N_Aggregate
+   and then Present (Etype (Par))
+   and then Etype (Par) /= Any_Composite
+   and then Is_Array_Type (Etype (Par))
+   and then Nkind (Expr) = N_Component_Association
+ then
+declare
+   Choice   : Node_Id;
+   In_Others_Choice : Boolean := False;
+
+begin
+   --  The expression of an array_component_association is
+   --  potentially unevaluated if the associated choice is a
+   --  subtype_indication or range that defines a nonstatic or
+   --  null range.
+
+   Choice := First (Choices (Expr));
+   while Present (Choice) loop
+  if Nkind (Choice) = N_Range
+and then Non_Static_Or_Null_Range (Choice)
+  then
+ return True;
+
+  elsif Nkind (Choice) = N_Identifier
+and then Present (Scalar_Range (Etype (Choice)))
+and then
+  Non_Static_Or_Null_Range (Scalar_Range (Etype (Choice)))
+  then
+ return True;
+
+  elsif Nkind (Choice) = N_Others_Choice then
+ In_Others_Choice := True;
+  end if;
+
+  Next (Choice);
+   end loop;
+
+   --  It is also potentially unevaluated if the associated choice
+   --  is an others choice and the applicable index constraint is
+   --  nonstatic or null.
+
+   if In_Others_Choice then
+  if not Compile_Time_Known_Bounds (Etype (Par)) then
+ return True;
+  else
+ return Has_Null_Others_Choice (Par);
+  end if;
+   end if;
+end;
+
+return False;
+
+ else
+return False;
+ end if;
+  end Immediate_Context_Implies_Is_Potentially_Unevaluated;
+
   --
   -- Non_Static_Or_Null_Range --
   --
@@ -17850,25 +17950,27 @@ package body Sem_Util is
   --  conjunct in a postcondition) with a potentially unevaluated operand.
 
   Par := Parent (Expr);
-  while not Nkind_In (Par, 

[Ada] Add warning for overlays changing scalar storage order

2020-07-10 Thread Pierre-Marie de Rodat
This makes the compiler issue an unconditional warning for an overlay
that changes the scalar storage order, i.e. for an address clause when
the overlaid and the underlying objects are of array or record types
that have opposite scalar storage order.  The reason is that the code
generator does not support toggling the scalar storage order through
the use of aliasing or type punning.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch13.adb (Analyze_Attribute_Definition_Clause) :
Issue an unconditional warning for an overlay that changes the
scalar storage order.diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -6075,10 +6075,10 @@ package body Sem_Ch13 is
   (N, U_Ent, No_Uint, O_Ent, Off);
  end if;
 
- --  If the overlay changes the storage order, mark the
- --  entity as being volatile to block any optimization
- --  for it since the construct is not really supported
- --  by the back end.
+ --  If the overlay changes the storage order, warn since
+ --  the construct is not really supported by the back end.
+ --  Also mark the entity as being volatile to block the
+ --  optimizer, even if there is no warranty on the result.
 
  if (Is_Record_Type (Etype (U_Ent))
   or else Is_Array_Type (Etype (U_Ent)))
@@ -6087,6 +6087,8 @@ package body Sem_Ch13 is
and then Reverse_Storage_Order (Etype (U_Ent)) /=
 Reverse_Storage_Order (Etype (O_Ent))
  then
+Error_Msg_N
+  ("??overlay changes scalar storage order", Expr);
 Set_Treat_As_Volatile (U_Ent);
  end if;
 




[Ada] Ada2020: AI12-0368 Declare expressions can be static

2020-07-10 Thread Pierre-Marie de Rodat
This patch implements AI12-0368, which allows declare expressions
to be static.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_res.adb (Resolve_Expression_With_Actions): Check the rules
of AI12-0368, and mark the declare expression as static or known
at compile time as appropriate.
* sem_ch4.adb: Minor reformatting.
* libgnat/a-stoufo.ads, libgnat/a-stoufo.adb: Allow up to 9
replacement parameters. I'm planning to use this in the test
case for this ticket.diff --git a/gcc/ada/libgnat/a-stoufo.adb b/gcc/ada/libgnat/a-stoufo.adb
--- a/gcc/ada/libgnat/a-stoufo.adb
+++ b/gcc/ada/libgnat/a-stoufo.adb
@@ -38,10 +38,10 @@ package body Ada.Strings.Text_Output.Formatting is
 
procedure Put
  (S : in out Sink'Class; T : Template;
-  X1, X2, X3, X4, X5, X6 : UTF_8_Lines := "")
+  X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "")
is
   J : Positive := T'First;
-  Used : array (1 .. 6) of Boolean := (others => False);
+  Used : array (1 .. 9) of Boolean := (others => False);
begin
   while J <= T'Last loop
  if T (J) = '\' then
@@ -78,6 +78,15 @@ package body Ada.Strings.Text_Output.Formatting is
when '6' =>
   Used (6) := True;
   Put_UTF_8_Lines (S, X6);
+   when '7' =>
+  Used (7) := True;
+  Put_UTF_8_Lines (S, X7);
+   when '8' =>
+  Used (8) := True;
+  Put_UTF_8_Lines (S, X8);
+   when '9' =>
+  Used (9) := True;
+  Put_UTF_8_Lines (S, X9);
 
when others =>
   raise Program_Error;
@@ -107,32 +116,41 @@ package body Ada.Strings.Text_Output.Formatting is
   if not Used (6) then
  pragma Assert (X6 = "");
   end if;
+  if not Used (7) then
+ pragma Assert (X7 = "");
+  end if;
+  if not Used (8) then
+ pragma Assert (X8 = "");
+  end if;
+  if not Used (9) then
+ pragma Assert (X9 = "");
+  end if;
 
   Flush (S);
end Put;
 
procedure Put
  (T : Template;
-  X1, X2, X3, X4, X5, X6 : UTF_8_Lines := "") is
+  X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "") is
begin
-  Put (Files.Standard_Output.all, T, X1, X2, X3, X4, X5, X6);
+  Put (Files.Standard_Output.all, T, X1, X2, X3, X4, X5, X6, X7, X8, X9);
end Put;
 
procedure Err
  (T : Template;
-  X1, X2, X3, X4, X5, X6 : UTF_8_Lines := "") is
+  X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "") is
begin
-  Put (Files.Standard_Error.all, T, X1, X2, X3, X4, X5, X6);
+  Put (Files.Standard_Error.all, T, X1, X2, X3, X4, X5, X6, X7, X8, X9);
end Err;
 
function Format
  (T : Template;
-  X1, X2, X3, X4, X5, X6 : UTF_8_Lines := "")
+  X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "")
  return UTF_8_Lines
is
   Buf : Buffer := New_Buffer;
begin
-  Put (Buf, T, X1, X2, X3, X4, X5, X6);
+  Put (Buf, T, X1, X2, X3, X4, X5, X6, X7, X8, X9);
   return Get_UTF_8 (Buf);
end Format;
 


diff --git a/gcc/ada/libgnat/a-stoufo.ads b/gcc/ada/libgnat/a-stoufo.ads
--- a/gcc/ada/libgnat/a-stoufo.ads
+++ b/gcc/ada/libgnat/a-stoufo.ads
@@ -43,7 +43,7 @@ package Ada.Strings.Text_Output.Formatting is
type Template is new UTF_8;
procedure Put
  (S : in out Sink'Class; T : Template;
-  X1, X2, X3, X4, X5, X6 : UTF_8_Lines := "");
+  X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "");
--  Prints the template as is, except for the following escape sequences:
--"\n" is end of line.
--"\i" indents by the default amount, and "\o" outdents.
@@ -57,17 +57,17 @@ package Ada.Strings.Text_Output.Formatting is
 
procedure Put
  (T : Template;
-  X1, X2, X3, X4, X5, X6 : UTF_8_Lines := "");
+  X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "");
--  Sends to standard output
 
procedure Err
  (T : Template;
-  X1, X2, X3, X4, X5, X6 : UTF_8_Lines := "");
+  X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "");
--  Sends to standard error
 
function Format
  (T : Template;
-  X1, X2, X3, X4, X5, X6 : UTF_8_Lines := "")
+  X1, X2, X3, X4, X5, X6, X7, X8, X9 : UTF_8_Lines := "")
  return UTF_8_Lines;
--  Returns a UTF-8-encoded String
 


diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -2217,8 +2217,6 @@ package body Sem_Ch4 is
-- Analyze_Expression_With_Actions --
-
 
-   --  Start of processing for Analyze_Quantified_Expression
-
procedure Analyze_Expression_With_Actions (N : Node_Id) is
 
   procedure Check_Action_OK (A : Node_Id);


diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ 

[Ada] Spurious error on parameterless acccess_to_subprogram

2020-07-10 Thread Pierre-Marie de Rodat
Compiler rejects an indirect call through an Access_To_Subprogram
value that denotes a parameterless subprogram, when the corresponding
access type has a pre- or postcondition.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch3.adb (Build_Access_Subprogram_Wrapper_Body): Create a
proper signature when the access type denotes a parameterless
subprogram.
* exp_ch6.adb (Expand_Call): Handle properly a  parameterless
indirect call when the corresponding access type has contracts.diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -547,10 +547,10 @@ package body Exp_Ch3 is
   Act := First (Parameter_Specifications (Spec_Node));
 
   while Present (Act) loop
+ exit when Act = Last (Parameter_Specifications (Spec_Node));
  Append_To (Actuals,
Make_Identifier (Loc, Chars (Defining_Identifier (Act;
  Next (Act);
- exit when Act = Last (Parameter_Specifications (Spec_Node));
   end loop;
 
   Ptr :=


diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -2686,9 +2686,10 @@ package body Exp_Ch6 is
   Access_Subprogram_Wrapper (Etype (Name (N)));
 Ptr  : constant Node_Id   := Prefix (Name (N));
 Ptr_Type : constant Entity_Id := Etype (Ptr);
-Parms: constant List_Id   := Parameter_Associations (N);
 Typ  : constant Entity_Id := Etype (N);
+
 New_N: Node_Id;
+Parms: List_Id   := Parameter_Associations (N);
 Ptr_Act  : Node_Id;
 
  begin
@@ -2711,6 +2712,12 @@ package body Exp_Ch6 is
Ptr_Act := Ptr;
 end if;
 
+--  Handle parameterless subprogram.
+
+if No (Parms) then
+   Parms := New_List;
+end if;
+
 Append
  (Make_Parameter_Association (Loc,
 Selector_Name => Make_Identifier (Loc,




[Ada] Fix detection of actual parameters for procedure calls

2020-07-10 Thread Pierre-Marie de Rodat
Routine Is_Actual_Parameter, which deals with cross-references and
pragma Unreferenced, for a procedure call like this:

   P (A);

was wrongly returning True for both the identifiers P and A above, on
the grounds that both have N_Procedure_Call_Statement as their parent.
Now it only returns True for A.

This is just a cleanup; it appears to have no impact on cross-references
in the ALI files or on code with pragma Unreferenced.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch8.adb (Is_Actual_Parameter): Fix processing when parent
is a procedure call statement; extend comment.diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -5020,7 +5020,12 @@ package body Sem_Ch8 is
   --  not know what procedure is being called if the procedure might be
   --  overloaded, so it is premature to go setting referenced flags or
   --  making calls to Generate_Reference. We will wait till Resolve_Actuals
-  --  for that processing
+  --  for that processing.
+  --  Note: there is a similar routine Sem_Util.Is_Actual_Parameter, but
+  --  it works for both function and procedure calls, while here we are
+  --  only concerned with procedure calls (and with entry calls as well,
+  --  but they are parsed as procedure calls and only later rewritten to
+  --  entry calls).
 
   function Known_But_Invisible (E : Entity_Id) return Boolean;
   --  This function determines whether a reference to the entity E, which
@@ -5141,15 +5146,24 @@ package body Sem_Ch8 is
 
   function Is_Actual_Parameter return Boolean is
   begin
- return
-   Nkind (N) = N_Identifier
- and then
-   (Nkind (Parent (N)) = N_Procedure_Call_Statement
- or else
-   (Nkind (Parent (N)) = N_Parameter_Association
- and then N = Explicit_Actual_Parameter (Parent (N))
- and then Nkind (Parent (Parent (N))) =
-  N_Procedure_Call_Statement));
+ if Nkind (N) = N_Identifier then
+case Nkind (Parent (N)) is
+   when N_Procedure_Call_Statement =>
+  return Is_List_Member (N)
+and then List_Containing (N) =
+  Parameter_Associations (Parent (N));
+
+   when N_Parameter_Association =>
+  return N = Explicit_Actual_Parameter (Parent (N))
+and then Nkind (Parent (Parent (N))) =
+   N_Procedure_Call_Statement;
+
+   when others =>
+  return False;
+end case;
+ else
+return False;
+ end if;
   end Is_Actual_Parameter;
 
   -




[Ada] Remove references to non-existing E_Protected_Object

2020-07-10 Thread Pierre-Marie de Rodat
Nowhere in the code we call set Ekind to E_Protected_Object, so all the
code that tests this is necessarily dead. This patch removes references
to E_Protected_Object.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* einfo.ads (E_Protected_Object): Enumeration literal removed.
* lib-xref.ads (Xref_Entity_Letters): Remove reference to
removed literal.
* sem_ch3.adb (Check_Completion): Likewise.
* sem_util.adb (Has_Enabled_Property): Likewise.diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -5214,10 +5214,6 @@ package Einfo is
   --  there are some attributes that are significant for the body entity.
   --  For example, collection of exception handlers.
 
-  E_Protected_Object,
-  --  A protected object, created by an object declaration that declares
-  --  an object of a protected type.
-
   E_Protected_Body,
   --  A protected body. This entity serves almost no function, since all
   --  semantic analysis uses the protected entity (E_Protected_Type).


diff --git a/gcc/ada/lib-xref.ads b/gcc/ada/lib-xref.ads
--- a/gcc/ada/lib-xref.ads
+++ b/gcc/ada/lib-xref.ads
@@ -514,7 +514,6 @@ package Lib.Xref is
 
   E_Package_Body   => ' ',
   E_Protected_Body => ' ',
-  E_Protected_Object   => ' ',
   E_Subprogram_Body=> ' ',
   E_Task_Body  => ' ');
 


diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -11676,9 +11676,8 @@ package body Sem_Ch3 is
 end if;
 
  elsif Is_Entry (E) then
-if not Has_Completion (E) and then
-  (Ekind (Scope (E)) = E_Protected_Object
-or else Ekind (Scope (E)) = E_Protected_Type)
+if not Has_Completion (E)
+  and then Ekind (Scope (E)) = E_Protected_Type
 then
Post_Error;
 end if;
@@ -11722,11 +11721,6 @@ package body Sem_Ch3 is
  then
 Post_Error;
 
- elsif Ekind (E) = E_Protected_Object
-   and then not Has_Completion (Etype (E))
- then
-Post_Error;
-
  elsif Ekind (E) = E_Record_Type then
 if Is_Tagged_Type (E) then
Check_Abstract_Overriding (E);


diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -11541,14 +11541,6 @@ package body Sem_Util is
  return Type_Or_Variable_Has_Enabled_Property
(Item_Id => First_Subtype (Item_Id));
 
-  --  By default, protected objects only have the properties Async_Readers
-  --  and Async_Writers. If they have Part_Of components, they also inherit
-  --  their properties Effective_Reads and Effective_Writes
-  --  (SPARK RM 7.1.2(16)).
-
-  elsif Ekind (Item_Id) = E_Protected_Object then
- return Protected_Type_Or_Variable_Has_Enabled_Property;
-
   --  Otherwise a property is enabled when the related item is effectively
   --  volatile.
 




[Ada] Further improve the expansion of array aggregates

2020-07-10 Thread Pierre-Marie de Rodat
First, this change extends the memset optimization to the case of array
aggregates nested in other aggregates, when the outer aggregates are
expanded component-wise; second, it prevents the compiler from
duplicating allocators and other nonstatic constructs present in an
Others choice of array aggregates, even in a preelaborate context.

In addition, if the expression given in an Others choice of an aggregate
is not obviously static, this causes the compiler to preanalyze it in
order to resolve syntactic ambiguities in static expressions, for
example conversions; this also makes the Flatten function treat all
nested aggregates alike in the case of a multidimensional array by
checking if they can recursively be flattened in any position in the
outer aggregate, i.e.  not just in the first and the last positions.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_aggr.adb
(Convert_To_Positional): Add Dims local variable
and pass it in calls to Is_Flat and Flatten.
(Check_Static_Components): Pass Dims in call to
Is_Static_Element.
(Nonflattenable_Next_Aggr): New predicate.
(Flatten): Add Dims parameter and Expr local variable.  Call
Nonflattenable_Next_Aggr in a couple of places.  In the case
when an Others choice is present, check that the element is
either static or a nested aggregate that can be flattened,
before disregarding the replication limit for elaboration
purposes.  Check that a nested array is flattenable in the case
of a multidimensional array in any position.  Remove redundant
check in the Others case and pass Dims in call to
Is_Static_Element.  Use Expr variable.
(Is_Flat): Change type of Dims parameter from Int to Nat.
(Is_Static_Element): Add Dims parameter.  Replace tests on
literals with call to Compile_Time_Known_Value.  If everything
else failed and the dimension is 1, preanalyze the expression
before calling again Compile_Time_Known_Value on it.  Return
true for null.
(Late_Expansion): Do not expand further if the assignment to the
target can be done directly by the back end.diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -4954,6 +4954,7 @@ package body Exp_Aggr is
   Handle_Bit_Packed : Boolean := False)
is
   Typ  : constant Entity_Id := Etype (N);
+  Dims : constant Nat := Number_Dimensions (Typ);
   Max_Others_Replicate : constant Nat := Max_Aggregate_Size (Typ);
 
   Static_Components : Boolean := True;
@@ -4964,18 +4965,19 @@ package body Exp_Aggr is
   --  expansion.
 
   function Flatten
-(N   : Node_Id;
- Ix  : Node_Id;
- Ixb : Node_Id) return Boolean;
+(N: Node_Id;
+ Dims : Nat;
+ Ix   : Node_Id;
+ Ixb  : Node_Id) return Boolean;
   --  Convert the aggregate into a purely positional form if possible. On
   --  entry the bounds of all dimensions are known to be static, and the
   --  total number of components is safe enough to expand.
 
-  function Is_Flat (N : Node_Id; Dims : Int) return Boolean;
-  --  Return True iff the array N is flat (which is not trivial in the case
-  --  of multidimensional aggregates).
+  function Is_Flat (N : Node_Id; Dims : Nat) return Boolean;
+  --  Return True if the aggregate N is flat (which is not trivial in the
+  --  case of multidimensional aggregates).
 
-  function Is_Static_Element (N : Node_Id) return Boolean;
+  function Is_Static_Element (N : Node_Id; Dims : Nat) return Boolean;
   --  Return True if N, an element of a component association list, i.e.
   --  N_Component_Association or N_Iterated_Component_Association, has a
   --  compile-time known value and can be passed as is to the back-end
@@ -5019,7 +5021,7 @@ package body Exp_Aggr is
  then
 Assoc := First (Component_Associations (N));
 while Present (Assoc) loop
-   if not Is_Static_Element (Assoc) then
+   if not Is_Static_Element (Assoc, Dims) then
   Static_Components := False;
   exit;
end if;
@@ -5034,18 +5036,39 @@ package body Exp_Aggr is
   -
 
   function Flatten
-(N   : Node_Id;
- Ix  : Node_Id;
- Ixb : Node_Id) return Boolean
+(N: Node_Id;
+ Dims : Nat;
+ Ix   : Node_Id;
+ Ixb  : Node_Id) return Boolean
   is
  Loc : constant Source_Ptr := Sloc (N);
  Blo : constant Node_Id:= Type_Low_Bound (Etype (Ixb));
  Lo  : constant Node_Id:= Type_Low_Bound (Etype (Ix));
  Hi  : constant Node_Id:= Type_High_Bound (Etype (Ix));
- Lov : Uint;
- Hiv : Uint;
 
- Others_Present : Boolean := 

[Ada] Spurious error in generic dispatching constructor call

2020-07-10 Thread Pierre-Marie de Rodat
Given two interface types Ifc0 and Ifc1 where Ifc1 is a descendant of
Ifc0, the frontend reports a spurious error handling a call to a
Generic_Dispatching_Constructor instance that occurs as the operand of a
qualified expression initializing an allocator where Ifc1'Class is the
subtype_mark of the qualified expression and the designated type of the
type of the allocator is Ifc0'Class, as in the following example:

type Ref is access Ifc0'Class;
Ptr : Ref := new Ifc1'Class ();

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch6.adb (Make_Build_In_Place_Iface_Call_In_Allocator):
Build the internal anonymous access type using as a reference
the designated type imposed by the context (instead of using the
return type of the called function).diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -9709,7 +9709,8 @@ package body Exp_Ch6 is
   --  declaration.
 
   Anon_Type := Create_Itype (E_Anonymous_Access_Type, Function_Call);
-  Set_Directly_Designated_Type (Anon_Type, Etype (BIP_Func_Call));
+  Set_Directly_Designated_Type (Anon_Type,
+Designated_Type (Etype (Allocator)));
   Set_Etype (Anon_Type, Anon_Type);
   Build_Class_Wide_Master (Anon_Type);
 




[Ada] Part of implementation of AI12-0212: container aggregates

2020-07-10 Thread Pierre-Marie de Rodat
This is ongoing work for the implementation of Ada 2020 generalized
aggregates for containers. The patch includes the infrastructure to
support the new aspect and related subprograms, and implements the
functionality of positional aggregates for set-like containers.

Still to come:

a) resolution and expansion for named and indexed aggregates
b) Updating of standard container libraries for Ada 2012 containers.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* aspects.ads: Add Aspect_Aggregate.
* exp_aggr.adb (Expand_Container_Aggregate): Expand positional
container aggregates into separate initialization and insertion
operations.
* sem_aggr.ads (Resolve_Container_Aggregate): New subprogram.
* sem_aggr.adb (Resolve_Container_Aggregate): Parse aspect
aggregate, establish element types and key types if present, and
resolve aggregate components.
* sem_ch13.ads (Parse_Aspect_Aggregate): Public subprogram used
in validation, resolution and expansion of container aggregates
* sem_ch13.adb
(Parse_Aspect_Aggregate): Retrieve names of primitives specified
in aspect specification.
(Validate_Aspect_Aggregate): Check legality of specified
operations given in aspect specification, before nane
resolution.
(Resolve_Aspect_Aggregate): At freeze point resolve operations
and verify that given operations have the required profile.
* sem_res.adb (Resolve): Call Resolve_Aspect_Aggregate if aspect
is present for type.
* snames.ads-tmpl: Add names used in aspect Aggregate: Empty,
Add_Named, Add_Unnamed, New_Indexed, Assign_Indexed.diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads
--- a/gcc/ada/aspects.ads
+++ b/gcc/ada/aspects.ads
@@ -76,6 +76,7 @@ package Aspects is
  (No_Aspect,-- Dummy entry for no aspect
   Aspect_Abstract_State,-- GNAT
   Aspect_Address,
+  Aspect_Aggregate,
   Aspect_Alignment,
   Aspect_Annotate,  -- GNAT
   Aspect_Async_Readers, -- GNAT
@@ -300,6 +301,7 @@ package Aspects is
   Aspect_Iterator_Element   => True,
   Aspect_Iterable   => True,
   Aspect_Variable_Indexing  => True,
+  Aspect_Aggregate  => True,
   others=> False);
 
--  The following array indicates aspects for which multiple occurrences of
@@ -345,6 +347,7 @@ package Aspects is
  (No_Aspect => Optional_Expression,
   Aspect_Abstract_State => Expression,
   Aspect_Address=> Expression,
+  Aspect_Aggregate  => Expression,
   Aspect_Alignment  => Expression,
   Aspect_Annotate   => Expression,
   Aspect_Async_Readers  => Optional_Expression,
@@ -442,6 +445,7 @@ package Aspects is
  (No_Aspect   => False,
   Aspect_Abstract_State   => False,
   Aspect_Address  => True,
+  Aspect_Aggregate=> False,
   Aspect_Alignment=> True,
   Aspect_Annotate => False,
   Aspect_Async_Readers=> False,
@@ -580,6 +584,7 @@ package Aspects is
  (No_Aspect   => No_Name,
   Aspect_Abstract_State   => Name_Abstract_State,
   Aspect_Address  => Name_Address,
+  Aspect_Aggregate=> Name_Aggregate,
   Aspect_Alignment=> Name_Alignment,
   Aspect_All_Calls_Remote => Name_All_Calls_Remote,
   Aspect_Annotate => Name_Annotate,
@@ -828,6 +833,7 @@ package Aspects is
Aspect_Delay : constant array (Aspect_Id) of Delay_Type :=
  (No_Aspect   => Always_Delay,
   Aspect_Address  => Always_Delay,
+  Aspect_Aggregate=> Always_Delay,
   Aspect_All_Calls_Remote => Always_Delay,
   Aspect_Asynchronous => Always_Delay,
   Aspect_Attach_Handler   => Always_Delay,


diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -23,6 +23,7 @@
 --  --
 --
 
+with Aspects;  use Aspects;
 with Atree;use Atree;
 with Checks;   use Checks;
 with Debug;use Debug;
@@ -52,6 +53,7 @@ with Sem;  use Sem;
 with Sem_Aggr; use Sem_Aggr;
 with Sem_Aux;  use Sem_Aux;
 with Sem_Ch3;  use Sem_Ch3;
+with Sem_Ch13; use Sem_Ch13;
 with Sem_Eval; use Sem_Eval;
 with Sem_Mech; use Sem_Mech;
 with Sem_Res;  use Sem_Res;
@@ 

[Ada] Fix internal error on if-expression in call returning tagged type

2020-07-10 Thread Pierre-Marie de Rodat
This removes the left-overs of an expansion done in Expand_Call_Helper
in order to pass the correct accessibility level to the callee when
the actual is an if-expression of an access type.  The expansion uses
a dummy temporary to analyze the outermost Expression_With_Actions it
makes and removes its declaration afterward but, if the temporary is
of a tagged type, there is more to be removed after the declaration.

This also changes the type of the minimum accessibility level object
created by Analyze_Subprogram_Body_Helper to Natural and enhances
Determine_Range to deal with the Min and Max attributes that are used
to initialize the object, the end goal being to remove an useless
range check generated for the accessibility level itself.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* checks.adb (Determine_Range): Deal with Min and Max attributes.
* exp_ch6.adb (Expand_Call_Helper): When generating code to pass
the accessibility level to the caller in the case of an actual
which is an if-expression, also remove the nodes created after
the declaration of the dummy temporary.
* sem_ch6.adb (Analyze_Subprogram_Body_Helper): Use Natural as
the type of the minimum accessibility level object.diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -5119,6 +5119,27 @@ package body Checks is
  when N_Attribute_Reference =>
 case Get_Attribute_Id (Attribute_Name (N)) is
 
+   --  For Min/Max attributes, we can refine the range using the
+   --  possible range of values of the attribute expressions.
+
+   when Attribute_Min
+  | Attribute_Max
+   =>
+  Determine_Range
+(First (Expressions (N)),
+ OK1, Lo_Left, Hi_Left, Assume_Valid);
+
+  if OK1 then
+ Determine_Range
+   (Next (First (Expressions (N))),
+OK1, Lo_Right, Hi_Right, Assume_Valid);
+  end if;
+
+  if OK1 then
+ Lor := UI_Min (Lo_Left, Lo_Right);
+ Hir := UI_Max (Hi_Left, Hi_Right);
+  end if;
+
--  For Pos/Val attributes, we can refine the range using the
--  possible range of values of the attribute expression.
 


diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -3927,6 +3927,8 @@ package body Exp_Ch6 is
  then
 declare
Decl : Node_Id;
+   pragma Warnings (Off, Decl);
+   --  Suppress warning for the final removal loop
Lvl  : Entity_Id;
Res  : Entity_Id;
Temp : Node_Id;
@@ -4045,8 +4047,7 @@ package body Exp_Ch6 is
--  expansion if we are dealing with a function
--  call.
 
-   if Nkind (Call_Node) =
-N_Procedure_Call_Statement
+   if Nkind (Call_Node) = N_Procedure_Call_Statement
then
   --  Generate:
   --Lvl : Natural;
@@ -4109,7 +4110,13 @@ package body Exp_Ch6 is
 
   Set_Expression (Call_Node, Relocate_Node (Temp));
   Call_Node := Expression (Call_Node);
-  Remove (Next (Decl));
+
+  --  Remove the declaration of the dummy and the
+  --  subsequent actions its analysis has created.
+
+  while Present (Remove_Next (Decl)) loop
+ null;
+  end loop;
end if;
 
--  Decorate the conditional expression with


diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -4684,7 +4684,7 @@ package body Sem_Ch6 is
   then
  --  Generate the minimum accessibility level object
 
- --A60b : integer := integer'min(2, paramL);
+ --A60b : natural := natural'min(1, paramL);
 
  declare
 Loc  : constant Source_Ptr := Sloc (Body_Nod);
@@ -4694,11 +4694,11 @@ package body Sem_Ch6 is
   Make_Temporary
 (Loc, 'A', Extra_Accessibility (Form)),
 Object_Definition   => New_Occurrence_Of
- (Standard_Integer, Loc),
+   

[Ada] Cleanup excessive conditions in Check_Completion

2020-07-10 Thread Pierre-Marie de Rodat
In routine Check_Completion once the entity kind is determined, it is
enough to look if the required completion is provided. However, those
two tests were combined, so we were processing the entity several times,
which was inelegant and inefficient.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch3.adb (Check_Completion): Refactor chained
if-then-elsif-...  statement to be more like a case
statement (note: we can't simply use case statement because of
Is_Intrinsic_Subprogram in the first condition).diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -11698,28 +11698,30 @@ package body Sem_Ch3 is
  --  A formal incomplete type (Ada 2012) does not require a completion;
  --  other incomplete type declarations do.
 
- elsif Ekind (E) = E_Incomplete_Type
-   and then No (Underlying_Type (E))
-   and then not Is_Generic_Type (E)
- then
-Post_Error;
+ elsif Ekind (E) = E_Incomplete_Type then
+if No (Underlying_Type (E))
+  and then not Is_Generic_Type (E)
+then
+   Post_Error;
+end if;
 
- elsif Ekind_In (E, E_Task_Type, E_Protected_Type)
-   and then not Has_Completion (E)
- then
-Post_Error;
+ elsif Ekind_In (E, E_Task_Type, E_Protected_Type) then
+if not Has_Completion (E) then
+   Post_Error;
+end if;
 
  --  A single task declared in the current scope is a constant, verify
  --  that the body of its anonymous type is in the same scope. If the
  --  task is defined elsewhere, this may be a renaming declaration for
  --  which no completion is needed.
 
- elsif Ekind (E) = E_Constant
-   and then Ekind (Etype (E)) = E_Task_Type
-   and then not Has_Completion (Etype (E))
-   and then Scope (Etype (E)) = Current_Scope
- then
-Post_Error;
+ elsif Ekind (E) = E_Constant then
+if Ekind (Etype (E)) = E_Task_Type
+  and then not Has_Completion (Etype (E))
+  and then Scope (Etype (E)) = Current_Scope
+then
+   Post_Error;
+end if;
 
  elsif Ekind (E) = E_Record_Type then
 if Is_Tagged_Type (E) then




[Ada] Small cleanup throughout Exp_Ch4

2020-07-10 Thread Pierre-Marie de Rodat
This replaces calls to Esize or RM_Size for standard integer types with
their value, uses Standard_Long_Long_Unsigned directly in one case and
Standard_Long_Long_Integer in another case, and changes the recently
added Narrow_Large_Operation to use Uint instead of Nat for sizes.

No functional changes (except maybe in a corner case on 32-bit targets).

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch4.adb (Expand_Array_Comparison): Reformat.
(Expand_Concatenate): Use standard size values directly and use
Standard_Long_Long_Unsigned instead of RE_Long_Long_Unsigned.
(Expand_Modular_Op): Use Standard_Long_Long_Integer in case the
modulus is larger than Integer.
(Expand_N_Op_Expon): Use standard size value directly.
(Narrow_Large_Operation): Use Uint instead of Nat for sizes and
use a local variable for the size of the type.
(Get_Size_For_Range): Return Uint instead of Nat.
(Is_OK_For_Range): Take Uint instead of Nat.diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -1378,9 +1378,7 @@ package body Exp_Ch4 is
   --  except that we avoid this for targets for which are not addressable
   --  by bytes.
 
-  if not Is_Bit_Packed_Array (Typ1)
-and then Byte_Addressable
-  then
+  if not Is_Bit_Packed_Array (Typ1) and then Byte_Addressable then
  --  The call we generate is:
 
  --  Compare_Array_xn[_Unaligned]
@@ -3008,23 +3006,23 @@ package body Exp_Ch4 is
 
   --  For modular types, we use a 32-bit modular type for types whose size
   --  is in the range 1-31 bits. For 32-bit unsigned types, we use the
-  --  identity type, and for larger unsigned types we use 64-bits.
+  --  identity type, and for larger unsigned types we use a 64-bit type.
 
   elsif Is_Modular_Integer_Type (Ityp) then
- if RM_Size (Ityp) < RM_Size (Standard_Unsigned) then
+ if RM_Size (Ityp) < Standard_Integer_Size then
 Artyp := Standard_Unsigned;
- elsif RM_Size (Ityp) = RM_Size (Standard_Unsigned) then
+ elsif RM_Size (Ityp) = Standard_Integer_Size then
 Artyp := Ityp;
  else
-Artyp := RTE (RE_Long_Long_Unsigned);
+Artyp := Standard_Long_Long_Unsigned;
  end if;
 
   --  Similar treatment for signed types
 
   else
- if RM_Size (Ityp) < RM_Size (Standard_Integer) then
+ if RM_Size (Ityp) < Standard_Integer_Size then
 Artyp := Standard_Integer;
- elsif RM_Size (Ityp) = RM_Size (Standard_Integer) then
+ elsif RM_Size (Ityp) = Standard_Integer_Size then
 Artyp := Ityp;
  else
 Artyp := Standard_Long_Long_Integer;
@@ -4167,7 +4165,7 @@ package body Exp_Ch4 is
 --  errors on large legal literals of the type.
 
 if Modulus (Etype (N)) > UI_From_Int (Int (Integer'Last)) then
-   Target_Type := Standard_Long_Integer;
+   Target_Type := Standard_Long_Long_Integer;
 else
Target_Type := Standard_Integer;
 end if;
@@ -8747,7 +8745,7 @@ package body Exp_Ch4 is
 --  We only handle cases where the right type is a integer
 
 and then Is_Integer_Type (Root_Type (Exptyp))
-and then Esize (Root_Type (Exptyp)) <= Esize (Standard_Integer)
+and then Esize (Root_Type (Exptyp)) <= Standard_Integer_Size
 
 --  This transformation is not applicable for a modular type with a
 --  nonbinary modulus because we do not handle modular reduction in
@@ -11394,7 +11392,7 @@ package body Exp_Ch4 is
  --  integer type large enough to hold the result.
 
  if Is_Fixed_Point_Type (Etype (Expr)) then
-if Esize (Base_Type (Etype (Expr))) > Esize (Standard_Integer) then
+if Esize (Base_Type (Etype (Expr))) > Standard_Integer_Size then
Ityp := Standard_Long_Long_Integer;
 else
Ityp := Standard_Integer;
@@ -13910,8 +13908,9 @@ package body Exp_Ch4 is
   Compar : constant Boolean   := Kind in N_Op_Compare or else In_Rng;
   R  : constant Node_Id   := Right_Opnd (N);
   Typ: constant Entity_Id := Etype (R);
+  Tsiz   : constant Uint  := RM_Size (Typ);
 
-  function Get_Size_For_Range (Lo, Hi : Uint) return Nat;
+  function Get_Size_For_Range (Lo, Hi : Uint) return Uint;
   --  Return the size of a small signed integer type covering Lo .. Hi.
   --  The important thing is to return a size lower than that of Typ.
 
@@ -13919,16 +13918,16 @@ package body Exp_Ch4 is
   -- Get_Size_For_Range --
   
 
-  function Get_Size_For_Range (Lo, Hi : Uint) return Nat is
+  function Get_Size_For_Range (Lo, Hi : Uint) return Uint is
 
- function Is_OK_For_Range (Siz : Nat) return Boolean;
+ 

[Ada] Use small limit for aggregates inside subprograms

2020-07-10 Thread Pierre-Marie de Rodat
We want to favor large static aggregate at library level, but within
subprograms, we want to favor loops instead when relevant.

As part of this work we uncovered a missing freeze on allocator subtype
marks showing up with this change, as well as the need to generate
predicate checks within init procs when the expression involved is not
compiler generated.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_aggr.adb (Max_Aggregate_Size): Use small limit for
aggregate inside subprograms.
* sprint.adb (Sprint_Node_Actual [N_Object_Declaration]): Do not
print the initialization expression if the No_Initialization
flag is set.
* sem_util.ads, sem_util.adb (Predicate_Enabled): New.
* exp_ch4.adb (Expand_N_Type_Conversion): Code cleanup and apply
predicate check consistently.
* exp_ch6.adb (Expand_Actuals.By_Ref_Predicate_Check): Ditto.
* sem_ch3.adb (Analyze_Object_Declaration): Ditto.
* exp_ch3.adb (Build_Assignment): Revert handling of predicate
check for allocators with qualified expressions, now handled in
Freeze_Expression directly.
* sem_aggr.adb: Fix typos.
* checks.adb: Code refactoring: use Predicate_Enabled.
(Apply_Predicate_Check): Code cleanup.
* freeze.adb (Freeze_Expression): Freeze the subtype mark before
a qualified expression on an allocator.
* exp_util.ads, exp_util.adb (Within_Internal_Subprogram):
Renamed Predicate_Check_In_Scope to clarify usage, refine
handling of predicates within init procs which should be enabled
when the node comes from source.
* sem_ch13.adb (Freeze_Entity_Checks): Update call to
Predicate_Check_In_Scope.diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -2746,153 +2746,146 @@ package body Checks is
   S   : Entity_Id;
 
begin
-  if Predicate_Checks_Suppressed (Empty) then
- return;
-
-  elsif Predicates_Ignored (Typ) then
+  if not Predicate_Enabled (Typ)
+or else not Predicate_Check_In_Scope (N)
+  then
  return;
+  end if;
 
-  elsif Present (Predicate_Function (Typ)) then
- S := Current_Scope;
- while Present (S) and then not Is_Subprogram (S) loop
-S := Scope (S);
- end loop;
-
- --  A predicate check does not apply within internally generated
- --  subprograms, such as TSS functions.
+  S := Current_Scope;
+  while Present (S) and then not Is_Subprogram (S) loop
+ S := Scope (S);
+  end loop;
 
- if Within_Internal_Subprogram then
-return;
+  --  If the check appears within the predicate function itself, it means
+  --  that the user specified a check whose formal is the predicated
+  --  subtype itself, rather than some covering type. This is likely to be
+  --  a common error, and thus deserves a warning.
 
- --  If the check appears within the predicate function itself, it
- --  means that the user specified a check whose formal is the
- --  predicated subtype itself, rather than some covering type. This
- --  is likely to be a common error, and thus deserves a warning.
+  if Present (S) and then S = Predicate_Function (Typ) then
+ Error_Msg_NE
+   ("predicate check includes a call to& that requires a "
+& "predicate check??", Parent (N), Fun);
+ Error_Msg_N
+   ("\this will result in infinite recursion??", Parent (N));
 
- elsif Present (S) and then S = Predicate_Function (Typ) then
+ if Is_First_Subtype (Typ) then
 Error_Msg_NE
-  ("predicate check includes a call to& that requires a "
-   & "predicate check??", Parent (N), Fun);
-Error_Msg_N
-  ("\this will result in infinite recursion??", Parent (N));
+  ("\use an explicit subtype of& to carry the predicate",
+   Parent (N), Typ);
+ end if;
 
-if Is_First_Subtype (Typ) then
-   Error_Msg_NE
- ("\use an explicit subtype of& to carry the predicate",
-  Parent (N), Typ);
-end if;
+ Insert_Action (N,
+   Make_Raise_Storage_Error (Sloc (N),
+ Reason => SE_Infinite_Recursion));
+ return;
+  end if;
 
-Insert_Action (N,
-  Make_Raise_Storage_Error (Sloc (N),
-Reason => SE_Infinite_Recursion));
+  --  Normal case of predicate active
 
- --  Here for normal case of predicate active
+  --  If the expression is an IN parameter, the predicate will have
+  --  been applied at the point of call. An additional check would
+  --  be redundant, or will lead to out-of-scope references if the
+  --  call appears within an aspect specification for 

[Ada] Fix detection of volatile properties in SPARK

2020-07-10 Thread Pierre-Marie de Rodat
Now that volatile properties can be set on types, objects other than
variable may have fine-grain volatile properties inherited through their
type. This is now fixed.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_util.adb (Has_Enabled_Property): Add handling of
non-variable objects.diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -11537,6 +11537,14 @@ package body Sem_Util is
   elsif Ekind (Item_Id) = E_Variable then
  return Type_Or_Variable_Has_Enabled_Property (Item_Id);
 
+  --  Other objects can only inherit properties through their type. We
+  --  cannot call directly Type_Or_Variable_Has_Enabled_Property on
+  --  these as they don't have contracts attached, which is expected by
+  --  this function.
+
+  elsif Is_Object (Item_Id) then
+ return Type_Or_Variable_Has_Enabled_Property (Etype (Item_Id));
+
   elsif Is_Type (Item_Id) then
  return Type_Or_Variable_Has_Enabled_Property
(Item_Id => First_Subtype (Item_Id));




[Ada] Reuse SPARK expansion of attribute Update for delta_aggregate

2020-07-10 Thread Pierre-Marie de Rodat
For GNATprove we have a special expansion of attribute Update. It is now
refactored it into a dedicated routine and reused for delta_aggregate.

For attribute Update the behaviour is as it was; for delta_aggregate we
now decorate the AST with range checks flags that were previously
missing.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_spark.adb (Expand_SPARK_Delta_Or_Update): Refactored from
Expand_SPARK_N_Attribute_Reference; rewrite into N_Aggregate or
N_Delta_Aggregate depending on what is being rewritten.
(Expand_SPARK_N_Delta_Aggregate): New routine to expand
delta_aggregate.
(Expand_SPARK_N_Attribute_Reference): Call the refactored
routine.diff --git a/gcc/ada/exp_spark.adb b/gcc/ada/exp_spark.adb
--- a/gcc/ada/exp_spark.adb
+++ b/gcc/ada/exp_spark.adb
@@ -54,6 +54,9 @@ package body Exp_SPARK is
procedure Expand_SPARK_N_Attribute_Reference (N : Node_Id);
--  Perform attribute-reference-specific expansion
 
+   procedure Expand_SPARK_N_Delta_Aggregate (N : Node_Id);
+   --  Perform delta-aggregate-specific expansion
+
procedure Expand_SPARK_N_Freeze_Type (E : Entity_Id);
--  Build the DIC procedure of a type when needed, if not already done
 
@@ -69,6 +72,9 @@ package body Exp_SPARK is
procedure Expand_SPARK_N_Op_Ne (N : Node_Id);
--  Rewrite operator /= based on operator = when defined explicitly
 
+   procedure Expand_SPARK_Delta_Or_Update (Typ : Entity_Id; Aggr : Node_Id);
+   --  Common expansion of attribute Update and delta_aggregate
+
--
-- Expand_SPARK --
--
@@ -101,6 +107,9 @@ package body Exp_SPARK is
  when N_Attribute_Reference =>
 Expand_SPARK_N_Attribute_Reference (N);
 
+ when N_Delta_Aggregate =>
+Expand_SPARK_N_Delta_Aggregate (N);
+
  when N_Expanded_Name
 | N_Identifier
  =>
@@ -137,6 +146,185 @@ package body Exp_SPARK is
   end case;
end Expand_SPARK;
 
+   --
+   -- Expand_SPARK_Delta_Or_Update --
+   --
+
+   procedure Expand_SPARK_Delta_Or_Update
+ (Typ  : Entity_Id;
+  Aggr : Node_Id)
+   is
+  Assoc : Node_Id;
+  Comp  : Node_Id;
+  Comp_Id   : Entity_Id;
+  Comp_Type : Entity_Id;
+  Expr  : Node_Id;
+  Index : Node_Id;
+  Index_Typ : Entity_Id;
+  New_Assoc : Node_Id;
+
+   begin
+  --  Apply scalar range checks on the updated components, if needed
+
+  if Is_Array_Type (Typ) then
+
+ --  Multi-dimensional array
+
+ if Present (Next_Index (First_Index (Typ))) then
+Assoc := First (Component_Associations (Aggr));
+
+while Present (Assoc) loop
+   Expr  := Expression (Assoc);
+   Comp_Type := Component_Type (Typ);
+
+   if Is_Scalar_Type (Comp_Type) then
+  Apply_Scalar_Range_Check (Expr, Comp_Type);
+   end if;
+
+   --  The current association contains a sequence of indexes
+   --  denoting an element of a multidimensional array:
+   --
+   --(Index_1, ..., Index_N)
+
+   Expr := First (Choices (Assoc));
+
+   pragma Assert (Nkind (Aggr) = N_Aggregate);
+
+   while Present (Expr) loop
+  Index := First (Expressions (Expr));
+  Index_Typ := First_Index (Typ);
+
+  while Present (Index_Typ) loop
+ Apply_Scalar_Range_Check (Index, Etype (Index_Typ));
+ Next (Index);
+ Next_Index (Index_Typ);
+  end loop;
+
+  Next (Expr);
+   end loop;
+
+   Next (Assoc);
+end loop;
+
+ --  One-dimensional array
+
+ else
+Assoc := First (Component_Associations (Aggr));
+
+while Present (Assoc) loop
+   Expr  := Expression (Assoc);
+   Comp_Type := Component_Type (Typ);
+
+   if Is_Scalar_Type (Comp_Type) then
+  Apply_Scalar_Range_Check (Expr, Comp_Type);
+   end if;
+
+   Index := First (Choices (Assoc));
+   Index_Typ := First_Index (Typ);
+
+   while Present (Index) loop
+  --  The index denotes a range of elements
+
+  if Nkind (Index) = N_Range then
+ Apply_Scalar_Range_Check
+   (Low_Bound  (Index), Etype (Index_Typ));
+ Apply_Scalar_Range_Check
+   (High_Bound (Index), Etype (Index_Typ));
+
+ --  Otherwise the index denotes a single element
+
+  else
+ Apply_Scalar_Range_Check (Index, Etype (Index_Typ));
+  end if;
+
+  Next (Index);

[Ada] Fix failing assertions related to volatile objects

2020-07-10 Thread Pierre-Marie de Rodat
Comments for routines No_Caching_Enabled and Is_Effectively_Volatile,
which are both related to volatile objects, were not enforced with
assertions. As a result, we had failing assertions much deeper in the
call tree, far from where the problems occur. This patch adds both the
missing assertions and guards to prevent those assertions from failing.

In preparation for a main commit that will address a problem related to
freezing of Dynamic_Predicate aspect on volatile objects.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch3.adb (Process_Discriminants): Set Ekind of the
processed discriminant entity before passing to
Is_Effectively_Volatile, which was crashing on a failed
assertion.
* sem_prag.adb (Analyze_External_Property_In_Decl_Part): Prevent
call to No_Caching_Enabled with entities other than variables,
which was crashing on a failed assertion.
(Analyze_Pragma): Style cleanups.
* sem_util.adb (Is_Effectively_Volatile): Enforce comment with
an assertion; prevent call to No_Caching_Enabled with entities
other than variables.
(Is_Effectively_Volatile_Object): Only call
Is_Effectively_Volatile on objects, not on types.
(No_Caching_Enabled): Enforce comment with an assertion.diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -19977,6 +19977,7 @@ package body Sem_Ch3 is
  end if;
 
  Set_Etype (Defining_Identifier (Discr), Discr_Type);
+ Set_Ekind (Defining_Identifier (Discr), E_Discriminant);
 
  --  If a discriminant specification includes the assignment compound
  --  delimiter followed by an expression, the expression is the default
@@ -20035,7 +20036,7 @@ package body Sem_Ch3 is
  (Defining_Identifier (Discr), Expression (Discr));
 end if;
 
---  In gnatc or gnatprove mode, make sure set Do_Range_Check flag
+--  In gnatc or GNATprove mode, make sure set Do_Range_Check flag
 --  gets set unless we can be sure that no range check is required.
 
 if not Expander_Active
@@ -20175,7 +20176,6 @@ package body Sem_Ch3 is
   Discr_Number := Uint_1;
   while Present (Discr) loop
  Id := Defining_Identifier (Discr);
- Set_Ekind (Id, E_Discriminant);
  Init_Component_Location (Id);
  Init_Esize (Id);
  Set_Discriminant_Number (Id, Discr_Number);


diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -2122,7 +2122,9 @@ package body Sem_Prag is
   if Prag_Id /= Pragma_No_Caching
 and then not Is_Effectively_Volatile (Obj_Id)
   then
- if No_Caching_Enabled (Obj_Id) then
+ if Ekind (Obj_Id) = E_Variable
+   and then No_Caching_Enabled (Obj_Id)
+ then
 SPARK_Msg_N
   ("illegal combination of external property % and property "
& """No_Caching"" (SPARK RM 7.1.2(6))", N);
@@ -13363,7 +13365,7 @@ package body Sem_Prag is
 --  respective root types.
 
 if Nkind (Obj_Or_Type_Decl) /= N_Object_Declaration then
-   if (Prag_Id = Pragma_No_Caching)
+   if Prag_Id = Pragma_No_Caching
   or not Nkind_In (Original_Node (Obj_Or_Type_Decl),
N_Full_Type_Declaration,
N_Private_Type_Declaration,
@@ -13383,7 +13385,8 @@ package body Sem_Prag is
 --  will be done at the end of the declarative region that
 --  contains the pragma.
 
-if Ekind (Obj_Or_Type_Id) = E_Variable or Is_Type (Obj_Or_Type_Id)
+if Ekind (Obj_Or_Type_Id) = E_Variable
+  or else Is_Type (Obj_Or_Type_Id)
 then
 
--  In the case of a type, pragma is a type-related


diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -15651,12 +15651,14 @@ package body Sem_Util is
 
   --  Otherwise Id denotes an object
 
-  else
+  else pragma Assert (Is_Object (Id));
  --  A volatile object for which No_Caching is enabled is not
  --  effectively volatile.
 
  return
-   (Is_Volatile (Id) and then not No_Caching_Enabled (Id))
+   (Is_Volatile (Id)
+and then not
+  (Ekind (Id) = E_Variable and then No_Caching_Enabled (Id)))
  or else Has_Volatile_Components (Id)
  or else Is_Effectively_Volatile (Etype (Id));
   end if;
@@ -15669,7 +15671,8 @@ package body Sem_Util is
function Is_Effectively_Volatile_Object (N : Node_Id) return Boolean is
begin
   if Is_Entity_Name (N) then
- return Is_Effectively_Volatile (Entity (N));
+ return Is_Object (Entity (N))
+   and then 

[Ada] Revert too late setting of Ekind on discriminants

2020-07-10 Thread Pierre-Marie de Rodat
A recent patch enforced an existing comment in Is_Effectively_Volatile
with an assertion. To satisfy this assertion, it also set the Ekind on
discriminants earlier. However, a subtle prevention of cascaded errors
in routine Enter_Name relies on the Ekind of discriminants being set
late.

This patch reverts change to setting Ekind for discriminants and instead
detects effective volatility of a discriminant by directly looking at
its type.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch3.adb (Process_Discriminants): Revert recent change to
location of Set_Ekind; detect effectively volatile discriminants
by their type only.diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -19977,7 +19977,6 @@ package body Sem_Ch3 is
  end if;
 
  Set_Etype (Defining_Identifier (Discr), Discr_Type);
- Set_Ekind (Defining_Identifier (Discr), E_Discriminant);
 
  --  If a discriminant specification includes the assignment compound
  --  delimiter followed by an expression, the expression is the default
@@ -20131,10 +20130,13 @@ package body Sem_Ch3 is
 
  --  A discriminant cannot be effectively volatile (SPARK RM 7.1.3(4)).
  --  This check is relevant only when SPARK_Mode is on as it is not a
- --  standard Ada legality rule.
+ --  standard Ada legality rule. The only way for a discriminant to be
+ --  effectively volatile is to have an effectively volatile type, so
+ --  we check this directly, because the Ekind of Discr might not be
+ --  set yet (to help preventing cascaded errors on derived types).
 
  if SPARK_Mode = On
-   and then Is_Effectively_Volatile (Defining_Identifier (Discr))
+   and then Is_Effectively_Volatile (Discr_Type)
  then
 Error_Msg_N ("discriminant cannot be volatile", Discr);
  end if;
@@ -20176,6 +20178,7 @@ package body Sem_Ch3 is
   Discr_Number := Uint_1;
   while Present (Discr) loop
  Id := Defining_Identifier (Discr);
+ Set_Ekind (Id, E_Discriminant);
  Init_Component_Location (Id);
  Init_Esize (Id);
  Set_Discriminant_Number (Id, Discr_Number);




[Ada] Fix expansion of 'Update with multiple choices in GNATprove

2020-07-10 Thread Pierre-Marie de Rodat
GNAT expands attribute Update applied to a record component into a
sequence of assignments to a temporary object and applies range checks
when analysing those assignment. GNATprove keeps such an aggregate
unexpanded, so it misses range checks, especially when several
components of a different type are updated with a single expression
(e.g. when components with types Natural and Positive are updated with
0).

This is now fixed by a custom expansion for GNATprove; GNAT is
unaffected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_spark.adb (Expand_SPARK_N_Attribute_Reference): Fix
expansion of attribute Update.diff --git a/gcc/ada/exp_spark.adb b/gcc/ada/exp_spark.adb
--- a/gcc/ada/exp_spark.adb
+++ b/gcc/ada/exp_spark.adb
@@ -258,10 +258,12 @@ package body Exp_SPARK is
 
 Assoc : Node_Id;
 Comp  : Node_Id;
+Comp_Id   : Entity_Id;
 Comp_Type : Entity_Id;
 Expr  : Node_Id;
 Index : Node_Id;
 Index_Typ : Entity_Id;
+New_Assoc : Node_Id;
 
  begin
 --  Apply scalar range checks on the updated components, if needed
@@ -346,19 +348,65 @@ package body Exp_SPARK is
 
 else pragma Assert (Is_Record_Type (Typ));
 
+   --  If the aggregate has multiple component choices, e.g.
+   --
+   --X'Update (A | B | C => 123)
+   --
+   --  then each component might be of a different type and might
+   --  or might not require a range check. We first rewrite
+   --  associations into single-component choices, e.g.:
+   --
+   --X'Update (A => 123, B => 123, C => 123)
+   --
+   --  and then apply range checks to individual copies of the
+   --  expressions.
+
+   --  Iterate over associations of the original aggregate
+
Assoc := First (Component_Associations (Aggr));
+
+   --  Rewrite into a new aggregate and decorate
+
+   Rewrite
+ (Aggr,
+  Make_Aggregate
+(Sloc   => Sloc (Aggr),
+ Component_Associations => New_List));
+
+   Set_Etype (Aggr, Typ);
+
+   --  Populate the new aggregate with component associations
+
while Present (Assoc) loop
-  Expr  := Expression (Assoc);
-  Comp  := First (Choices (Assoc));
-  Comp_Type := Etype (Entity (Comp));
+  Expr := Expression (Assoc);
+  Comp := First (Choices (Assoc));
+
+  while Present (Comp) loop
+ Comp_Id   := Entity (Comp);
+ Comp_Type := Etype (Comp_Id);
 
-  --  Use the type of the first component from the Choices
-  --  list, as multiple components can only appear there if
-  --  they have exactly the same type.
+ New_Assoc :=
+   Make_Component_Association
+ (Sloc   => Sloc (Assoc),
+  Choices=>
+New_List
+  (New_Occurrence_Of (Comp_Id, Sloc (Comp))),
+  Expression => New_Copy_Tree (Expr));
 
-  if Is_Scalar_Type (Comp_Type) then
- Apply_Scalar_Range_Check (Expr, Comp_Type);
-  end if;
+ --  New association must be attached as a child of the
+ --  aggregate before we analyze it.
+
+ Append (New_Assoc, Component_Associations (Aggr));
+
+ Analyze_And_Resolve (Expression (New_Assoc), Comp_Type);
+
+ if Is_Scalar_Type (Comp_Type) then
+Apply_Scalar_Range_Check
+  (Expression (New_Assoc), Comp_Type);
+ end if;
+
+ Next (Comp);
+  end loop;
 
   Next (Assoc);
end loop;




[Ada] Make System.Generic_Bignums more flexible

2020-07-10 Thread Pierre-Marie de Rodat
Reorganize the code and add new generic parameters so that this unit can
be reused in more contexts and in particular provide support for bounded
large integers without needing any dynamic memory allocation nor
secondary stack.

Move the implementation of To_String to System.Generic_Bignums to allow more
code sharing.

We now provide bitwise operations on big integers: and, or, shift left,
shift right.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* Makefile.rtl (GNATRTL_NONTASKING_OBJS): Add s-shabig.o.
* libgnat/s-shabig.ads: New file to share definitions.
* libgnat/s-genbig.ads, libgnat/s-genbig.adb: Reorganized to
make it more generic and flexible in terms of memory allocation
and data structure returned.
(To_String): Moved to System.Generic_Bignums to allow sharing
this code.
(Big_And, Big_Or, Big_Shift_Left, Big_Shift_Right): New.
* libgnat/s-bignum.adb, libgnat/s-bignum.ads: Adapt to new
System.Generic_Bignums spec.
* libgnat/a-nbnbin.adb: Likewise.
(To_String): Moved to System.Generic_Bignums to allow sharing
this code.
* libgnat/a-nbnbre.adb (Normalize): Fix handling of Num = 0
leading to an exception.

patch.diff.gz
Description: application/gzip


[Ada] Add global contracts to Ada.Numerics.Big_Numbers libraries

2020-07-10 Thread Pierre-Marie de Rodat
This patch adds global contracts to functions from
Ada.Numerics.Big_Numbers.Big_Integers and
Ada.Numerics.Big_Numbers.Big_Reals. This removes the warnings returned
when using these functions in SPARK.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* libgnat/a-nbnbin.ads, libgnat/a-nbnbre.ads: Add global
contract (Global => null) to all functions.diff --git a/gcc/ada/libgnat/a-nbnbin.ads b/gcc/ada/libgnat/a-nbnbin.ads
--- a/gcc/ada/libgnat/a-nbnbin.ads
+++ b/gcc/ada/libgnat/a-nbnbin.ads
@@ -28,23 +28,26 @@ is
   Put_Image   => Put_Image;
 
function Is_Valid (Arg : Big_Integer) return Boolean
- with Convention => Intrinsic;
+   with
+ Convention => Intrinsic,
+ Global => null;
 
subtype Valid_Big_Integer is Big_Integer
  with Dynamic_Predicate => Is_Valid (Valid_Big_Integer),
   Predicate_Failure => raise Program_Error;
 
-   function "=" (L, R : Valid_Big_Integer) return Boolean;
+   function "=" (L, R : Valid_Big_Integer) return Boolean with Global => null;
 
-   function "<" (L, R : Valid_Big_Integer) return Boolean;
+   function "<" (L, R : Valid_Big_Integer) return Boolean with Global => null;
 
-   function "<=" (L, R : Valid_Big_Integer) return Boolean;
+   function "<=" (L, R : Valid_Big_Integer) return Boolean with Global => null;
 
-   function ">" (L, R : Valid_Big_Integer) return Boolean;
+   function ">" (L, R : Valid_Big_Integer) return Boolean with Global => null;
 
-   function ">=" (L, R : Valid_Big_Integer) return Boolean;
+   function ">=" (L, R : Valid_Big_Integer) return Boolean with Global => null;
 
-   function To_Big_Integer (Arg : Integer) return Valid_Big_Integer;
+   function To_Big_Integer (Arg : Integer) return Valid_Big_Integer
+ with Global => null;
 
subtype Big_Positive is Big_Integer
  with Dynamic_Predicate =>
@@ -60,79 +63,105 @@ is
 
function In_Range
  (Arg : Valid_Big_Integer; Low, High : Big_Integer) return Boolean
-   is (Low <= Arg and Arg <= High);
+   is (Low <= Arg and Arg <= High)
+   with
+ Global => null;
 
function To_Integer (Arg : Valid_Big_Integer) return Integer
- with Pre => In_Range (Arg,
-   Low  => To_Big_Integer (Integer'First),
-   High => To_Big_Integer (Integer'Last))
-  or else (raise Constraint_Error);
+   with
+ Pre=> In_Range (Arg,
+ Low  => To_Big_Integer (Integer'First),
+ High => To_Big_Integer (Integer'Last))
+or else (raise Constraint_Error),
+ Global => null;
 
generic
   type Int is range <>;
package Signed_Conversions is
 
-  function To_Big_Integer (Arg : Int) return Valid_Big_Integer;
+  function To_Big_Integer (Arg : Int) return Valid_Big_Integer
+with Global => null;
 
   function From_Big_Integer (Arg : Valid_Big_Integer) return Int
-with Pre => In_Range (Arg,
-  Low  => To_Big_Integer (Int'First),
-  High => To_Big_Integer (Int'Last))
- or else (raise Constraint_Error);
-
+  with
+Pre=> In_Range (Arg,
+Low  => To_Big_Integer (Int'First),
+High => To_Big_Integer (Int'Last))
+   or else (raise Constraint_Error),
+Global => null;
end Signed_Conversions;
 
generic
   type Int is mod <>;
package Unsigned_Conversions is
 
-  function To_Big_Integer (Arg : Int) return Valid_Big_Integer;
+  function To_Big_Integer (Arg : Int) return Valid_Big_Integer
+with Global => null;
 
   function From_Big_Integer (Arg : Valid_Big_Integer) return Int
-with Pre => In_Range (Arg,
-  Low  => To_Big_Integer (Int'First),
-  High => To_Big_Integer (Int'Last))
- or else (raise Constraint_Error);
+  with
+Pre=> In_Range (Arg,
+Low  => To_Big_Integer (Int'First),
+High => To_Big_Integer (Int'Last))
+   or else (raise Constraint_Error),
+Global => null;
 
end Unsigned_Conversions;
 
function To_String (Arg   : Valid_Big_Integer;
Width : Field := 0;
Base  : Number_Base := 10) return String
- with Post => To_String'Result'First = 1;
+   with
+ Post   => To_String'Result'First = 1,
+ Global => null;
 
-   function From_String (Arg : String) return Big_Integer;
+   function From_String (Arg : String) return Big_Integer
+ with Global => null;
 
procedure Put_Image (S : in out Sink'Class; V : Big_Integer);
 
-   function "+" (L : Valid_Big_Integer) return Valid_Big_Integer;
+   function "+" (L : Valid_Big_Integer) return Valid_Big_Integer
+  with Global => null;
 
-   function "-" (L : Valid_Big_Integer) return 

[Ada] Fix crash on quantified expression in expression function (2)

2020-07-10 Thread Pierre-Marie de Rodat
This just replaces Find_Aspect with Find_Value_Of_Aspect, which seems
to be the preferred idiom to retrieve the value of an aspect.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* freeze.adb (Freeze_Expr_Types): Replace call to Find_Aspect
with call to Find_Value_Of_Aspect and adjust accordingly.diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -8000,10 +8000,11 @@ package body Freeze is
  then
 declare
Iter : constant Node_Id :=
-   Find_Aspect (Etype (Node), Aspect_Default_Iterator);
+ Find_Value_Of_Aspect (Etype (Node), Aspect_Default_Iterator);
+
 begin
if Present (Iter) then
-  Check_And_Freeze_Type (Etype (Expression (Iter)));
+  Check_And_Freeze_Type (Etype (Iter));
end if;
 end;
  end if;




[Ada] Fix crash on quantified expression in expression function

2020-07-10 Thread Pierre-Marie de Rodat
The problem is that the compiler freezes the iterator type associated
with a given type in the body of an expression function that contains
a quantified expression for this type and happens to be the completion
of a previous declaration.   The reason is that Freeze_Expr_Types does
not see that the iterator type is referenced by the expression.

The patch also changes Write_Field24_Name to also display the field as
the Related_Expression for an E_Loop_Parameter entity.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* einfo.adb (Write_Field24_Name): Handle E_Loop_Parameter.
* freeze.adb (Freeze_Expr_Types): Freeze the iterator type used as
Default_Iterator of the name of an N_Iterator_Specification node.diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb
--- a/gcc/ada/einfo.adb
+++ b/gcc/ada/einfo.adb
@@ -10969,6 +10969,7 @@ package body Einfo is
 
  when Type_Kind
 | E_Constant
+| E_Loop_Parameter
 | E_Variable
  =>
 Write_Str ("Related_Expression");


diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -7990,6 +7990,22 @@ package body Freeze is
and then Nkind (Parent (Node)) = N_Explicit_Dereference
  then
 Check_And_Freeze_Type (Designated_Type (Etype (Node)));
+
+ --  An iterator specification freezes the iterator type, even though
+ --  that type is not attached to an entity in the construct.
+
+ elsif Nkind (Node) in N_Has_Etype
+   and then Nkind (Parent (Node)) = N_Iterator_Specification
+   and then Node = Name (Parent (Node))
+ then
+declare
+   Iter : constant Node_Id :=
+   Find_Aspect (Etype (Node), Aspect_Default_Iterator);
+begin
+   if Present (Iter) then
+  Check_And_Freeze_Type (Etype (Expression (Iter)));
+   end if;
+end;
  end if;
 
  --  No point in posting several errors on the same expression




Re: [PATCH] [AVX512] [PR87767] Optimize memory broadcast for constant vector under AVX512

2020-07-10 Thread Hongtao Liu via Gcc-patches
+ maintainer.
cc H.J

On Thu, Jul 9, 2020 at 4:33 PM Hongtao Liu  wrote:
>
> Hi:
>   For a constant vector having one duplicated value, there's no need
> to put the whole vector in the constant pool, using embedded broadcast
> instead.
>
>   Bootstrap test is Ok, regression test for i386/x86-64 backend is ok.
>
> gcc/ChangeLog:
>
> PR target/87767
> * config/i386/i386-features.c
> (replace_constant_pool_with_broadcast): New function.
> (constant_pool_broadcast): Ditto.
> (class pass_constant_pool_broadcast): New pass.
> (make_pass_constant_pool_broadcast): Ditto.
> * config/i386/i386-passes.def: Insert new pass after combine.
> * config/i386/i386-protos.h
> (make_pass_constant_pool_broadcast): Declare.
> * config/i386/sse.md (*avx512dq_mul3_bcst,
> *avx512f_mul3_bcst): New define_insn.
>
> gcc/testsuite/ChangeLog:
>
> PR target/87767
> * gcc.target/i386/avx2-broadcast-pr87767-1.c: New test.
> * gcc.target/i386/avx512f-broadcast-pr87767-1.c: New test.
> * gcc.target/i386/avx512f-broadcast-pr87767-2.c: New test.
> * gcc.target/i386/avx512vl-broadcast-pr87767-1.c: New test.
> * gcc.target/i386/pr92865-1.c: Adjust testcase.
>
>
>
>
> --
> BR,
> Hongtao



-- 
BR,
Hongtao


[PATCH] gcov: create folders with 0777.

2020-07-10 Thread Martin Liška

As mention in the PR, we should leave rights to umask.

I'm going to install the patch if there are no comments.
Martin

libgcc/ChangeLog:

PR gcov-profile/96035
* libgcov-driver-system.c: Create gcov folders with 0777
so that it respects a system umask.
---
 libgcc/libgcov-driver-system.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index 031f057e318..216992afa8a 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -115,7 +115,7 @@ create_file_directory (char *filename)
 /* Try to make directory if it doesn't already exist.  */
 if (access (filename, F_OK) == -1
 #ifdef TARGET_POSIX_IO
-&& mkdir (filename, 0755) == -1
+   && mkdir (filename, 0777) == -1
 #else
 #ifdef mkdir
 #undef mkdir
--
2.27.0



[PATCH] fix constant folding from array CTORs

2020-07-10 Thread Richard Biener
This fixes the case where we try to fold a read from an
array initalizer and happen to cross the boundary of
multiple CTORs which isn't really supported.  For the
interesting cases like the testcase we actually handle
the folding by encoding the whole initializer.

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

2020-07-10  Richard Biener  

PR tree-optimization/96133
* gimple-fold.c (fold_array_ctor_reference): Do not
recurse to folding a CTOR that does not fully cover the
asked for object.

* gcc.dg/torture/pr96133.c: New testcase.
---
 gcc/gimple-fold.c  | 11 +--
 gcc/testsuite/gcc.dg/torture/pr96133.c | 16 
 2 files changed, 25 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr96133.c

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 41b84ba3bb3..dfda6db5e96 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -6875,10 +6875,17 @@ fold_array_ctor_reference (tree type, tree ctor,
 SIZE to the size of the accessed element.  */
  inner_offset = 0;
  type = TREE_TYPE (val);
- size = elt_size.to_uhwi () * BITS_PER_UNIT;
+ size = elt_sz * BITS_PER_UNIT;
}
+  else if (size && access_index < CONSTRUCTOR_NELTS (ctor) - 1
+  && TREE_CODE (val) == CONSTRUCTOR
+  && (elt_sz * BITS_PER_UNIT - inner_offset) < size)
+   /* If this isn't the last element in the CTOR and a CTOR itself
+  and it does not cover the whole object we are requesting give up
+  since we're not set up for combining from multiple CTORs.  */
+   return NULL_TREE;
 
-  *suboff += (access_index * elt_size * BITS_PER_UNIT).to_uhwi ();
+  *suboff += access_index.to_uhwi () * elt_sz * BITS_PER_UNIT;
   return fold_ctor_reference (type, val, inner_offset, size, from_decl,
  suboff);
 }
diff --git a/gcc/testsuite/gcc.dg/torture/pr96133.c 
b/gcc/testsuite/gcc.dg/torture/pr96133.c
new file mode 100644
index 000..8d051ce2913
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr96133.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+
+typedef int T;
+static const T a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
+typedef T v2 __attribute__((vector_size(2*sizeof(T;
+
+int
+main()
+{
+  const T *p = [0][2];
+  v2 x = *(const v2 *)p;
+  T z = x[1];
+  if (z != 4)
+__builtin_abort ();
+  return 0;
+}
-- 
2.26.2


Re: [PATCH] Remove dead vector comparisons

2020-07-10 Thread Richard Biener via Gcc-patches
On Fri, Jul 10, 2020 at 9:50 AM Martin Liška  wrote:
>
> As mentioned in the PR, we need to clean up orphan vector comparisons
> that tend to happen be gimplification of VEC_COND_EXPR.
>
> I've done that easily in expand_vector_comparison where I add these
> to a bitmap used in simple DCE.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> Ready to be installed?

I don't like this much - the reason for the dead code is that the gimplifier,
while it manages to DCE the VEC_COND_EXPR because the value is not
needed, does not apply the same for the operands where only side-effects
would need to be kept.

But then if the vector comparisons would not be dead, the testcase
would still ICE even with your patch.  And the reason for the ICE is
that vector lowering checks

  if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)
  && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))
{

while RTL expansion has

  /* For vector typed comparisons emit code to generate the desired
 all-ones or all-zeros mask.  */
  if (TREE_CODE (ops->type) == VECTOR_TYPE)
{
  tree ifexp = build2 (ops->code, ops->type, arg0, arg1);
  if (VECTOR_BOOLEAN_TYPE_P (ops->type)
  && expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, ops->code))
return expand_vec_cmp_expr (ops->type, ifexp, target);
  else
gcc_unreachable ();

so vector lowering doesn't lower vector comparisons when we can expand
via a VEC_COND_EXPR but the RTL expansion code asserts this will not
be needed.

Thus this should either be fixed by re-instantiating the RTL expansion code
or handling vector comparisons in gimple-isel.cc at least when they need
to be expanded as VEC_COND_EXPR.

Richard.

> Thanks,
> Martin
>
> gcc/ChangeLog:
>
> PR tree-optimization/96128
> * tree-vect-generic.c (expand_vector_comparison): Remove vector
> comparisons that don't have a usage.
>
> gcc/testsuite/ChangeLog:
>
> PR tree-optimization/96128
> * gcc.target/s390/vector/pr96128.c: New test.
> ---
>   .../gcc.target/s390/vector/pr96128.c  | 35 +++
>   gcc/tree-vect-generic.c   |  4 ++-
>   2 files changed, 38 insertions(+), 1 deletion(-)
>   create mode 100644 gcc/testsuite/gcc.target/s390/vector/pr96128.c
>
> diff --git a/gcc/testsuite/gcc.target/s390/vector/pr96128.c 
> b/gcc/testsuite/gcc.target/s390/vector/pr96128.c
> new file mode 100644
> index 000..20abe5e515c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/s390/vector/pr96128.c
> @@ -0,0 +1,35 @@
> +/* PR tree-optimization/96128 */
> +/* { dg-options "-march=z13" } */
> +
> +#define B_TEST(TYPE) { TYPE v __attribute__((vector_size(16))); (void)((v < 
> v) < v); }
> +#ifdef __cplusplus
> +#define T_TEST(TYPE) { TYPE s; TYPE v __attribute__((vector_size(16))); 
> __typeof((v v); }
> +#else
> +#define T_TEST(TYPE)
> +#endif
> +#define T(TYPE) B_TEST(TYPE) T_TEST(TYPE)
> +#ifdef __SIZEOF_INT128__
> +#define SIZEOF_MAXINT __SIZEOF_INT128__
> +#else
> +#define SIZEOF_MAXINT __SIZEOF_LONG_LONG__
> +#endif
> +
> +void f ()
> +{
> +  T(short)
> +  T(int)
> +  T(long)
> +  T(long long)
> +
> +  T_TEST(float)
> +  T_TEST(double)
> +  /* Avoid trouble with non-power-of-two sizes.
> + Also avoid trouble with long double larger than integral types.  */
> +#if !defined(__i386__) && !defined(__x86_64__) && !defined(__m68k__) \
> +&& !defined(__ia64__) && !defined(__hppa__) \
> +&& (__SIZEOF_LONG_DOUBLE__ & (__SIZEOF_LONG_DOUBLE__ - 1)) == 0 \
> +&& __SIZEOF_LONG_DOUBLE__ <= 16 \
> +&& __SIZEOF_LONG_DOUBLE__ <= SIZEOF_MAXINT
> +  T_TEST(long double)
> +#endif
> +}
> diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
> index f8bd26f2156..636104dea13 100644
> --- a/gcc/tree-vect-generic.c
> +++ b/gcc/tree-vect-generic.c
> @@ -415,7 +415,9 @@ expand_vector_comparison (gimple_stmt_iterator *gsi, tree 
> type, tree op0,
> }
>   }
>
> -  if (!uses.is_empty () && vec_cond_expr_only)
> +  if (uses.is_empty ())
> +bitmap_set_bit (dce_ssa_names, SSA_NAME_VERSION (lhs));
> +  else if (vec_cond_expr_only)
>   return NULL_TREE;
>
> tree t;
> --
> 2.27.0
>


Re: [PATCH] Add -fdump-profile-report.

2020-07-10 Thread Richard Biener via Gcc-patches
On Thu, Jul 9, 2020 at 1:55 PM Martin Liška  wrote:
>
> When using -fprofile-report, -fdump-profile-report can be used to
> print the report to a foo.c.000i.profile-report file instead
> of stderr. I see it handy for comparison purpose.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> Ready to be installed?

OK.

> Thanks,
> Martin
>
> ---
>   gcc/dumpfile.c |  3 ++-
>   gcc/dumpfile.h |  1 +
>   gcc/passes.c   | 47 +++
>   3 files changed, 30 insertions(+), 21 deletions(-)
>
> diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c
> index 5d61946fc49..9a5496a18e8 100644
> --- a/gcc/dumpfile.c
> +++ b/gcc/dumpfile.c
> @@ -103,8 +103,9 @@ static struct dump_file_info dump_files[TDI_end] =
> DUMP_FILE_INFO (".gimple", "tree-gimple", DK_tree, 0),
> DUMP_FILE_INFO (".nested", "tree-nested", DK_tree, 0),
> DUMP_FILE_INFO (".lto-stream-out", "ipa-lto-stream-out", DK_ipa, 0),
> +  DUMP_FILE_INFO (".profile-report", "profile-report", DK_ipa, 0),
>   #define FIRST_AUTO_NUMBERED_DUMP 1
> -#define FIRST_ME_AUTO_NUMBERED_DUMP 4
> +#define FIRST_ME_AUTO_NUMBERED_DUMP 5
>
> DUMP_FILE_INFO (NULL, "lang-all", DK_lang, 0),
> DUMP_FILE_INFO (NULL, "tree-all", DK_tree, 0),
> diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h
> index 00e175a4737..ee9e602b67f 100644
> --- a/gcc/dumpfile.h
> +++ b/gcc/dumpfile.h
> @@ -48,6 +48,7 @@ enum tree_dump_index
> TDI_gimple, /* dump each function after gimplifying it */
> TDI_nested, /* dump each function after unnesting it */
> TDI_lto_stream_out, /* dump information about lto streaming */
> +  TDI_profile_report,  /* dump information about profile quality */
>
> TDI_lang_all,   /* enable all the language dumps.  */
> TDI_tree_all,   /* enable all the GENERIC/GIMPLE 
> dumps.  */
> diff --git a/gcc/passes.c b/gcc/passes.c
> index 07b2613ffea..a5da9a46f4e 100644
> --- a/gcc/passes.c
> +++ b/gcc/passes.c
> @@ -1850,10 +1850,15 @@ pass_manager::dump_profile_report () const
>
> if (!profile_record)
>   return;
> -  fprintf (stderr, "\nProfile consistency report:\n\n");
> -  fprintf (stderr, " |mismatch |mismatch 
> | |\n");
> -  fprintf (stderr, "Pass name|IN|IN|OUT   
> |OUT   |overall  |\n");
> -  fprintf (stderr, " |freq  |count |freq  
> |count |size  |time  |\n");
> +
> +  FILE *dump_file = dump_begin (TDI_profile_report, NULL);
> +  if (dump_file == NULL)
> +dump_file = stderr;
> +
> +  fprintf (dump_file, "Profile consistency report:\n\n");
> +  fprintf (dump_file, " |mismatch 
> |mismatch | |\n");
> +  fprintf (dump_file, "Pass name|IN|IN|OUT   
> |OUT   |overall  |\n");
> +  fprintf (dump_file, " |freq  |count |freq  
> |count |size  |time  |\n");
>
> for (int i = 1; i < passes_by_id_size; i++)
>   if (profile_record[i].run)
> @@ -1876,47 +1881,47 @@ pass_manager::dump_profile_report () const
> || rel_time_change || rel_size_change)
>   {
> last_reported = i;
> -   fprintf (stderr, "%-33s", passes_by_id[i]->name);
> +   fprintf (dump_file, "%-33s", passes_by_id[i]->name);
> if (profile_record[i].num_mismatched_freq_in != last_freq_in)
> - fprintf (stderr, "| %+5i",
> + fprintf (dump_file, "| %+5i",
>profile_record[i].num_mismatched_freq_in
>- last_freq_in);
> else
> - fprintf (stderr, "|  ");
> + fprintf (dump_file, "|  ");
> if (profile_record[i].num_mismatched_count_in != last_count_in)
> - fprintf (stderr, "| %+5i",
> + fprintf (dump_file, "| %+5i",
>profile_record[i].num_mismatched_count_in
>- last_count_in);
> else
> - fprintf (stderr, "|  ");
> + fprintf (dump_file, "|  ");
> if (profile_record[i].num_mismatched_freq_out != last_freq_out)
> - fprintf (stderr, "| %+5i",
> + fprintf (dump_file, "| %+5i",
>profile_record[i].num_mismatched_freq_out
>- last_freq_out);
> else
> - fprintf (stderr, "|  ");
> + fprintf (dump_file, "|  ");
> if (profile_record[i].num_mismatched_count_out != last_count_out)
> - fprintf (stderr, "| %+5i",
> + fprintf (dump_file, "| %+5i",
>profile_record[i].num_mismatched_count_out
>- last_count_out);
> else
> - fprintf (stderr, "|  

[PATCH] Remove dead vector comparisons

2020-07-10 Thread Martin Liška

As mentioned in the PR, we need to clean up orphan vector comparisons
that tend to happen be gimplification of VEC_COND_EXPR.

I've done that easily in expand_vector_comparison where I add these
to a bitmap used in simple DCE.

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

Ready to be installed?
Thanks,
Martin

gcc/ChangeLog:

PR tree-optimization/96128
* tree-vect-generic.c (expand_vector_comparison): Remove vector
comparisons that don't have a usage.

gcc/testsuite/ChangeLog:

PR tree-optimization/96128
* gcc.target/s390/vector/pr96128.c: New test.
---
 .../gcc.target/s390/vector/pr96128.c  | 35 +++
 gcc/tree-vect-generic.c   |  4 ++-
 2 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/s390/vector/pr96128.c

diff --git a/gcc/testsuite/gcc.target/s390/vector/pr96128.c 
b/gcc/testsuite/gcc.target/s390/vector/pr96128.c
new file mode 100644
index 000..20abe5e515c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/pr96128.c
@@ -0,0 +1,35 @@
+/* PR tree-optimization/96128 */
+/* { dg-options "-march=z13" } */
+
+#define B_TEST(TYPE) { TYPE v __attribute__((vector_size(16))); (void)((v < v) 
< v); }
+#ifdef __cplusplus
+#define T_TEST(TYPE) { TYPE s; TYPE v __attribute__((vector_size(16))); 
__typeof((v 
-  if (!uses.is_empty () && vec_cond_expr_only)

+  if (uses.is_empty ())
+bitmap_set_bit (dce_ssa_names, SSA_NAME_VERSION (lhs));
+  else if (vec_cond_expr_only)
 return NULL_TREE;
 
   tree t;

--
2.27.0



Re: [PATCH] rs6000: Split movsf_from_si from high word before reload[PR89310]

2020-07-10 Thread luoxhu via Gcc-patches



On 2020/7/10 03:25, Segher Boessenkool wrote:
> 
>> +  "TARGET_NO_SF_SUBREG"
>> +  "#"
>> +  "&& vsx_reg_sfsubreg_ok (operands[0], SFmode)"
> 
> Put this in the insn condition?  And since this is just a predicate,
> you can just use it instead of gpc_reg_operand.
> 
> (The split condition becomes "&& 1" then, not "").
> 

+(define_insn_and_split "movsf_from_si2"
+  [(set (match_operand:SF 0 "vsx_reg_sfsubreg_ok" "=wa")
+   (unspec:SF
+[(subreg:SI
+  (ashiftrt:DI
+   (match_operand:DI 1 "input_operand" "r")
+   (const_int 32))
+  0)]
+UNSPEC_SF_FROM_SI))
+  (clobber (match_scratch:DI 2 "=r"))]
+  "TARGET_NO_SF_SUBREG"
+  "#"
+  "&& 1"
+  [(const_int 0)]

This change is invalid as it will cause an ICE in PR42475.c, reason is:
insn #29 will be combined to insn #40, though split1 is success, but it 
will cause ICE in sched1 as the op[0] is not SFmode.  Without this, #29
won't be combined to #40 as the gpc_reg_operand (operands[0], E_SFmode)
will cause the match fail for subreg:SF (reg:SI 155 [ _4 ]) 0).


pr42475.c.268r.combine:
Trying 29 -> 40:
   29: {r120:SF=unspec[r133:DI>>0x20#0] 86;clobber scratch;}
   40: r155:SI#0=r120:SF
  REG_DEAD r120:SF
Successfully matched this instruction:
(set (subreg:SF (reg:SI 155 [ _4 ]) 0)
(unspec:SF [
(subreg:SI (ashiftrt:DI (reg:DI 133)
(const_int 32 [0x20])) 0)
] UNSPEC_SF_FROM_SI))
allowing combination of insns 29 and 40
original costs 12 + 4 = 16
replacement cost 12
deferring deletion of insn with uid = 29.
modifying insn i340: {r155:SI#0=unspec[r133:DI>>0x20#0] 86;clobber scratch;}
  REG_DEAD r133:DI
deferring rescan insn with uid = 40.


pr42475.c.273r.split1:
69: r172:DI=r133:DI&0x
70: r155:SI#0=unspec[r172:DI] 62
71: r155:SI#0=unspec[r155:SI#0] 103
41: NOTE_INSN_DELETED
42: r157:DI=r155:SI#0<<0x20


pr42475.c.280r.sched1:
pr42475.c: In function ‘bar’:
pr42475.c:20:1: error: unrecognizable insn:
   20 | }
  | ^
(insn 71 70 41 2 (set (subreg:SF (reg:SI 155 [ _4 ]) 0)
(unspec:SF [
(subreg:SF (reg:SI 155 [ _4 ]) 0)
] UNSPEC_VSX_CVSPDPN)) -1
 (nil))
during RTL pass: sched1
dump file: pr42475.c.280r.sched1
pr42475.c:20:1: internal compiler error: in extract_insn, at recog.c:2294
Please submit a full bug report,
with preprocessed source if appropriate.
See  for instructions.


VS not using vsx_reg_sfsubreg_ok as condition:


pr42475.c.268r.combine:
Trying 29 -> 40:
   29: {r120:SF=unspec[r133:DI>>0x20#0] 86;clobber scratch;}
   40: r155:SI#0=r120:SF
  REG_DEAD r120:SF
Failed to match this instruction:
(set (subreg:SF (reg:SI 155 [ _4 ]) 0)
(unspec:SF [
(subreg:SI (ashiftrt:DI (reg:DI 133)
(const_int 32 [0x20])) 0)
] UNSPEC_SF_FROM_SI))


273r.split1:
69: r172:DI=r133:DI&0x
70: r120:SF=unspec[r172:DI] 62
71: r120:SF=unspec[r120:SF] 103
40: r155:SI#0=r120:SF
REG_DEAD r120:SF


Re: [PATCH 5/7 v6] vect: Support vector load/store with length in vectorizer

2020-07-10 Thread Kewen.Lin via Gcc-patches
Hi Richard,

on 2020/7/8 下午8:50, Richard Sandiford wrote:
> "Kewen.Lin"  writes:
>>> […]
 I tested the updated patch with this releasing, LOOP_VINFO_PEELING_FOR_GAPS
 part looks fine, but LOOP_VINFO_PEELING_FOR_ALIGNMENT caused one case to
 fail at execution during vect-partial-vector-usage=2.  So far the patch
 doesn't handle any niters_skip cases.  I think if we want to support it, 
 we have to add some handlings in/like what we have for masking, such as: 
 mask_skip_niters, vect_prepare_for_masked_peels etc.  

 Do you prefer me to extend the support in this patch series?
>>>
>>> It's not so much whether it has to be supported now, but more why
>>> it doesn't work now.  What was the reason for the failure?
>>>
>>> The peeling-with-masking thing is just an optimisation, so that we
>>> can vectorise the peeled iterations rather than falling back to
>>> scalar code for them.  It shouldn't be needed for correctness.
>>>
>>
>> Whoops, thanks for the clarification!  Nice, I just realized it's a way to
>> adopt partial vectors for prologue.  The fail case is 
>> gcc.dg/vect/vect-ifcvt-11.c.
>> There the first iteration is optimized out due to the known AND result of
>> IV 0, then it tries to peel 3 iterations, the number of remaining iterations
>> for vectorization body is expected to be 12.  But it still uses 15 and causes
>> out-of-bound access.
>>
>> The below fix can fix the failure.  The justification is that we need to use
>> the fixed up niters after peeling prolog for the vectorization body for
>> partial vectors.  I'm not sure why the other cases not using partial vectors 
>> don't need the fixed up niters, to avoid troubles I guarded it with 
>> LOOP_VINFO_USING_PARTIAL_VECTORS_P explicitly.
> 
> I think the reason is that if we're peeling prologue iterations and
> the total number of iterations isn't fixed, full-vector vectorisation
> will “almost always” need an epilogue loop too, and in that case
> niters_vector will be nonnull.
> 
> But that's not guaranteed to be true forever.  E.g. if the start
> pointers have a known misalignment that require peeling a constant
> number of iterations N, and if we can prove (using enhanced range/
> nonzero-bits information) that the way niters is calculated means
> that niter - N is a multiple of the vector size, we could peel
> the prologue and not the epilogue.  In that case, what your patch
> does would be correct.
> 

Thanks for the explanation, it makes more sense!

> So…
> 
>> --- a/gcc/tree-vect-loop.c
>> +++ b/gcc/tree-vect-loop.c
>> @@ -,6 +8896,11 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple 
>> *loop_vectorized_call)
>>   LOOP_VINFO_INT_NITERS (loop_vinfo) / lowest_vf);
>>step_vector = build_one_cst (TREE_TYPE (niters));
>>  }
>> +  else if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
>> +  && !vect_use_loop_mask_for_alignment_p (loop_vinfo))
>> +   vect_gen_vector_loop_niters (loop_vinfo, LOOP_VINFO_NITERS 
>> (loop_vinfo),
>> +_vector, _vector,
>> +niters_no_overflow);
>>else
>>  vect_gen_vector_loop_niters (loop_vinfo, niters, _vector,
>>   _vector, niters_no_overflow);
> 
> …I think we should drop the LOOP_VINFO_USING_PARTIAL_VECTORS_P
> condition.  Could you also add a comment above the new call saying:
> 
>/* vect_do_peeling subtracted the number of peeled prologue
>   iterations from LOOP_VINFO_NITERS.  */
> 
> It wasn't obvious to me where the update was happening when I first
> looked at the code.
> 
> Very minor, but maybe also switch the last two cases round so that
> “else” is the default behaviour and the “if”s are the exceptions.
> 
> OK with those changes, thanks.

Bootstrapped/regtested on aarch64-linux-gnu and powerpc64le-linux-gnu.

Committed it via r11-1978 by incorporating your comments.  Thanks!

BR,
Kewen


Re: [PATCH V2] PING^2 correct COUNT and PROB for unrolled loop

2020-07-10 Thread Martin Liška

On 7/10/20 4:14 AM, Jiufu Guo wrote:

Thanks so much for your time and kindly help!!!


And I run your patch on SPEC2006 with:
https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549728.html

Doing that I see just few changes:

diff -qr /tmp/before /tmp/after
Files /tmp/before/Meat.fppized.f90.000i.profile-report and 
/tmp/after/Meat.fppized.f90.000i.profile-report differ
Files /tmp/before/bezier.cpp.000i.profile-report and 
/tmp/after/bezier.cpp.000i.profile-report differ
Files /tmp/before/module_big_step_utilities_em.fppized.f90.000i.profile-report 
and /tmp/after/module_big_step_utilities_em.fppized.f90.000i.profile-report 
differ
Files /tmp/before/module_cu_bmj.fppized.f90.000i.profile-report and 
/tmp/after/module_cu_bmj.fppized.f90.000i.profile-report differ
Files /tmp/before/momx2.f.000i.profile-report and 
/tmp/after/momx2.f.000i.profile-report differ
Files /tmp/before/momx3.f.000i.profile-report and 
/tmp/after/momx3.f.000i.profile-report differ
Files /tmp/before/tml.f.000i.profile-report and 
/tmp/after/tml.f.000i.profile-report differ
Files /tmp/before/tranx2.f.000i.profile-report and 
/tmp/after/tranx2.f.000i.profile-report differ
Files /tmp/before/tranx3.f.000i.profile-report and 
/tmp/after/tranx3.f.000i.profile-report differ

But I see few regression, e.g.:

$ cat bezier.ii
int bezier_value_t, bezier_value_du_1;
int bezier_value_u[4], bezier_value_du[4];
void bezier_value() {
  int i = 1;
  for (; i < 4; i++) {
bezier_value_u[i] = 1;
bezier_value_du[i] = i * bezier_value_u[i - 1];
bezier_value_t = bezier_value_du_1;
  }
}

$ g++ bezier.ii -c -march=native -O3 -Wno-multichar 
-Wno-aggressive-loop-optimizations -fdump-tree-pcom=/tmp/bad.txt
...

And your patch changed:

-   [local count: 134217728]:
+   [local count: 89478486]:

where the function looks like:

   [local count: 268435456]:
...
  if (ivtmp_45 > 1)
goto ; [50.00%]
  else
goto ; [50.00%]

   [local count: 89478486]:
  goto ; [100.00%]

So 89478486 != 268435456 / 2. That seems a regression caused by your patch.

Can you please check it?
Martin


  1   2   >