[gcc r15-3731] Fix small thinko in IPA mod/ref pass

2024-09-20 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:16d2d177ac11b4d968d0ec7df9602b3f4059583d

commit r15-3731-g16d2d177ac11b4d968d0ec7df9602b3f4059583d
Author: Eric Botcazou 
Date:   Fri Sep 20 12:32:13 2024 +0200

Fix small thinko in IPA mod/ref pass

When a memory copy operation is analyzed by analyze_ssa_name, if both the
load and store are made through the same SSA name, the store is overlooked.

gcc/
* ipa-modref.cc (modref_eaf_analysis::analyze_ssa_name): Always
process both the load and the store of a memory copy operation.

gcc/testsuite/
* gcc.dg/ipa/modref-4.c: New test.

Diff:
---
 gcc/ipa-modref.cc   |  3 ++-
 gcc/testsuite/gcc.dg/ipa/modref-4.c | 34 ++
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index 9275030c2546..400a8856de2d 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -2610,8 +2610,9 @@ modref_eaf_analysis::analyze_ssa_name (tree name, bool 
deferred)
 is used arbitrarily.  */
  if (memory_access_to (gimple_assign_rhs1 (assign), name))
m_lattice[index].merge (deref_flags (0, false));
+
  /* Handle *name = *exp.  */
- else if (memory_access_to (gimple_assign_lhs (assign), name))
+ if (memory_access_to (gimple_assign_lhs (assign), name))
m_lattice[index].merge_direct_store ();
}
  /* Handle lhs = *name.  */
diff --git a/gcc/testsuite/gcc.dg/ipa/modref-4.c 
b/gcc/testsuite/gcc.dg/ipa/modref-4.c
new file mode 100644
index ..71ed1ca5f5b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/modref-4.c
@@ -0,0 +1,34 @@
+/* { dg-options "-O"  } */
+/* { dg-do run } */
+
+static __attribute__((noipa)) int foo (void)
+{
+  return 1;
+}
+
+int main (void)
+{
+  struct S { int a; int b; };
+  struct T { struct S s; };
+
+  struct T t = { { 0, 0 } };
+  struct T u;
+
+  __attribute__((noinline)) void bar (void)
+  {
+if (foo ())
+  {
+   u = t;
+/* OK with u.s.a = 0; */
+  }
+  }
+
+  u.s.a = 1;
+
+  bar ();
+
+  if (u.s.a != 0)
+__builtin_abort ();
+
+  return 0;
+}


[gcc(refs/users/aoliva/heads/testme)] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
https://gcc.gnu.org/g:3bd0565cf130cb126fea3287d144031ec831

commit 3bd0565cf130cb126fea3287d144031ec831
Author: Alexandre Oliva 
Date:   Thu Sep 19 06:43:22 2024 -0300

adjust probs after modified ifcombine

Diff:
---
 gcc/fold-const.h  |  10 ++
 gcc/tree-ssa-ifcombine.cc | 416 --
 2 files changed, 335 insertions(+), 91 deletions(-)

diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index 3e3998b57b04..136764f5c7eb 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -258,6 +258,16 @@ extern void clear_type_padding_in_mask (tree, unsigned 
char *);
 extern bool clear_padding_type_may_have_padding_p (tree);
 extern bool arith_overflowed_p (enum tree_code, const_tree, const_tree,
const_tree);
+extern tree fold_truth_andor_maybe_separate (location_t loc,
+enum tree_code code,
+tree truth_type,
+enum tree_code lcode,
+tree ll_arg,
+tree lr_arg,
+enum tree_code rcode,
+tree rl_arg,
+tree rr_arg,
+tree *separatep);
 
 /* Class used to compare gimple operands.  */
 
diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index 79ccc70b2678..8258df8dbaf3 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa.h"
 #include "attribs.h"
 #include "asan.h"
+#include "bitmap.h"
 
 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
 #define LOGICAL_OP_NON_SHORT_CIRCUIT \
@@ -49,6 +50,28 @@ along with GCC; see the file COPYING3.  If not see
 false) >= 2)
 #endif
 
+/* Return TRUE iff COND is NULL, or the condition in it is constant.  */
+
+static bool
+constant_condition_p (gcond *cond)
+{
+  if (!cond)
+return true;
+
+  return (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
+ && CONSTANT_CLASS_P (gimple_cond_rhs (cond)));
+}
+
+/* Return FALSE iff the condition in the COND stmt that ends COND_BB is not
+   constant.  */
+
+static bool
+constant_condition_p (basic_block cond_bb)
+{
+  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
+  return constant_condition_p (cond);
+}
+
 /* This pass combines COND_EXPRs to simplify control flow.  It
currently recognizes bit tests and comparisons in chains that
represent logical and or logical or of two COND_EXPRs.
@@ -107,12 +130,7 @@ recognize_if_then_else (basic_block cond_bb,
   if (!*else_bb)
 *else_bb = e->dest;
 
-  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
-  if (!cond)
-return false;
-
-  if (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
-  && CONSTANT_CLASS_P (gimple_cond_rhs (cond)))
+  if (constant_condition_p (cond_bb))
 return false;
 
   return true;
@@ -364,14 +382,27 @@ recognize_bits_test (gcond *cond, tree *name, tree *bits, 
bool inv)
 }
 
 
-/* Update profile after code in outer_cond_bb was adjusted so
-   outer_cond_bb has no condition.  */
+/* Update profile after code in either outer_cond_bb or inner_cond_bb was
+   adjusted so that it has no condition.  */
 
 static void
 update_profile_after_ifcombine (basic_block inner_cond_bb,
basic_block outer_cond_bb)
 {
-  edge outer_to_inner = find_edge (outer_cond_bb, inner_cond_bb);
+  /* In the following we assume that inner_cond_bb has single predecessor.  */
+  gcc_assert (single_pred_p (inner_cond_bb));
+
+  basic_block outer_to_inner_bb = inner_cond_bb;
+  profile_probability prob = profile_probability::always ();
+  for (basic_block parent = single_pred (outer_to_inner_bb);
+   parent != outer_cond_bb;
+   parent = single_pred (outer_to_inner_bb))
+{
+  prob *= find_edge (parent, outer_to_inner_bb)->probability;
+  outer_to_inner_bb = parent;
+}
+
+  edge outer_to_inner = find_edge (outer_cond_bb, outer_to_inner_bb);
   edge outer2 = (EDGE_SUCC (outer_cond_bb, 0) == outer_to_inner
 ? EDGE_SUCC (outer_cond_bb, 1)
 : EDGE_SUCC (outer_cond_bb, 0));
@@ -382,38 +413,98 @@ update_profile_after_ifcombine (basic_block inner_cond_bb,
 std::swap (inner_taken, inner_not_taken);
   gcc_assert (inner_taken->dest == outer2->dest);
 
-  /* In the following we assume that inner_cond_bb has single predecessor.  */
-  gcc_assert (single_pred_p (inner_cond_bb));
-
-  /* Path outer_cond_bb->(outer2) needs to be merged into path
- outer_cond_bb->(outer_to_inner)->inner_cond_bb->(inner_taken)
- and probability of inner_not_taken updated.  */
-
-  inner_cond_bb->count = outer_cond_bb->count;
+  if (outer_to_inner_bb == inner_cond_bb
+  && constant_condition_p (outer_cond_bb))
+{
+ 

[gcc/aoliva/heads/testme] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
The branch 'aoliva/heads/testme' was updated to point to:

 3bd0565cf130... adjust probs after modified ifcombine

It previously pointed to:

 f8372d9ec46d... adjust probs after modified ifcombine

Diff:

!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
---

  f8372d9... adjust probs after modified ifcombine


Summary of changes (added commits):
---

  3bd0565... adjust probs after modified ifcombine


[gcc(refs/users/aoliva/heads/testme)] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
https://gcc.gnu.org/g:7660c0400ee5c9207397d3936be695af962d455e

commit 7660c0400ee5c9207397d3936be695af962d455e
Author: Alexandre Oliva 
Date:   Thu Sep 19 06:43:22 2024 -0300

adjust probs after modified ifcombine

Diff:
---
 gcc/fold-const.h |  10 +
 gcc/testsuite/gcc.dg/field-merge-7.c |  23 ++
 gcc/tree-ssa-ifcombine.cc| 482 ---
 3 files changed, 423 insertions(+), 92 deletions(-)

diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index 3e3998b57b04..136764f5c7eb 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -258,6 +258,16 @@ extern void clear_type_padding_in_mask (tree, unsigned 
char *);
 extern bool clear_padding_type_may_have_padding_p (tree);
 extern bool arith_overflowed_p (enum tree_code, const_tree, const_tree,
const_tree);
+extern tree fold_truth_andor_maybe_separate (location_t loc,
+enum tree_code code,
+tree truth_type,
+enum tree_code lcode,
+tree ll_arg,
+tree lr_arg,
+enum tree_code rcode,
+tree rl_arg,
+tree rr_arg,
+tree *separatep);
 
 /* Class used to compare gimple operands.  */
 
diff --git a/gcc/testsuite/gcc.dg/field-merge-7.c 
b/gcc/testsuite/gcc.dg/field-merge-7.c
new file mode 100644
index ..b0e953c01e91
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/field-merge-7.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ifcombine-details" } */
+
+/* Check that the third compare won't be combined with the first one.  */
+
+struct s {
+  char a, b;
+  int p;
+};
+
+struct s a = { 0, 0, 0 };
+struct s b = { 0, 0, 0 };
+
+int f () {
+  return (a.a != b.a || (a.p != b.p && a.b != b.b));
+}
+
+int g () {
+  return (a.a == b.a && (a.p == b.p || a.b == b.b));
+}
+
+/* { dg-do { scan-tree-dump-not "optimizing" "ifcombine" } } */
+/* { dg-do { scan-tree-dump-not "BIT_FIELD_REF" "ifcombine" } } */
diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index 79ccc70b2678..9bb250bf2993 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa.h"
 #include "attribs.h"
 #include "asan.h"
+#include "bitmap.h"
 
 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
 #define LOGICAL_OP_NON_SHORT_CIRCUIT \
@@ -49,6 +50,28 @@ along with GCC; see the file COPYING3.  If not see
 false) >= 2)
 #endif
 
+/* Return TRUE iff COND is NULL, or the condition in it is constant.  */
+
+static bool
+constant_condition_p (gcond *cond)
+{
+  if (!cond)
+return true;
+
+  return (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
+ && CONSTANT_CLASS_P (gimple_cond_rhs (cond)));
+}
+
+/* Return FALSE iff the condition in the COND stmt that ends COND_BB is not
+   constant.  */
+
+static bool
+constant_condition_p (basic_block cond_bb)
+{
+  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
+  return constant_condition_p (cond);
+}
+
 /* This pass combines COND_EXPRs to simplify control flow.  It
currently recognizes bit tests and comparisons in chains that
represent logical and or logical or of two COND_EXPRs.
@@ -107,15 +130,38 @@ recognize_if_then_else (basic_block cond_bb,
   if (!*else_bb)
 *else_bb = e->dest;
 
-  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
-  if (!cond)
-return false;
+  return true;
+}
+
+/* Same as recognize_if_then_else, but check that the condition is not
+   constant.  It is not useful to combine constant conditions.  */
 
-  if (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
-  && CONSTANT_CLASS_P (gimple_cond_rhs (cond)))
+static bool
+recognize_if_then_else_nc (basic_block cond_bb,
+  basic_block *then_bb, basic_block *else_bb)
+{
+  return recognize_if_then_else (cond_bb, then_bb, else_bb)
+&& !constant_condition_p (cond_bb);
+}
+
+/* Same as recognize_if_then_else, but don't associate the blocks with then and
+   else, check both possibilities.  */
+
+static bool
+recognize_if_succs (basic_block cond_bb,
+   basic_block succ1, basic_block succ2)
+{
+  basic_block t, e;
+
+  if (EDGE_COUNT (cond_bb->succs) != 2)
 return false;
 
-  return true;
+  /* Find both succs.  */
+  t = EDGE_SUCC (cond_bb, 0)->dest;
+  e = EDGE_SUCC (cond_bb, 1)->dest;
+
+  return ((t == succ1 && e == succ2)
+ || (t == succ2 && e == succ1));
 }
 
 /* Verify if the basic block BB does not have side-effects.  Return
@@ -364,14 +410,27 @@ recognize_bits_test (gcond *cond, tree *name, tree *bits, 
bool inv)
 }
 
 
-/* Update profile after code in outer_cond_bb was adjusted so
-   outer_con

[gcc/aoliva/heads/testme] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
The branch 'aoliva/heads/testme' was updated to point to:

 7660c0400ee5... adjust probs after modified ifcombine

It previously pointed to:

 1d6ef2e03dff... adjust probs after modified ifcombine

Diff:

!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
---

  1d6ef2e... adjust probs after modified ifcombine


Summary of changes (added commits):
---

  7660c04... adjust probs after modified ifcombine


[gcc r15-3729] testsuite: fix target-specific 'do-' typos

2024-09-20 Thread Sam James via Gcc-cvs
https://gcc.gnu.org/g:0be3f4546f9b92eb149a12303bd1f13569da7f28

commit r15-3729-g0be3f4546f9b92eb149a12303bd1f13569da7f28
Author: Sam James 
Date:   Fri Aug 2 06:32:55 2024 +0100

testsuite: fix target-specific 'do-' typos

Fix some target-specific 'do-' (rather than 'dg-') typos.

gcc/testsuite/ChangeLog:

* gcc.target/m68k/pr108640.c: Fix dg directive typo.
* gcc.target/m68k/pr110934.c: Ditto.
* gcc.target/m68k/pr82420.c: Ditto.
* gcc.target/powerpc/pr99708.c: Ditto.

Diff:
---
 gcc/testsuite/gcc.target/m68k/pr108640.c   | 2 +-
 gcc/testsuite/gcc.target/m68k/pr110934.c   | 2 +-
 gcc/testsuite/gcc.target/m68k/pr82420.c| 2 +-
 gcc/testsuite/gcc.target/powerpc/pr99708.c | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.target/m68k/pr108640.c 
b/gcc/testsuite/gcc.target/m68k/pr108640.c
index 5f3e8b49d42e..80a32e751a39 100644
--- a/gcc/testsuite/gcc.target/m68k/pr108640.c
+++ b/gcc/testsuite/gcc.target/m68k/pr108640.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { do-options "-O1" } */
+/* { dg-options "-O1" } */
 
 int x;
 void andsi3(void) { x &= ~(1 << 16); }
diff --git a/gcc/testsuite/gcc.target/m68k/pr110934.c 
b/gcc/testsuite/gcc.target/m68k/pr110934.c
index 8c21d46f6600..3798cae18fb6 100644
--- a/gcc/testsuite/gcc.target/m68k/pr110934.c
+++ b/gcc/testsuite/gcc.target/m68k/pr110934.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { do-options "-fzero-call-used-regs=used -fpic -O2" } */
+/* { dg-options "-fzero-call-used-regs=used -fpic -O2" } */
 
 extern double clobber_fp0 (void);
 
diff --git a/gcc/testsuite/gcc.target/m68k/pr82420.c 
b/gcc/testsuite/gcc.target/m68k/pr82420.c
index 5c84f292103c..0261720f725f 100644
--- a/gcc/testsuite/gcc.target/m68k/pr82420.c
+++ b/gcc/testsuite/gcc.target/m68k/pr82420.c
@@ -1,4 +1,4 @@
-/* { do-do compile } */
+/* { dg-do compile } */
 /* { dg-options "-march=68000 -malign-int" } */
 
 int a;
diff --git a/gcc/testsuite/gcc.target/powerpc/pr99708.c 
b/gcc/testsuite/gcc.target/powerpc/pr99708.c
index c6aa0511b892..5d2f435a746b 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr99708.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr99708.c
@@ -1,6 +1,6 @@
 /* { dg-do run } */
 /* { dg-skip-if "" { powerpc*-*-darwin* powerpc-ibm-aix* } } */
-/* { require-effective-target ppc_float128_sw } */
+/* { dg-require-effective-target ppc_float128_sw } */
 /* { dg-options "-O2 -mvsx -mfloat128" } */
 
 /*


[gcc r15-3730] OpenMP: Add get_device_from_uid/omp_get_uid_from_device routines

2024-09-20 Thread Tobias Burnus via Gcc-cvs
https://gcc.gnu.org/g:bf4a5efa80ef8438deb0a99c9a02b1f550aaf814

commit r15-3730-gbf4a5efa80ef8438deb0a99c9a02b1f550aaf814
Author: Tobias Burnus 
Date:   Fri Sep 20 09:25:33 2024 +0200

OpenMP: Add get_device_from_uid/omp_get_uid_from_device routines

Those TR13/OpenMP 6.0 routines permit a reproducible offloading to
a specific device by mapping an OpenMP device number to a
unique ID (UID). The GPU device UIDs should be universally unique,
the one for the host is not.

gcc/ChangeLog:

* omp-general.cc (omp_runtime_api_procname): Add
get_device_from_uid and omp_get_uid_from_device routines.

include/ChangeLog:

* cuda/cuda.h (cuDeviceGetUuid): Declare.
(cuDeviceGetUuid_v2): Add prototype.

libgomp/ChangeLog:

* config/gcn/target.c (omp_get_uid_from_device,
omp_get_device_from_uid): Add stub implementation.
* config/nvptx/target.c (omp_get_uid_from_device,
omp_get_device_from_uid): Likewise.
* fortran.c (omp_get_uid_from_device_,
omp_get_uid_from_device_8_): New functions.
* libgomp-plugin.h (GOMP_OFFLOAD_get_uid): Add prototype.
* libgomp.h (struct gomp_device_descr): Add 'uid' and 
'get_uid_func'.
* libgomp.map (GOMP_6.0): New, includind the new UID routines.
* libgomp.texi (OpenMP Technical Report 13): Mark UID routines as 
'Y'.
(Device Information Routines): Document new UID routines.
(Offload-Target Specifics): Document UID format.
* omp.h.in (omp_get_device_from_uid, omp_get_uid_from_device):
New prototype.
* omp_lib.f90.in (omp_get_device_from_uid, omp_get_uid_from_device):
New interface.
* omp_lib.h.in: Likewise.
* plugin/cuda-lib.def: Add cuDeviceGetUuid and cuDeviceGetUuid_v2 
via
CUDA_ONE_CALL_MAYBE_NULL.
* plugin/plugin-gcn.c (GOMP_OFFLOAD_get_uid): New.
* plugin/plugin-nvptx.c (GOMP_OFFLOAD_get_uid): New.
* target.c (str_omp_initial_device): New static var.
(STR_OMP_DEV_PREFIX): Define.
(gomp_get_uid_for_device, omp_get_uid_from_device,
omp_get_device_from_uid): New.
(gomp_load_plugin_for_device): DLSYM_OPT the function 'get_uid'.
(gomp_target_init): Set the device's 'uid' field to NULL.
* testsuite/libgomp.c/device_uid.c: New test.
* testsuite/libgomp.fortran/device_uid.f90: New test.

Diff:
---
 gcc/omp-general.cc   |  4 +-
 include/cuda/cuda.h  |  7 ++
 libgomp/config/gcn/target.c  | 14 
 libgomp/config/nvptx/target.c| 14 
 libgomp/fortran.c| 15 
 libgomp/libgomp-plugin.h |  1 +
 libgomp/libgomp.h|  2 +
 libgomp/libgomp.map  |  8 +++
 libgomp/libgomp.texi | 89 ++--
 libgomp/omp.h.in |  3 +
 libgomp/omp_lib.f90.in   | 23 ++
 libgomp/omp_lib.h.in | 23 ++
 libgomp/plugin/cuda-lib.def  |  2 +
 libgomp/plugin/plugin-gcn.c  | 16 +
 libgomp/plugin/plugin-nvptx.c| 34 +
 libgomp/target.c | 56 +++
 libgomp/testsuite/libgomp.c/device_uid.c | 38 ++
 libgomp/testsuite/libgomp.fortran/device_uid.f90 | 42 +++
 18 files changed, 384 insertions(+), 7 deletions(-)

diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc
index de91ba8a4a74..12788ad02490 100644
--- a/gcc/omp-general.cc
+++ b/gcc/omp-general.cc
@@ -3260,6 +3260,7 @@ omp_runtime_api_procname (const char *name)
   "alloc",
   "calloc",
   "free",
+  "get_device_from_uid",
   "get_interop_int",
   "get_interop_ptr",
   "get_mapped_ptr",
@@ -3338,12 +3339,13 @@ omp_runtime_api_procname (const char *name)
 as DECL_NAME only omp_* and omp_*_8 appear.  */
   "display_env",
   "get_ancestor_thread_num",
-  "init_allocator",
+  "omp_get_uid_from_device",
   "get_partition_place_nums",
   "get_place_num_procs",
   "get_place_proc_ids",
   "get_schedule",
   "get_team_size",
+  "init_allocator",
   "set_default_device",
   "set_dynamic",
   "set_max_active_levels",
diff --git a/include/cuda/cuda.h b/include/cuda/cuda.h
index 804d08ca57ea..3ade20f6bbf0 100644
--- a/include/cuda/cuda.h
+++ b/include/cuda/cuda.h
@@ -201,6 +201,10 @@ typedef struct {
   size_t WidthInBytes, Height, Depth;
 } CUDA_MEMCPY3D_PEER;
 
+typedef struct {
+  char bytes[16];
+} CUuuid;
+
 #define cuCtxCreate cuCtxCreate_v2
 CUresult cuCtxCreate (CUcontext *, unsi

[gcc(refs/users/aoliva/heads/testme)] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
https://gcc.gnu.org/g:cd77751018e24e7288b109978d41e0002410c49d

commit cd77751018e24e7288b109978d41e0002410c49d
Author: Alexandre Oliva 
Date:   Thu Sep 19 06:43:22 2024 -0300

adjust probs after modified ifcombine

Diff:
---
 gcc/tree-ssa-ifcombine.cc | 403 +-
 1 file changed, 323 insertions(+), 80 deletions(-)

diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index 79ccc70b2678..425fbae46eac 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa.h"
 #include "attribs.h"
 #include "asan.h"
+#include "bitmap.h"
 
 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
 #define LOGICAL_OP_NON_SHORT_CIRCUIT \
@@ -49,6 +50,28 @@ along with GCC; see the file COPYING3.  If not see
 false) >= 2)
 #endif
 
+/* Return TRUE iff COND is NULL, or the condition in it is constant.  */
+
+static bool
+constant_condition_p (gcond *cond)
+{
+  if (!cond)
+return true;
+
+  return (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
+ && CONSTANT_CLASS_P (gimple_cond_rhs (cond)));
+}
+
+/* Return FALSE iff the condition in the COND stmt that ends COND_BB is not
+   constant.  */
+
+static bool
+constant_condition_p (basic_block cond_bb)
+{
+  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
+  return constant_condition_p (cond);
+}
+
 /* This pass combines COND_EXPRs to simplify control flow.  It
currently recognizes bit tests and comparisons in chains that
represent logical and or logical or of two COND_EXPRs.
@@ -107,12 +130,7 @@ recognize_if_then_else (basic_block cond_bb,
   if (!*else_bb)
 *else_bb = e->dest;
 
-  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
-  if (!cond)
-return false;
-
-  if (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
-  && CONSTANT_CLASS_P (gimple_cond_rhs (cond)))
+  if (constant_condition_p (cond_bb))
 return false;
 
   return true;
@@ -364,14 +382,27 @@ recognize_bits_test (gcond *cond, tree *name, tree *bits, 
bool inv)
 }
 
 
-/* Update profile after code in outer_cond_bb was adjusted so
-   outer_cond_bb has no condition.  */
+/* Update profile after code in either outer_cond_bb or inner_cond_bb was
+   adjusted so that it has no condition.  */
 
 static void
 update_profile_after_ifcombine (basic_block inner_cond_bb,
basic_block outer_cond_bb)
 {
-  edge outer_to_inner = find_edge (outer_cond_bb, inner_cond_bb);
+  /* In the following we assume that inner_cond_bb has single predecessor.  */
+  gcc_assert (single_pred_p (inner_cond_bb));
+
+  basic_block outer_to_inner_bb = inner_cond_bb;
+  profile_probability prob = profile_probability::always ();
+  for (basic_block parent = single_pred (outer_to_inner_bb);
+   parent != outer_cond_bb;
+   parent = single_pred (outer_to_inner_bb))
+{
+  prob *= find_edge (parent, outer_to_inner_bb)->probability;
+  outer_to_inner_bb = parent;
+}
+
+  edge outer_to_inner = find_edge (outer_cond_bb, outer_to_inner_bb);
   edge outer2 = (EDGE_SUCC (outer_cond_bb, 0) == outer_to_inner
 ? EDGE_SUCC (outer_cond_bb, 1)
 : EDGE_SUCC (outer_cond_bb, 0));
@@ -382,29 +413,62 @@ update_profile_after_ifcombine (basic_block inner_cond_bb,
 std::swap (inner_taken, inner_not_taken);
   gcc_assert (inner_taken->dest == outer2->dest);
 
-  /* In the following we assume that inner_cond_bb has single predecessor.  */
-  gcc_assert (single_pred_p (inner_cond_bb));
+  if (constant_condition_p (outer_cond_bb))
+{
+  gcc_checking_assert (outer_to_inner_bb == inner_cond_bb);
 
-  /* Path outer_cond_bb->(outer2) needs to be merged into path
- outer_cond_bb->(outer_to_inner)->inner_cond_bb->(inner_taken)
- and probability of inner_not_taken updated.  */
+  /* Path outer_cond_bb->(outer2) needs to be merged into path
+outer_cond_bb->(outer_to_inner)->inner_cond_bb->(inner_taken)
+and probability of inner_not_taken updated.  */
 
-  inner_cond_bb->count = outer_cond_bb->count;
+  inner_cond_bb->count = outer_cond_bb->count;
 
-  /* Handle special case where inner_taken probability is always. In this case
- we know that the overall outcome will be always as well, but combining
- probabilities will be conservative because it does not know that
- outer2->probability is inverse of outer_to_inner->probability.  */
-  if (inner_taken->probability == profile_probability::always ())
-;
-  else
-inner_taken->probability = outer2->probability + 
outer_to_inner->probability
-  * inner_taken->probability;
-  inner_not_taken->probability = profile_probability::always ()
-- inner_taken->probability;
+  /* Handle special case where inner_taken probability is always. In this
+case we know that the overall outcome will be always as well, but
+combining probabilities

[gcc/aoliva/heads/testme] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
The branch 'aoliva/heads/testme' was updated to point to:

 cd77751018e2... adjust probs after modified ifcombine

It previously pointed to:

 9919ba13180b... adjust probs after modified ifcombine

Diff:

!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
---

  9919ba1... adjust probs after modified ifcombine


Summary of changes (added commits):
---

  cd77751... adjust probs after modified ifcombine


[gcc/aoliva/heads/testme] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
The branch 'aoliva/heads/testme' was updated to point to:

 f8372d9ec46d... adjust probs after modified ifcombine

It previously pointed to:

 cd77751018e2... adjust probs after modified ifcombine

Diff:

!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
---

  cd77751... adjust probs after modified ifcombine


Summary of changes (added commits):
---

  f8372d9... adjust probs after modified ifcombine


[gcc(refs/users/aoliva/heads/testme)] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
https://gcc.gnu.org/g:f8372d9ec46d74dc9e5f273c0a7bb2a9ad65578d

commit f8372d9ec46d74dc9e5f273c0a7bb2a9ad65578d
Author: Alexandre Oliva 
Date:   Thu Sep 19 06:43:22 2024 -0300

adjust probs after modified ifcombine

Diff:
---
 gcc/tree-ssa-ifcombine.cc | 409 --
 1 file changed, 326 insertions(+), 83 deletions(-)

diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index 79ccc70b2678..f058120a93c0 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa.h"
 #include "attribs.h"
 #include "asan.h"
+#include "bitmap.h"
 
 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
 #define LOGICAL_OP_NON_SHORT_CIRCUIT \
@@ -49,6 +50,28 @@ along with GCC; see the file COPYING3.  If not see
 false) >= 2)
 #endif
 
+/* Return TRUE iff COND is NULL, or the condition in it is constant.  */
+
+static bool
+constant_condition_p (gcond *cond)
+{
+  if (!cond)
+return true;
+
+  return (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
+ && CONSTANT_CLASS_P (gimple_cond_rhs (cond)));
+}
+
+/* Return FALSE iff the condition in the COND stmt that ends COND_BB is not
+   constant.  */
+
+static bool
+constant_condition_p (basic_block cond_bb)
+{
+  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
+  return constant_condition_p (cond);
+}
+
 /* This pass combines COND_EXPRs to simplify control flow.  It
currently recognizes bit tests and comparisons in chains that
represent logical and or logical or of two COND_EXPRs.
@@ -107,12 +130,7 @@ recognize_if_then_else (basic_block cond_bb,
   if (!*else_bb)
 *else_bb = e->dest;
 
-  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
-  if (!cond)
-return false;
-
-  if (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
-  && CONSTANT_CLASS_P (gimple_cond_rhs (cond)))
+  if (constant_condition_p (cond_bb))
 return false;
 
   return true;
@@ -364,14 +382,27 @@ recognize_bits_test (gcond *cond, tree *name, tree *bits, 
bool inv)
 }
 
 
-/* Update profile after code in outer_cond_bb was adjusted so
-   outer_cond_bb has no condition.  */
+/* Update profile after code in either outer_cond_bb or inner_cond_bb was
+   adjusted so that it has no condition.  */
 
 static void
 update_profile_after_ifcombine (basic_block inner_cond_bb,
basic_block outer_cond_bb)
 {
-  edge outer_to_inner = find_edge (outer_cond_bb, inner_cond_bb);
+  /* In the following we assume that inner_cond_bb has single predecessor.  */
+  gcc_assert (single_pred_p (inner_cond_bb));
+
+  basic_block outer_to_inner_bb = inner_cond_bb;
+  profile_probability prob = profile_probability::always ();
+  for (basic_block parent = single_pred (outer_to_inner_bb);
+   parent != outer_cond_bb;
+   parent = single_pred (outer_to_inner_bb))
+{
+  prob *= find_edge (parent, outer_to_inner_bb)->probability;
+  outer_to_inner_bb = parent;
+}
+
+  edge outer_to_inner = find_edge (outer_cond_bb, outer_to_inner_bb);
   edge outer2 = (EDGE_SUCC (outer_cond_bb, 0) == outer_to_inner
 ? EDGE_SUCC (outer_cond_bb, 1)
 : EDGE_SUCC (outer_cond_bb, 0));
@@ -382,29 +413,62 @@ update_profile_after_ifcombine (basic_block inner_cond_bb,
 std::swap (inner_taken, inner_not_taken);
   gcc_assert (inner_taken->dest == outer2->dest);
 
-  /* In the following we assume that inner_cond_bb has single predecessor.  */
-  gcc_assert (single_pred_p (inner_cond_bb));
+  if (constant_condition_p (outer_cond_bb))
+{
+  gcc_checking_assert (outer_to_inner_bb == inner_cond_bb);
 
-  /* Path outer_cond_bb->(outer2) needs to be merged into path
- outer_cond_bb->(outer_to_inner)->inner_cond_bb->(inner_taken)
- and probability of inner_not_taken updated.  */
+  /* Path outer_cond_bb->(outer2) needs to be merged into path
+outer_cond_bb->(outer_to_inner)->inner_cond_bb->(inner_taken)
+and probability of inner_not_taken updated.  */
 
-  inner_cond_bb->count = outer_cond_bb->count;
+  inner_cond_bb->count = outer_cond_bb->count;
 
-  /* Handle special case where inner_taken probability is always. In this case
- we know that the overall outcome will be always as well, but combining
- probabilities will be conservative because it does not know that
- outer2->probability is inverse of outer_to_inner->probability.  */
-  if (inner_taken->probability == profile_probability::always ())
-;
-  else
-inner_taken->probability = outer2->probability + 
outer_to_inner->probability
-  * inner_taken->probability;
-  inner_not_taken->probability = profile_probability::always ()
-- inner_taken->probability;
+  /* Handle special case where inner_taken probability is always. In this
+case we know that the overall outcome will be always as well, but
+combining probabilities

[gcc(refs/users/aoliva/heads/testme)] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
https://gcc.gnu.org/g:1d6ef2e03dff76f12ead4aceaf662d2e350d2678

commit 1d6ef2e03dff76f12ead4aceaf662d2e350d2678
Author: Alexandre Oliva 
Date:   Thu Sep 19 06:43:22 2024 -0300

adjust probs after modified ifcombine

Diff:
---
 gcc/fold-const.h |  10 +
 gcc/testsuite/gcc.dg/field-merge-7.c |  19 ++
 gcc/tree-ssa-ifcombine.cc| 482 ---
 3 files changed, 419 insertions(+), 92 deletions(-)

diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index 3e3998b57b04..136764f5c7eb 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -258,6 +258,16 @@ extern void clear_type_padding_in_mask (tree, unsigned 
char *);
 extern bool clear_padding_type_may_have_padding_p (tree);
 extern bool arith_overflowed_p (enum tree_code, const_tree, const_tree,
const_tree);
+extern tree fold_truth_andor_maybe_separate (location_t loc,
+enum tree_code code,
+tree truth_type,
+enum tree_code lcode,
+tree ll_arg,
+tree lr_arg,
+enum tree_code rcode,
+tree rl_arg,
+tree rr_arg,
+tree *separatep);
 
 /* Class used to compare gimple operands.  */
 
diff --git a/gcc/testsuite/gcc.dg/field-merge-7.c 
b/gcc/testsuite/gcc.dg/field-merge-7.c
new file mode 100644
index ..16a06286d823
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/field-merge-7.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ifcombine-details" } */
+
+/* Check that the third compare won't be combined with the first one.  */
+
+struct s {
+  char a, b;
+  int p;
+};
+
+struct s a = { 0, 0, 0 };
+struct s b = { 0, 0, 0 };
+
+int f () {
+  return (a.a != b.a && (a.p != b.p || a.b != b.b));
+}
+
+/* { dg-do { scan-tree-dump-not "optimizing" "ifcombine" } } */
+/* { dg-do { scan-tree-dump-not "BIT_FIELD_REF" "ifcombine" } } */
diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index 79ccc70b2678..9bb250bf2993 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa.h"
 #include "attribs.h"
 #include "asan.h"
+#include "bitmap.h"
 
 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
 #define LOGICAL_OP_NON_SHORT_CIRCUIT \
@@ -49,6 +50,28 @@ along with GCC; see the file COPYING3.  If not see
 false) >= 2)
 #endif
 
+/* Return TRUE iff COND is NULL, or the condition in it is constant.  */
+
+static bool
+constant_condition_p (gcond *cond)
+{
+  if (!cond)
+return true;
+
+  return (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
+ && CONSTANT_CLASS_P (gimple_cond_rhs (cond)));
+}
+
+/* Return FALSE iff the condition in the COND stmt that ends COND_BB is not
+   constant.  */
+
+static bool
+constant_condition_p (basic_block cond_bb)
+{
+  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
+  return constant_condition_p (cond);
+}
+
 /* This pass combines COND_EXPRs to simplify control flow.  It
currently recognizes bit tests and comparisons in chains that
represent logical and or logical or of two COND_EXPRs.
@@ -107,15 +130,38 @@ recognize_if_then_else (basic_block cond_bb,
   if (!*else_bb)
 *else_bb = e->dest;
 
-  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
-  if (!cond)
-return false;
+  return true;
+}
+
+/* Same as recognize_if_then_else, but check that the condition is not
+   constant.  It is not useful to combine constant conditions.  */
 
-  if (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
-  && CONSTANT_CLASS_P (gimple_cond_rhs (cond)))
+static bool
+recognize_if_then_else_nc (basic_block cond_bb,
+  basic_block *then_bb, basic_block *else_bb)
+{
+  return recognize_if_then_else (cond_bb, then_bb, else_bb)
+&& !constant_condition_p (cond_bb);
+}
+
+/* Same as recognize_if_then_else, but don't associate the blocks with then and
+   else, check both possibilities.  */
+
+static bool
+recognize_if_succs (basic_block cond_bb,
+   basic_block succ1, basic_block succ2)
+{
+  basic_block t, e;
+
+  if (EDGE_COUNT (cond_bb->succs) != 2)
 return false;
 
-  return true;
+  /* Find both succs.  */
+  t = EDGE_SUCC (cond_bb, 0)->dest;
+  e = EDGE_SUCC (cond_bb, 1)->dest;
+
+  return ((t == succ1 && e == succ2)
+ || (t == succ2 && e == succ1));
 }
 
 /* Verify if the basic block BB does not have side-effects.  Return
@@ -364,14 +410,27 @@ recognize_bits_test (gcond *cond, tree *name, tree *bits, 
bool inv)
 }
 
 
-/* Update profile after code in outer_cond_bb was adjusted so
-   outer_cond_bb has no condition.  */
+/* Update profile after code in either oute

[gcc/aoliva/heads/testme] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
The branch 'aoliva/heads/testme' was updated to point to:

 1d6ef2e03dff... adjust probs after modified ifcombine

It previously pointed to:

 3bd0565cf130... adjust probs after modified ifcombine

Diff:

!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
---

  3bd0565... adjust probs after modified ifcombine


Summary of changes (added commits):
---

  1d6ef2e... adjust probs after modified ifcombine


[gcc r15-3734] Handle patterns as SLP roots of only live stmts

2024-09-20 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:4eba48a684b1a1f77aa18b29a1ae58dbdc842b5b

commit r15-3734-g4eba48a684b1a1f77aa18b29a1ae58dbdc842b5b
Author: Richard Biener 
Date:   Fri Sep 20 13:35:49 2024 +0200

Handle patterns as SLP roots of only live stmts

gcc.dg/vect/vect-live-2.c shows it's important to handle live but
otherwise unused pattern stmts.

* tree-vect-slp.cc (vect_analyze_slp): Lookup patterns when
discovering from only-live roots.

Diff:
---
 gcc/tree-vect-slp.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index c8af4d320eb9..9c817de18bd1 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -4723,6 +4723,7 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size,
if (TREE_CODE (def) == SSA_NAME
&& !virtual_operand_p (def)
&& (stmt_info = loop_vinfo->lookup_def (def))
+   && ((stmt_info = vect_stmt_to_vectorize (stmt_info)), true)
&& STMT_VINFO_RELEVANT (stmt_info) == vect_used_only_live
&& STMT_VINFO_LIVE_P (stmt_info)
&& (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def


[gcc r15-3735] Fall back to elementwise access for too spaced SLP single element interleaving

2024-09-20 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:664e0ce580a8f20a78aa355c4e4647841f77

commit r15-3735-g664e0ce580a8f20a78aa355c4e4647841f77
Author: Richard Biener 
Date:   Fri Sep 20 12:17:22 2024 +0200

Fall back to elementwise access for too spaced SLP single element 
interleaving

gcc.dg/vect/vect-pr111779.c is a case where non-SLP manages to vectorize
using VMAT_ELEMENTWISE but SLP currently refuses because doing a regular
access with permutes would cause excess vector loads with at most one
element used.  The following makes us fall back to elementwise accesses
for that, too.

* tree-vect-stmts.cc (get_group_load_store_type): Fall back
to VMAT_ELEMENTWISE when single element interleaving of
a too large group.
(vectorizable_load): Do not try to verify load permutations
when using VMAT_ELEMENTWISE for single-lane SLP and fix code
generation for this case.

* gfortran.dg/vect/vect-8.f90: Allow one more vectorized loop.

Diff:
---
 gcc/testsuite/gfortran.dg/vect/vect-8.f90 |  2 +-
 gcc/tree-vect-stmts.cc| 37 ++-
 2 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/gcc/testsuite/gfortran.dg/vect/vect-8.f90 
b/gcc/testsuite/gfortran.dg/vect/vect-8.f90
index 2a3fa90740e3..918eddee292f 100644
--- a/gcc/testsuite/gfortran.dg/vect/vect-8.f90
+++ b/gcc/testsuite/gfortran.dg/vect/vect-8.f90
@@ -708,5 +708,5 @@ END SUBROUTINE kernel
 
 ! { dg-final { scan-tree-dump-times "vectorized 2\[56\] loops" 1 "vect" { 
target aarch64_sve } } }
 ! { dg-final { scan-tree-dump-times "vectorized 2\[45\] loops" 1 "vect" { 
target { aarch64*-*-* && { ! aarch64_sve } } } } }
-! { dg-final { scan-tree-dump-times "vectorized 2\[345\] loops" 1 "vect" { 
target { vect_intdouble_cvt && { ! aarch64*-*-* } } } } }
+! { dg-final { scan-tree-dump-times "vectorized 2\[3456\] loops" 1 "vect" { 
target { vect_intdouble_cvt && { ! aarch64*-*-* } } } } }
 ! { dg-final { scan-tree-dump-times "vectorized 17 loops" 1 "vect" { target { 
{ ! vect_intdouble_cvt } && { ! aarch64*-*-* } } } } }
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 33cdccae7849..45003f762ddf 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -2190,11 +2190,12 @@ get_group_load_store_type (vec_info *vinfo, 
stmt_vec_info stmt_info,
  && single_element_p
  && maybe_gt (group_size, TYPE_VECTOR_SUBPARTS (vectype)))
{
+ *memory_access_type = VMAT_ELEMENTWISE;
  if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 "single-element interleaving not supported "
-"for not adjacent vector loads\n");
- return false;
+"for not adjacent vector loads, using "
+"elementwise access\n");
}
}
 }
@@ -10039,7 +10040,23 @@ vectorizable_load (vec_info *vinfo,
   else
 group_size = 1;
 
-  if (slp && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ())
+  vect_memory_access_type memory_access_type;
+  enum dr_alignment_support alignment_support_scheme;
+  int misalignment;
+  poly_int64 poffset;
+  internal_fn lanes_ifn;
+  if (!get_load_store_type (vinfo, stmt_info, vectype, slp_node, mask, 
VLS_LOAD,
+   ncopies, &memory_access_type, &poffset,
+   &alignment_support_scheme, &misalignment, &gs_info,
+   &lanes_ifn))
+return false;
+
+  /* ???  The following checks should really be part of
+ get_group_load_store_type.  */
+  if (slp
+  && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()
+  && !(memory_access_type == VMAT_ELEMENTWISE
+  && SLP_TREE_LANES (slp_node) == 1))
 {
   slp_perm = true;
 
@@ -10079,17 +10096,6 @@ vectorizable_load (vec_info *vinfo,
}
 }
 
-  vect_memory_access_type memory_access_type;
-  enum dr_alignment_support alignment_support_scheme;
-  int misalignment;
-  poly_int64 poffset;
-  internal_fn lanes_ifn;
-  if (!get_load_store_type (vinfo, stmt_info, vectype, slp_node, mask, 
VLS_LOAD,
-   ncopies, &memory_access_type, &poffset,
-   &alignment_support_scheme, &misalignment, &gs_info,
-   &lanes_ifn))
-return false;
-
   if (slp_node
   && slp_node->ldst_lanes
   && memory_access_type != VMAT_LOAD_STORE_LANES)
@@ -10292,7 +10298,8 @@ vectorizable_load (vec_info *vinfo,
  first_dr_info = dr_info;
}
 
-  if (slp && grouped_load)
+  if (slp && grouped_load
+ && memory_access_type == VMAT_STRIDED_SLP)
{
  group_size = DR_GROUP_SIZE (first_stmt_info);
  ref_type = get_group_alias_ptr_type (first_stmt_info);


[gcc r15-3728] i386: Fix up _mm_min_ss etc. handling of zeros and NaNs [PR116738]

2024-09-20 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:624d3af025e820ede7ec4334f7a2d5d4731c99a9

commit r15-3728-g624d3af025e820ede7ec4334f7a2d5d4731c99a9
Author: Jakub Jelinek 
Date:   Fri Sep 20 09:14:29 2024 +0200

i386: Fix up _mm_min_ss etc. handling of zeros and NaNs [PR116738]

min/max patterns for intrinsics which on x86 result in the second
input operand if the two operands are both zeros or one or both of them
are a NaN shouldn't use SMIN/SMAX RTL, because that is similarly to
MIN_EXPR/MAX_EXPR undefined what will be the result in those cases.

The following patch adds an expander which uses either a new pattern with
UNSPEC_IEEE_M{AX,IN} or use the S{MIN,MAX} representation of the same.

2024-09-20  Uros Bizjak  
Jakub Jelinek  

PR target/116738
* config/i386/subst.md (mask_scalar_operand_arg34,
mask_scalar_expand_op3, round_saeonly_scalar_mask_arg3): New
subst attributes.
* config/i386/sse.md

(_vm3):
Change from define_insn to define_expand, rename the old define_insn
to ...

(*_vm3):
... this.

(_ieee_vm3):
New define_insn.

* gcc.target/i386/sse-pr116738.c: New test.

Diff:
---
 gcc/config/i386/sse.md   | 41 +++-
 gcc/config/i386/subst.md |  3 ++
 gcc/testsuite/gcc.target/i386/sse-pr116738.c | 28 +++
 3 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index ff4f33b7b637..29b0ea3507d5 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -,7 +,27 @@
   (const_string "*")))
(set_attr "mode" "")])
 
-(define_insn 
"_vm3"
+(define_expand 
"_vm3"
+  [(set (match_operand:VFH_128 0 "register_operand")
+   (vec_merge:VFH_128
+ (smaxmin:VFH_128
+   (match_operand:VFH_128 1 "register_operand")
+   (match_operand:VFH_128 2 "nonimmediate_operand"))
+(match_dup 1)
+(const_int 1)))]
+  "TARGET_SSE"
+{
+  if (!flag_finite_math_only || flag_signed_zeros)
+{
+  emit_insn 
(gen__ieee_vm3
+(operands[0], operands[1], operands[2]
+ 
+ ));
+  DONE;
+}
+})
+
+(define_insn 
"*_vm3"
   [(set (match_operand:VFH_128 0 "register_operand" "=x,v")
(vec_merge:VFH_128
  (smaxmin:VFH_128
@@ -3351,6 +3371,25 @@
(set_attr "prefix" "")
(set_attr "mode" "")])
 
+(define_insn 
"_ieee_vm3"
+  [(set (match_operand:VFH_128 0 "register_operand" "=x,v")
+   (vec_merge:VFH_128
+ (unspec:VFH_128
+   [(match_operand:VFH_128 1 "register_operand" "0,v")
+(match_operand:VFH_128 2 "nonimmediate_operand" 
"xm,")]
+   IEEE_MAXMIN)
+(match_dup 1)
+(const_int 1)))]
+  "TARGET_SSE"
+  "@
+   \t{%2, %0|%0, %2}
+   v\t{%2, 
%1, %0|%0, %1, 
%2}"
+  [(set_attr "isa" "noavx,avx")
+   (set_attr "type" "sse")
+   (set_attr "btver2_sse_attr" "maxmin")
+   (set_attr "prefix" "")
+   (set_attr "mode" "")])
+
 (define_mode_attr addsub_cst [(V4DF "5") (V2DF "1")
   (V4SF "5") (V8SF "85")])
 
diff --git a/gcc/config/i386/subst.md b/gcc/config/i386/subst.md
index ca5341320ea8..3722b0d2d53d 100644
--- a/gcc/config/i386/subst.md
+++ b/gcc/config/i386/subst.md
@@ -366,6 +366,8 @@
 (define_subst_attr "mask_scalarcz_operand4" "mask_scalarcz" "" "%{%5%}%N4")
 (define_subst_attr "mask_scalar4_dest_false_dep_for_glc_cond" "mask_scalar" 
"1" "operands[4] == CONST0_RTX(mode)")
 (define_subst_attr "mask_scalarc_dest_false_dep_for_glc_cond" "mask_scalarc" 
"1" "operands[3] == CONST0_RTX(V8HFmode)")
+(define_subst_attr "mask_scalar_operand_arg34" "mask_scalar" "" ", 
operands[3], operands[4]")
+(define_subst_attr "mask_scalar_expand_op3" "mask_scalar" "3" "5")
 
 (define_subst "mask_scalar"
   [(set (match_operand:SUBST_V 0)
@@ -473,6 +475,7 @@
 (define_subst_attr "round_saeonly_scalar_constraint" "round_saeonly_scalar" 
"vm" "v")
 (define_subst_attr "round_saeonly_scalar_prefix" "round_saeonly_scalar" "vex" 
"evex")
 (define_subst_attr "round_saeonly_scalar_nimm_predicate" 
"round_saeonly_scalar" "nonimmediate_operand" "register_operand")
+(define_subst_attr "round_saeonly_scalar_mask_arg3" "round_saeonly_scalar" "" 
", operands[]")
 
 (define_subst "round_saeonly_scalar"
   [(set (match_operand:SUBST_V 0)
diff --git a/gcc/testsuite/gcc.target/i386/sse-pr116738.c 
b/gcc/testsuite/gcc.target/i386/sse-pr116738.c
new file mode 100644
index ..5b31bf247488
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse-pr116738.c
@@ -0,0 +1,28 @@
+/* PR target/116738 */
+/* { dg-do run } */
+/* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
+
+#include "sse-check.h"
+
+static inline float
+clamp (float f)
+{
+  __m128 v = _mm_set_ss (f);
+  __m128 zero = _mm_setzero_ps ();
+  __

[gcc r14-10692] s390: Fix strict_low_part generation

2024-09-20 Thread Stefan Schulze Frielinghaus via Gcc-cvs
https://gcc.gnu.org/g:bff6e5667d6a8bf8060e550bdcb40e094d00af41

commit r14-10692-gbff6e5667d6a8bf8060e550bdcb40e094d00af41
Author: Stefan Schulze Frielinghaus 
Date:   Fri Sep 20 14:06:42 2024 +0200

s390: Fix strict_low_part generation

In s390_expand_insv(), if generating code for ICM et al. src is a MEM
and gen_lowpart might force src into a register such that we end up with
patterns which do not match anymore.  Use adjust_address() instead in
order to preserve a MEM.

Furthermore, it is not straight forward to enforce a subreg.  For
example, in case of a paradoxical subreg, gen_lowpart() may return a
register.  In order to compensate this, s390_gen_lowpart_subreg() emits
a reference to a pseudo which does not coincide with its definition
which is wrong.  Additionally, if dest is a paradoxical subreg, then do
not try to emit a strict_low_part since it could mean that dest was not
initialized even though this might be fixed up later by init-regs.

Splitter for insn *get_tp_64, *zero_extendhisi2_31,
*zero_extendqisi2_31, *zero_extendqihi2_31 are applied after reload.
Thus, operands[0] is a hard register and gen_lowpart (m, operands[0])
just returns the hard register for mode m which is fine to use as an
argument for strict_low_part, i.e., we do not need to enforce subregs
here since after reload subregs are supposed to be eliminated anyway.

This fixes gcc.dg/torture/pr111821.c.

gcc/ChangeLog:

* config/s390/s390-protos.h (s390_gen_lowpart_subreg): Remove.
* config/s390/s390.cc (s390_gen_lowpart_subreg): Remove.
(s390_expand_insv): Use adjust_address() and emit a
strict_low_part only in case of a natural subreg.
* config/s390/s390.md: Use gen_lowpart() instead of
s390_gen_lowpart_subreg().

(cherry picked from commit 9ebc9fbdddfe1ec85355b068354315a4da8e1ca0)

Diff:
---
 gcc/config/s390/s390-protos.h |  1 -
 gcc/config/s390/s390.cc   | 47 +--
 gcc/config/s390/s390.md   | 13 ++--
 3 files changed, 20 insertions(+), 41 deletions(-)

diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 8c2985a79c4d..4bda36e01ec2 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -50,7 +50,6 @@ extern void s390_set_has_landing_pad_p (bool);
 extern bool s390_hard_regno_rename_ok (unsigned int, unsigned int);
 extern int s390_class_max_nregs (enum reg_class, machine_mode);
 extern bool s390_return_addr_from_memory(void);
-extern rtx s390_gen_lowpart_subreg (machine_mode, rtx);
 extern bool s390_fma_allowed_p (machine_mode);
 #if S390_USE_TARGET_ATTRIBUTE
 extern tree s390_valid_target_attribute_tree (tree args,
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index ec836ec3cd4a..4be95788094c 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -516,31 +516,6 @@ s390_return_addr_from_memory ()
   return cfun_gpr_save_slot(RETURN_REGNUM) == SAVE_SLOT_STACK;
 }
 
-/* Generate a SUBREG for the MODE lowpart of EXPR.
-
-   In contrast to gen_lowpart it will always return a SUBREG
-   expression.  This is useful to generate STRICT_LOW_PART
-   expressions.  */
-rtx
-s390_gen_lowpart_subreg (machine_mode mode, rtx expr)
-{
-  rtx lowpart = gen_lowpart (mode, expr);
-
-  /* There might be no SUBREG in case it could be applied to the hard
- REG rtx or it could be folded with a paradoxical subreg.  Bring
- it back.  */
-  if (!SUBREG_P (lowpart))
-{
-  machine_mode reg_mode = TARGET_ZARCH ? DImode : SImode;
-  gcc_assert (REG_P (lowpart));
-  lowpart = gen_lowpart_SUBREG (mode,
-   gen_rtx_REG (reg_mode,
-REGNO (lowpart)));
-}
-
-  return lowpart;
-}
-
 /* Return nonzero if it's OK to use fused multiply-add for MODE.  */
 bool
 s390_fma_allowed_p (machine_mode mode)
@@ -6982,15 +6957,21 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
   /* Emit a strict_low_part pattern if possible.  */
   if (smode_bsize == bitsize && bitpos == mode_bsize - smode_bsize)
{
- rtx low_dest = s390_gen_lowpart_subreg (smode, dest);
- rtx low_src = gen_lowpart (smode, src);
-
- switch (smode)
+ rtx low_dest = gen_lowpart (smode, dest);
+ if (SUBREG_P (low_dest) && !paradoxical_subreg_p (low_dest))
{
-   case E_QImode: emit_insn (gen_movstrictqi (low_dest, low_src)); 
return true;
-   case E_HImode: emit_insn (gen_movstricthi (low_dest, low_src)); 
return true;
-   case E_SImode: emit_insn (gen_movstrictsi (low_dest, low_src)); 
return true;
-   default: break;
+ poly_int64 offset = GET_MODE_SIZE (mode) - GET_MODE_SIZE (smode);
+ rtx low_src = adjust_address (src, smode, offset);
+ switc

[gcc r13-9045] s390: Fix strict_low_part generation

2024-09-20 Thread Stefan Schulze Frielinghaus via Gcc-cvs
https://gcc.gnu.org/g:edda7ba3b569652eb782a7c47a4ad32e3c0e29dd

commit r13-9045-gedda7ba3b569652eb782a7c47a4ad32e3c0e29dd
Author: Stefan Schulze Frielinghaus 
Date:   Fri Sep 20 14:07:36 2024 +0200

s390: Fix strict_low_part generation

In s390_expand_insv(), if generating code for ICM et al. src is a MEM
and gen_lowpart might force src into a register such that we end up with
patterns which do not match anymore.  Use adjust_address() instead in
order to preserve a MEM.

Furthermore, it is not straight forward to enforce a subreg.  For
example, in case of a paradoxical subreg, gen_lowpart() may return a
register.  In order to compensate this, s390_gen_lowpart_subreg() emits
a reference to a pseudo which does not coincide with its definition
which is wrong.  Additionally, if dest is a paradoxical subreg, then do
not try to emit a strict_low_part since it could mean that dest was not
initialized even though this might be fixed up later by init-regs.

Splitter for insn *get_tp_64, *zero_extendhisi2_31,
*zero_extendqisi2_31, *zero_extendqihi2_31 are applied after reload.
Thus, operands[0] is a hard register and gen_lowpart (m, operands[0])
just returns the hard register for mode m which is fine to use as an
argument for strict_low_part, i.e., we do not need to enforce subregs
here since after reload subregs are supposed to be eliminated anyway.

This fixes gcc.dg/torture/pr111821.c.

gcc/ChangeLog:

* config/s390/s390-protos.h (s390_gen_lowpart_subreg): Remove.
* config/s390/s390.cc (s390_gen_lowpart_subreg): Remove.
(s390_expand_insv): Use adjust_address() and emit a
strict_low_part only in case of a natural subreg.
* config/s390/s390.md: Use gen_lowpart() instead of
s390_gen_lowpart_subreg().

(cherry picked from commit 9ebc9fbdddfe1ec85355b068354315a4da8e1ca0)

Diff:
---
 gcc/config/s390/s390-protos.h |  1 -
 gcc/config/s390/s390.cc   | 47 +--
 gcc/config/s390/s390.md   | 13 ++--
 3 files changed, 20 insertions(+), 41 deletions(-)

diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 67fe09e732da..6a0cc2ca45c9 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -50,7 +50,6 @@ extern void s390_set_has_landing_pad_p (bool);
 extern bool s390_hard_regno_rename_ok (unsigned int, unsigned int);
 extern int s390_class_max_nregs (enum reg_class, machine_mode);
 extern bool s390_return_addr_from_memory(void);
-extern rtx s390_gen_lowpart_subreg (machine_mode, rtx);
 extern bool s390_fma_allowed_p (machine_mode);
 #if S390_USE_TARGET_ATTRIBUTE
 extern tree s390_valid_target_attribute_tree (tree args,
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 505de995da87..2a451c5ac5d1 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -505,31 +505,6 @@ s390_return_addr_from_memory ()
   return cfun_gpr_save_slot(RETURN_REGNUM) == SAVE_SLOT_STACK;
 }
 
-/* Generate a SUBREG for the MODE lowpart of EXPR.
-
-   In contrast to gen_lowpart it will always return a SUBREG
-   expression.  This is useful to generate STRICT_LOW_PART
-   expressions.  */
-rtx
-s390_gen_lowpart_subreg (machine_mode mode, rtx expr)
-{
-  rtx lowpart = gen_lowpart (mode, expr);
-
-  /* There might be no SUBREG in case it could be applied to the hard
- REG rtx or it could be folded with a paradoxical subreg.  Bring
- it back.  */
-  if (!SUBREG_P (lowpart))
-{
-  machine_mode reg_mode = TARGET_ZARCH ? DImode : SImode;
-  gcc_assert (REG_P (lowpart));
-  lowpart = gen_lowpart_SUBREG (mode,
-   gen_rtx_REG (reg_mode,
-REGNO (lowpart)));
-}
-
-  return lowpart;
-}
-
 /* Return nonzero if it's OK to use fused multiply-add for MODE.  */
 bool
 s390_fma_allowed_p (machine_mode mode)
@@ -6639,15 +6614,21 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
   /* Emit a strict_low_part pattern if possible.  */
   if (smode_bsize == bitsize && bitpos == mode_bsize - smode_bsize)
{
- rtx low_dest = s390_gen_lowpart_subreg (smode, dest);
- rtx low_src = gen_lowpart (smode, src);
-
- switch (smode)
+ rtx low_dest = gen_lowpart (smode, dest);
+ if (SUBREG_P (low_dest) && !paradoxical_subreg_p (low_dest))
{
-   case E_QImode: emit_insn (gen_movstrictqi (low_dest, low_src)); 
return true;
-   case E_HImode: emit_insn (gen_movstricthi (low_dest, low_src)); 
return true;
-   case E_SImode: emit_insn (gen_movstrictsi (low_dest, low_src)); 
return true;
-   default: break;
+ poly_int64 offset = GET_MODE_SIZE (mode) - GET_MODE_SIZE (smode);
+ rtx low_src = adjust_address (src, smode, offset);
+ switch

[gcc r12-10717] s390: Fix strict_low_part generation

2024-09-20 Thread Stefan Schulze Frielinghaus via Gcc-cvs
https://gcc.gnu.org/g:4fe0b88159a9548f90db4e846f2033d51e1506c7

commit r12-10717-g4fe0b88159a9548f90db4e846f2033d51e1506c7
Author: Stefan Schulze Frielinghaus 
Date:   Fri Sep 20 14:08:32 2024 +0200

s390: Fix strict_low_part generation

In s390_expand_insv(), if generating code for ICM et al. src is a MEM
and gen_lowpart might force src into a register such that we end up with
patterns which do not match anymore.  Use adjust_address() instead in
order to preserve a MEM.

Furthermore, it is not straight forward to enforce a subreg.  For
example, in case of a paradoxical subreg, gen_lowpart() may return a
register.  In order to compensate this, s390_gen_lowpart_subreg() emits
a reference to a pseudo which does not coincide with its definition
which is wrong.  Additionally, if dest is a paradoxical subreg, then do
not try to emit a strict_low_part since it could mean that dest was not
initialized even though this might be fixed up later by init-regs.

Splitter for insn *get_tp_64, *zero_extendhisi2_31,
*zero_extendqisi2_31, *zero_extendqihi2_31 are applied after reload.
Thus, operands[0] is a hard register and gen_lowpart (m, operands[0])
just returns the hard register for mode m which is fine to use as an
argument for strict_low_part, i.e., we do not need to enforce subregs
here since after reload subregs are supposed to be eliminated anyway.

This fixes gcc.dg/torture/pr111821.c.

gcc/ChangeLog:

* config/s390/s390-protos.h (s390_gen_lowpart_subreg): Remove.
* config/s390/s390.cc (s390_gen_lowpart_subreg): Remove.
(s390_expand_insv): Use adjust_address() and emit a
strict_low_part only in case of a natural subreg.
* config/s390/s390.md: Use gen_lowpart() instead of
s390_gen_lowpart_subreg().

(cherry picked from commit 9ebc9fbdddfe1ec85355b068354315a4da8e1ca0)

Diff:
---
 gcc/config/s390/s390-protos.h |  1 -
 gcc/config/s390/s390.cc   | 47 +--
 gcc/config/s390/s390.md   | 13 ++--
 3 files changed, 20 insertions(+), 41 deletions(-)

diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 78117c36e030..7ce4c52abe9b 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -50,7 +50,6 @@ extern void s390_set_has_landing_pad_p (bool);
 extern bool s390_hard_regno_rename_ok (unsigned int, unsigned int);
 extern int s390_class_max_nregs (enum reg_class, machine_mode);
 extern bool s390_return_addr_from_memory(void);
-extern rtx s390_gen_lowpart_subreg (machine_mode, rtx);
 extern bool s390_fma_allowed_p (machine_mode);
 #if S390_USE_TARGET_ATTRIBUTE
 extern tree s390_valid_target_attribute_tree (tree args,
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index ae0cf9ef5b91..b66fc5be8719 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -457,31 +457,6 @@ s390_return_addr_from_memory ()
   return cfun_gpr_save_slot(RETURN_REGNUM) == SAVE_SLOT_STACK;
 }
 
-/* Generate a SUBREG for the MODE lowpart of EXPR.
-
-   In contrast to gen_lowpart it will always return a SUBREG
-   expression.  This is useful to generate STRICT_LOW_PART
-   expressions.  */
-rtx
-s390_gen_lowpart_subreg (machine_mode mode, rtx expr)
-{
-  rtx lowpart = gen_lowpart (mode, expr);
-
-  /* There might be no SUBREG in case it could be applied to the hard
- REG rtx or it could be folded with a paradoxical subreg.  Bring
- it back.  */
-  if (!SUBREG_P (lowpart))
-{
-  machine_mode reg_mode = TARGET_ZARCH ? DImode : SImode;
-  gcc_assert (REG_P (lowpart));
-  lowpart = gen_lowpart_SUBREG (mode,
-   gen_rtx_REG (reg_mode,
-REGNO (lowpart)));
-}
-
-  return lowpart;
-}
-
 /* Return nonzero if it's OK to use fused multiply-add for MODE.  */
 bool
 s390_fma_allowed_p (machine_mode mode)
@@ -6544,15 +6519,21 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
   /* Emit a strict_low_part pattern if possible.  */
   if (smode_bsize == bitsize && bitpos == mode_bsize - smode_bsize)
{
- rtx low_dest = s390_gen_lowpart_subreg (smode, dest);
- rtx low_src = gen_lowpart (smode, src);
-
- switch (smode)
+ rtx low_dest = gen_lowpart (smode, dest);
+ if (SUBREG_P (low_dest) && !paradoxical_subreg_p (low_dest))
{
-   case E_QImode: emit_insn (gen_movstrictqi (low_dest, low_src)); 
return true;
-   case E_HImode: emit_insn (gen_movstricthi (low_dest, low_src)); 
return true;
-   case E_SImode: emit_insn (gen_movstrictsi (low_dest, low_src)); 
return true;
-   default: break;
+ poly_int64 offset = GET_MODE_SIZE (mode) - GET_MODE_SIZE (smode);
+ rtx low_src = adjust_address (src, smode, offset);
+ switc

[gcc r14-10693] Fix small thinko in IPA mod/ref pass

2024-09-20 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:adab597af288d6e1e0b7c3414517147995b03cc9

commit r14-10693-gadab597af288d6e1e0b7c3414517147995b03cc9
Author: Eric Botcazou 
Date:   Fri Sep 20 12:32:13 2024 +0200

Fix small thinko in IPA mod/ref pass

When a memory copy operation is analyzed by analyze_ssa_name, if both the
load and store are made through the same SSA name, the store is overlooked.

gcc/
* ipa-modref.cc (modref_eaf_analysis::analyze_ssa_name): Always
process both the load and the store of a memory copy operation.

gcc/testsuite/
* gcc.dg/ipa/modref-4.c: New test.

Diff:
---
 gcc/ipa-modref.cc   |  3 ++-
 gcc/testsuite/gcc.dg/ipa/modref-4.c | 34 ++
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index 10344fbb4b58..ccf788e6398c 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -2604,8 +2604,9 @@ modref_eaf_analysis::analyze_ssa_name (tree name, bool 
deferred)
 is used arbitrarily.  */
  if (memory_access_to (gimple_assign_rhs1 (assign), name))
m_lattice[index].merge (deref_flags (0, false));
+
  /* Handle *name = *exp.  */
- else if (memory_access_to (gimple_assign_lhs (assign), name))
+ if (memory_access_to (gimple_assign_lhs (assign), name))
m_lattice[index].merge_direct_store ();
}
  /* Handle lhs = *name.  */
diff --git a/gcc/testsuite/gcc.dg/ipa/modref-4.c 
b/gcc/testsuite/gcc.dg/ipa/modref-4.c
new file mode 100644
index ..71ed1ca5f5b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/modref-4.c
@@ -0,0 +1,34 @@
+/* { dg-options "-O"  } */
+/* { dg-do run } */
+
+static __attribute__((noipa)) int foo (void)
+{
+  return 1;
+}
+
+int main (void)
+{
+  struct S { int a; int b; };
+  struct T { struct S s; };
+
+  struct T t = { { 0, 0 } };
+  struct T u;
+
+  __attribute__((noinline)) void bar (void)
+  {
+if (foo ())
+  {
+   u = t;
+/* OK with u.s.a = 0; */
+  }
+  }
+
+  u.s.a = 1;
+
+  bar ();
+
+  if (u.s.a != 0)
+__builtin_abort ();
+
+  return 0;
+}


[gcc r15-3732] testsuite/116397 - avoid looking for "VEC_PERM_EXPR"

2024-09-20 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:5d0e46a939f3840f810f071037e543a6249c06fe

commit r15-3732-g5d0e46a939f3840f810f071037e543a6249c06fe
Author: Richard Biener 
Date:   Fri Sep 20 13:47:34 2024 +0200

testsuite/116397 - avoid looking for "VEC_PERM_EXPR"

With SLP this token appears a lot, when looking for what gets code
generated instead look for " = VEC_PERM_EXPR"

PR testsuite/116397
* gcc.dg/vect/slp-reduc-3.c: Look for " = VEC_PERM_EXPR"
instead of "VEC_PERM_EXPR".

Diff:
---
 gcc/testsuite/gcc.dg/vect/slp-reduc-3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c 
b/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c
index 9e29757717fe..614d8ad17ca1 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c
@@ -62,4 +62,4 @@ int main (void)
 /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { 
vect_short_mult && { vect_widen_sum_hi_to_si  && vect_unpack } } } } } */ 
 /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { 
xfail { vect_widen_sum_hi_to_si_pattern || { ! { vect_short_mult && { 
vect_widen_sum_hi_to_si  && vect_unpack } } } } } } } */
 /* Check we can elide permutes if SLP vectorizing the reduction.  */
-/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" { xfail { { { 
vect_widen_sum_hi_to_si_pattern || { ! vect_unpack } } && { ! vect_load_lanes } 
} && { vect_short_mult && { vect_widen_sum_hi_to_si  && vect_unpack } } } } } } 
*/
+/* { dg-final { scan-tree-dump-times " = VEC_PERM_EXPR" 0 "vect" { xfail { { { 
vect_widen_sum_hi_to_si_pattern || { ! vect_unpack } } && { ! vect_load_lanes } 
} && { vect_short_mult && { vect_widen_sum_hi_to_si  && vect_unpack } } } } } } 
*/


[gcc r15-3733] s390: Remove -m{,no-}lra option

2024-09-20 Thread Stefan Schulze Frielinghaus via Gcc-cvs
https://gcc.gnu.org/g:09a52cf036ba8f2fa7b60b18ba58ca17ffa1b146

commit r15-3733-g09a52cf036ba8f2fa7b60b18ba58ca17ffa1b146
Author: Stefan Schulze Frielinghaus 
Date:   Fri Sep 20 13:53:08 2024 +0200

s390: Remove -m{,no-}lra option

Since the old reload pass is about to be removed and we defaulted to LRA
for over a decade, remove option -m{,no-}lra.

PR target/113953

gcc/ChangeLog:

* config/s390/s390.cc (s390_lra_p): Remove.
(TARGET_LRA_P): Remove.
* config/s390/s390.opt (mlra): Remove.
* config/s390/s390.opt.urls (mlra): Remove.

gcc/testsuite/ChangeLog:

* gcc.target/s390/TI-constants-nolra.c: Removed.
* gcc.target/s390/pr79895.c: Removed.

Diff:
---
 gcc/config/s390/s390.cc| 10 -
 gcc/config/s390/s390.opt   |  4 --
 gcc/config/s390/s390.opt.urls  |  2 -
 gcc/testsuite/gcc.target/s390/TI-constants-nolra.c | 47 --
 gcc/testsuite/gcc.target/s390/pr79895.c|  9 -
 5 files changed, 72 deletions(-)

diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index c9172d1153ac..25d43ae3e138 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -11342,13 +11342,6 @@ s390_can_change_mode_class (machine_mode from_mode,
   return true;
 }
 
-/* Return true if we use LRA instead of reload pass.  */
-static bool
-s390_lra_p (void)
-{
-  return s390_lra_flag;
-}
-
 /* Return true if register FROM can be eliminated via register TO.  */
 
 static bool
@@ -18444,9 +18437,6 @@ s390_c_mode_for_floating_type (enum tree_index ti)
 #undef TARGET_LEGITIMATE_CONSTANT_P
 #define TARGET_LEGITIMATE_CONSTANT_P s390_legitimate_constant_p
 
-#undef TARGET_LRA_P
-#define TARGET_LRA_P s390_lra_p
-
 #undef TARGET_CAN_ELIMINATE
 #define TARGET_CAN_ELIMINATE s390_can_eliminate
 
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
index a5b5aa95a122..23ea4b8232db 100644
--- a/gcc/config/s390/s390.opt
+++ b/gcc/config/s390/s390.opt
@@ -229,10 +229,6 @@ Set the branch costs for conditional branch instructions.  
Reasonable
 values are small, non-negative integers.  The default branch cost is
 1.
 
-mlra
-Target Var(s390_lra_flag) Init(1) Save
-Use LRA instead of reload.
-
 mpic-data-is-text-relative
 Target Var(s390_pic_data_is_text_relative) 
Init(TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE)
 Assume data segments are relative to text segment.
diff --git a/gcc/config/s390/s390.opt.urls b/gcc/config/s390/s390.opt.urls
index ab1e761efa88..bc772d2ffc75 100644
--- a/gcc/config/s390/s390.opt.urls
+++ b/gcc/config/s390/s390.opt.urls
@@ -74,8 +74,6 @@ UrlSuffix(gcc/S_002f390-and-zSeries-Options.html#index-mzarch)
 
 ; skipping UrlSuffix for 'mbranch-cost=' due to finding no URLs
 
-; skipping UrlSuffix for 'mlra' due to finding no URLs
-
 ; skipping UrlSuffix for 'mpic-data-is-text-relative' due to finding no URLs
 
 ; skipping UrlSuffix for 'mindirect-branch=' due to finding no URLs
diff --git a/gcc/testsuite/gcc.target/s390/TI-constants-nolra.c 
b/gcc/testsuite/gcc.target/s390/TI-constants-nolra.c
deleted file mode 100644
index b9948fc4aa58..
--- a/gcc/testsuite/gcc.target/s390/TI-constants-nolra.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* { dg-do compile { target int128 } } */
-/* { dg-options "-O3 -mno-lra" } */
-
-/* 2x lghi */
-__int128 a() {
-  return 0;
-}
-
-/* 2x lghi */
-__int128 b() {
-  return -1;
-}
-
-/* 2x lghi */
-__int128 c() {
-  return -2;
-}
-
-/* lghi + llilh */
-__int128 d() {
-  return 16000 << 16;
-}
-
-/* lghi + llihf */
-__int128 e() {
-  return (unsigned long long)8 << 32;
-}
-
-/* lghi + llihf */
-__int128 f() {
-  return (unsigned __int128)8 << 96;
-}
-
-/* llihf + llihf - this is handled via movti_bigconst pattern */
-__int128 g() {
-  return ((unsigned __int128)8 << 96) | ((unsigned __int128)8 << 32);
-}
-
-/* Literal pool */
-__int128 h() {
-  return ((unsigned __int128)8 << 32) | 1;
-}
-
-/* Literal pool */
-__int128 i() {
-  return (((unsigned __int128)8 << 32) | 1) << 64;
-}
diff --git a/gcc/testsuite/gcc.target/s390/pr79895.c 
b/gcc/testsuite/gcc.target/s390/pr79895.c
deleted file mode 100644
index 02374e4b8a80..
--- a/gcc/testsuite/gcc.target/s390/pr79895.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* { dg-do compile { target int128 } } */
-/* { dg-options "-O1 -mno-lra" } */
-
-unsigned __int128 g;
-void
-foo ()
-{
-  g = (unsigned __int128)1 << 127;
-}


[gcc r13-9046] Fix small thinko in IPA mod/ref pass

2024-09-20 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:f673c0c1d3038a87f58aa8be8603225711c50504

commit r13-9046-gf673c0c1d3038a87f58aa8be8603225711c50504
Author: Eric Botcazou 
Date:   Fri Sep 20 12:32:13 2024 +0200

Fix small thinko in IPA mod/ref pass

When a memory copy operation is analyzed by analyze_ssa_name, if both the
load and store are made through the same SSA name, the store is overlooked.

gcc/
* ipa-modref.cc (modref_eaf_analysis::analyze_ssa_name): Always
process both the load and the store of a memory copy operation.

gcc/testsuite/
* gcc.dg/ipa/modref-4.c: New test.

Diff:
---
 gcc/ipa-modref.cc   |  3 ++-
 gcc/testsuite/gcc.dg/ipa/modref-4.c | 34 ++
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index 0b42955eb3a1..795c4425ce37 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -2600,8 +2600,9 @@ modref_eaf_analysis::analyze_ssa_name (tree name, bool 
deferred)
 is used arbitrarily.  */
  if (memory_access_to (gimple_assign_rhs1 (assign), name))
m_lattice[index].merge (deref_flags (0, false));
+
  /* Handle *name = *exp.  */
- else if (memory_access_to (gimple_assign_lhs (assign), name))
+ if (memory_access_to (gimple_assign_lhs (assign), name))
m_lattice[index].merge_direct_store ();
}
  /* Handle lhs = *name.  */
diff --git a/gcc/testsuite/gcc.dg/ipa/modref-4.c 
b/gcc/testsuite/gcc.dg/ipa/modref-4.c
new file mode 100644
index ..71ed1ca5f5b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/modref-4.c
@@ -0,0 +1,34 @@
+/* { dg-options "-O"  } */
+/* { dg-do run } */
+
+static __attribute__((noipa)) int foo (void)
+{
+  return 1;
+}
+
+int main (void)
+{
+  struct S { int a; int b; };
+  struct T { struct S s; };
+
+  struct T t = { { 0, 0 } };
+  struct T u;
+
+  __attribute__((noinline)) void bar (void)
+  {
+if (foo ())
+  {
+   u = t;
+/* OK with u.s.a = 0; */
+  }
+  }
+
+  u.s.a = 1;
+
+  bar ();
+
+  if (u.s.a != 0)
+__builtin_abort ();
+
+  return 0;
+}


[gcc r15-3741] c++: CWG 2789 and usings [PR116492]

2024-09-20 Thread Patrick Palka via Gcc-cvs
https://gcc.gnu.org/g:ee3efe06c9c49c04eaa4e195a7ae8774a1b3faa2

commit r15-3741-gee3efe06c9c49c04eaa4e195a7ae8774a1b3faa2
Author: Patrick Palka 
Date:   Fri Sep 20 12:33:13 2024 -0400

c++: CWG 2789 and usings [PR116492]

After CWG 2789, the "more constrained" tiebreaker for non-template
functions should exclude member functions that are defined in
different classes.  This patch implements this missing refinement.

In turn we can get rid of four-parameter version of object_parms_correspond
and call the main overload directly since now correspondence is only
only checked for members from the same class.

PR c++/116492
DR 2789

gcc/cp/ChangeLog:

* call.cc (object_parms_correspond): Remove.
(cand_parms_match): Return false for member functions that come
from different classes.  Adjust call to object_parms_correspond.
(joust): Update comment for the non-template "more constrained"
case.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-memfun4.C: Also compile in C++20 mode.
Expect ambiguity when candidates come from different classes.
* g++.dg/cpp2a/concepts-inherit-ctor12.C: New test.

Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/call.cc | 54 --
 .../g++.dg/cpp2a/concepts-inherit-ctor12.C | 16 +++
 gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C  | 24 +-
 3 files changed, 49 insertions(+), 45 deletions(-)

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 6229dc452636..f2ce50857ece 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -12808,27 +12808,6 @@ class_of_implicit_object (z_candidate *cand)
   return BINFO_TYPE (cand->conversion_path);
 }
 
-/* True if candidates C1 and C2 have corresponding object parameters per
-   [basic.scope.scope].  */
-
-static bool
-object_parms_correspond (z_candidate *c1, tree fn1, z_candidate *c2, tree fn2)
-{
-  tree context = class_of_implicit_object (c1);
-  tree ctx2 = class_of_implicit_object (c2);
-  if (!ctx2)
-/* Leave context as is. */;
-  else if (!context)
-context = ctx2;
-  else if (context != ctx2)
-/* This can't happen for normal function calls, since it means finding
-   functions in multiple bases which would fail with an ambiguous lookup,
-   but it can occur with reversed operators.  */
-return false;
-
-  return object_parms_correspond (fn1, fn2, context);
-}
-
 /* Return whether the first parameter of C1 matches the second parameter
of C2.  */
 
@@ -12893,16 +12872,19 @@ cand_parms_match (z_candidate *c1, z_candidate *c2, 
pmatch match_kind)
   tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn1));
   tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (fn2));
 
-  if (!(DECL_FUNCTION_MEMBER_P (fn1)
-   && DECL_FUNCTION_MEMBER_P (fn2)))
-/* Early escape.  */;
-
-  /* CWG2789 is not adequate, it should specify corresponding object
- parameters, not same typed object parameters.  */
-  else if (!object_parms_correspond (c1, fn1, c2, fn2))
-return false;
-  else
+  if (DECL_FUNCTION_MEMBER_P (fn1)
+  && DECL_FUNCTION_MEMBER_P (fn2))
 {
+  tree base1 = DECL_CONTEXT (strip_inheriting_ctors (fn1));
+  tree base2 = DECL_CONTEXT (strip_inheriting_ctors (fn2));
+  if (base1 != base2)
+   return false;
+
+  /* Use object_parms_correspond to simplify comparing iobj/xobj/static
+member functions.  */
+  if (!object_parms_correspond (fn1, fn2, base1))
+   return false;
+
   /* We just compared the object parameters, if they don't correspond
 we already returned false.  */
   auto skip_parms = [] (tree fn, tree parms)
@@ -13269,10 +13251,14 @@ joust (struct z_candidate *cand1, struct z_candidate 
*cand2, bool warn,
return winner;
 }
 
-  /* Concepts: F1 and F2 are non-template functions with the same
- parameter-type-lists, and F1 is more constrained than F2 according to the
- partial ordering of constraints described in 13.5.4.  */
-
+  /* F1 and F2 are non-template functions and
+ - they have the same non-object-parameter-type-lists ([dcl.fct]), and
+ - if they are member functions, both are direct members of the same
+   class, and
+ - if both are non-static member functions, they have the same types for
+   their object parameters, and
+ - F1 is more constrained than F2 according to the partial ordering of
+   constraints described in [temp.constr.order].  */
   if (flag_concepts && DECL_P (cand1->fn) && DECL_P (cand2->fn)
   && !cand1->template_decl && !cand2->template_decl
   && cand_parms_match (cand1, cand2, pmatch::current))
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor12.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor12.C
new file mode 100644
index ..3e5dbfc37ad0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concep

[gcc r15-3740] c++: CWG 2273 and non-constructors

2024-09-20 Thread Patrick Palka via Gcc-cvs
https://gcc.gnu.org/g:06557ba12b64c57368673c46a21b14cf4e6afb50

commit r15-3740-g06557ba12b64c57368673c46a21b14cf4e6afb50
Author: Patrick Palka 
Date:   Fri Sep 20 12:31:40 2024 -0400

c++: CWG 2273 and non-constructors

Our implementation of the CWG 2273 inheritedness tiebreaker seems to be
incorrectly considering all member functions introduced via using, not
just constructors.  This patch restricts the tiebreaker accordingly.

DR 2273

gcc/cp/ChangeLog:

* call.cc (joust): Restrict inheritedness tiebreaker to
constructors.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1z/using1.C: Expect ambiguity for non-constructor call.
* g++.dg/overload/using5.C: Likewise.

Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/call.cc | 11 ---
 gcc/testsuite/g++.dg/cpp1z/using1.C|  8 
 gcc/testsuite/g++.dg/overload/using5.C |  2 +-
 3 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 3f753e2d2f98..6229dc452636 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -13350,13 +13350,10 @@ joust (struct z_candidate *cand1, struct z_candidate 
*cand2, bool warn,
}
 }
 
-  /* F1 is a member of a class D, F2 is a member of a base class B of D, and
- for all arguments the corresponding parameters of F1 and F2 have the same
- type (CWG 2273/2277). */
-  if (DECL_P (cand1->fn) && DECL_CLASS_SCOPE_P (cand1->fn)
-  && !DECL_CONV_FN_P (cand1->fn)
-  && DECL_P (cand2->fn) && DECL_CLASS_SCOPE_P (cand2->fn)
-  && !DECL_CONV_FN_P (cand2->fn))
+  /* F1 is a constructor for a class D, F2 is a constructor for a base class B
+ of D, and for all arguments the corresponding parameters of F1 and F2 have
+ the same type (CWG 2273/2277).  */
+  if (DECL_INHERITED_CTOR (cand1->fn) || DECL_INHERITED_CTOR (cand2->fn))
 {
   tree base1 = DECL_CONTEXT (strip_inheriting_ctors (cand1->fn));
   tree base2 = DECL_CONTEXT (strip_inheriting_ctors (cand2->fn));
diff --git a/gcc/testsuite/g++.dg/cpp1z/using1.C 
b/gcc/testsuite/g++.dg/cpp1z/using1.C
index 1ed939d45fd4..d8a045255795 100644
--- a/gcc/testsuite/g++.dg/cpp1z/using1.C
+++ b/gcc/testsuite/g++.dg/cpp1z/using1.C
@@ -1,5 +1,5 @@
-// Test for hiding of used base functions when all the conversion sequences are
-// equivalent, needed to avoid a regression on inherited default ctors.
+// Test the CWG 2273 inheritedness tiebreaker doesn't apply to
+// non-constructors.
 
 struct A
 {
@@ -17,7 +17,7 @@ struct B:A
 
 int main()
 {
-  B().f(1);// OK, derived f hides base f for single arg
+  B().f(1);// { dg-error "ambiguous" }
   B().f(1,2);  // OK, base f can still be called with two args
-  B().g(1);// { dg-error "" } signatures differ, ambiguous
+  B().g(1);// { dg-error "ambiguous" }
 }
diff --git a/gcc/testsuite/g++.dg/overload/using5.C 
b/gcc/testsuite/g++.dg/overload/using5.C
index ad17c78a561e..0933a9f0fac3 100644
--- a/gcc/testsuite/g++.dg/overload/using5.C
+++ b/gcc/testsuite/g++.dg/overload/using5.C
@@ -24,5 +24,5 @@ struct C: B {
 int main()
 {
   C c (42);
-  c.f();
+  c.f(); // { dg-error "ambiguous" }
 }


[gcc r15-3743] modula2: Remove unused parameter warnings seen in build

2024-09-20 Thread Gaius Mulley via Gcc-cvs
https://gcc.gnu.org/g:2828ec526eaf5612178b62d48bfd8443c7ecd674

commit r15-3743-g2828ec526eaf5612178b62d48bfd8443c7ecd674
Author: Gaius Mulley 
Date:   Fri Sep 20 19:05:16 2024 +0100

modula2: Remove unused parameter warnings seen in build

This patch removes unused parameters in gm2-compiler/M2Check.mod.
It also removes a --fixme-- and completes the missing code
which type checks unbounded arrays.  The patch also fixes a
build error seen when building m2/stage2/cc1gm2.

gcc/m2/ChangeLog:

* gm2-compiler/M2Check.mod (checkUnboundedArray): New
procedure function.
(checkUnboundedUnbounded): Ditto.
(checkUnbounded): Rewrite to check the unbounded data
type.
(checkPair): Add comment.
(doCheckPair): Add comment.
Remove tinfo parameter from the call to checkTypeKindViolation.
(checkTypeKindViolation): Remove ununsed parameter tinfo.
* gm2-libs-ch/UnixArgs.cc (GM2RTS.h): Remove include.
* gm2-libs-ch/m2rts.h (M2RTS_INIT): New define.
(M2RTS_DEP): Ditto.
(M2RTS_RegisterModule): New prototype.
(GM2RTS.h): Add include to the MC_M2 block.

gcc/testsuite/ChangeLog:

* gm2/iso/fail/testarrayunbounded2.mod: New test.
* gm2/iso/fail/testarrayunbounded3.mod: New test.
* gm2/iso/fail/testarrayunbounded4.mod: New test.
* gm2/iso/fail/testarrayunbounded5.mod: New test.
* gm2/iso/fail/testarrayunbounded6.mod: New test.
* gm2/iso/pass/testarrayunbounded.mod: New test.

Signed-off-by: Gaius Mulley 

Diff:
---
 gcc/m2/gm2-compiler/M2Check.mod| 138 +++--
 gcc/m2/gm2-libs-ch/UnixArgs.cc |   1 -
 gcc/m2/gm2-libs-ch/m2rts.h |   7 +-
 gcc/testsuite/gm2/iso/fail/testarrayunbounded2.mod |  14 +++
 gcc/testsuite/gm2/iso/fail/testarrayunbounded3.mod |  14 +++
 gcc/testsuite/gm2/iso/fail/testarrayunbounded4.mod |  14 +++
 gcc/testsuite/gm2/iso/fail/testarrayunbounded5.mod |  13 ++
 gcc/testsuite/gm2/iso/fail/testarrayunbounded6.mod |  13 ++
 gcc/testsuite/gm2/iso/pass/testarrayunbounded.mod  |  14 +++
 9 files changed, 213 insertions(+), 15 deletions(-)

diff --git a/gcc/m2/gm2-compiler/M2Check.mod b/gcc/m2/gm2-compiler/M2Check.mod
index 1750fe07ecf1..d096646c3877 100644
--- a/gcc/m2/gm2-compiler/M2Check.mod
+++ b/gcc/m2/gm2-compiler/M2Check.mod
@@ -48,7 +48,7 @@ FROM SymbolTable IMPORT NulSym, IsRecord, IsSet, GetDType, 
GetSType, IsType,
 GetMode, GetType, IsUnbounded, IsComposite, 
IsConstructor,
 IsParameter, IsConstString, IsConstLitInternal, 
IsConstLit,
 GetStringLength, GetProcedureProcType, IsHiddenType,
-IsHiddenReallyPointer ;
+IsHiddenReallyPointer, GetDimension ;
 
 FROM M2GCCDeclare IMPORT GetTypeMin, GetTypeMax ;
 FROM M2System IMPORT Address ;
@@ -259,12 +259,93 @@ BEGIN
 END checkSubrange ;
 
 
+(*
+   checkUnboundedArray - returns status if unbounded is parameter compatible 
with array.
+ It checks all type equivalences of the static array 
for a
+ match with the dynamic (unbounded) array.
+*)
+
+PROCEDURE checkUnboundedArray (result: status;
+   unbounded, array: CARDINAL) : status ;
+VAR
+   dim   : CARDINAL ;
+   ubtype,
+   type  : CARDINAL ;
+BEGIN
+   (* Firstly check to see if we have resolved this as false.  *)
+   IF isFalse (result)
+   THEN
+  RETURN result
+   ELSE
+  Assert (IsUnbounded (unbounded)) ;
+  Assert (IsArray (array)) ;
+  dim := GetDimension (unbounded) ;
+  ubtype := GetType (unbounded) ;
+  type := array ;
+  REPEAT
+ type := GetType (type) ;
+ DEC (dim) ;
+ (* Check type equivalences.  *)
+ IF checkTypeEquivalence (result, type, ubtype) = true
+ THEN
+RETURN true
+ END ;
+ type := SkipType (type) ;
+ (* If we have run out of dimensions we conclude false.  *)
+ IF dim = 0
+ THEN
+RETURN false
+ END ;
+  UNTIL NOT IsArray (type)
+   END ;
+   RETURN false
+END checkUnboundedArray ;
+
+
+(*
+   checkUnboundedUnbounded - check to see if formal and actual are compatible.
+ Both are unbounded parameters.
+*)
+
+PROCEDURE checkUnboundedUnbounded (result: status;
+   tinfo: tInfo;
+   formal, actual: CARDINAL) : status ;
+BEGIN
+   (* Firstly check to see if we have resolved this as false.  *)
+   IF isFalse (result)
+   THEN
+  RETURN result
+   ELSE
+  Assert (IsUnbounded (formal)) ;
+  Assert (IsUnbounded (actual)) ;
+  (* The actual parameter above might be a different symbol to the actual

[gcc r12-10720] Fortran: fix ICE in gfc_create_module_variable [PR100273]

2024-09-20 Thread Harald Anlauf via Gcc-cvs
https://gcc.gnu.org/g:cb25c5dd6b315dc216c7a5640dc89c5d74ffea34

commit r12-10720-gcb25c5dd6b315dc216c7a5640dc89c5d74ffea34
Author: Harald Anlauf 
Date:   Thu Sep 5 21:30:25 2024 +0200

Fortran: fix ICE in gfc_create_module_variable [PR100273]

gcc/fortran/ChangeLog:

PR fortran/100273
* trans-decl.cc (gfc_create_module_variable): Handle module
variable also when it is needed for the result specification
of a contained function.

gcc/testsuite/ChangeLog:

PR fortran/100273
* gfortran.dg/pr100273.f90: New test.

(cherry picked from commit 1f462b5072a5e82c35921f7e3bdf3959c4a49dc9)

Diff:
---
 gcc/fortran/trans-decl.cc  |  3 ++-
 gcc/testsuite/gfortran.dg/pr100273.f90 | 26 ++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 0e91553108f2..884978ad981d 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -5251,7 +5251,8 @@ gfc_create_module_variable (gfc_symbol * sym)
   /* Create the variable.  */
   pushdecl (decl);
   gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE
- || (sym->ns->parent->proc_name->attr.flavor == FL_MODULE
+ || ((sym->ns->parent->proc_name->attr.flavor == FL_MODULE
+  || sym->ns->parent->proc_name->attr.flavor == FL_PROCEDURE)
  && sym->fn_result_spec));
   DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
   rest_of_decl_compilation (decl, 1, 0);
diff --git a/gcc/testsuite/gfortran.dg/pr100273.f90 
b/gcc/testsuite/gfortran.dg/pr100273.f90
new file mode 100644
index ..f71947ad802d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr100273.f90
@@ -0,0 +1,26 @@
+! { dg-do compile }
+! PR fortran/100273 - ICE in gfc_create_module_variable
+!
+! Contributed by G.Steinmetz
+
+module m
+  implicit none
+contains
+  character(4) function g(k)
+integer :: k
+g = f(k)
+  contains
+function f(n)
+  character(3), parameter :: a(2) = ['1  ', '123']
+  integer :: n
+  character(len_trim(a(n))) :: f
+  f = 'abc'
+end
+  end
+end
+program p
+  use m 
+  implicit none
+  print *, '>>' // g(1) // '<<'
+  print *, '>>' // g(2) // '<<'
+end


[gcc r13-9048] Fortran: fix ICE in gfc_create_module_variable [PR100273]

2024-09-20 Thread Harald Anlauf via Gcc-cvs
https://gcc.gnu.org/g:3604d9cab9bb9fe6a3c642385c816211b8f2be5d

commit r13-9048-g3604d9cab9bb9fe6a3c642385c816211b8f2be5d
Author: Harald Anlauf 
Date:   Thu Sep 5 21:30:25 2024 +0200

Fortran: fix ICE in gfc_create_module_variable [PR100273]

gcc/fortran/ChangeLog:

PR fortran/100273
* trans-decl.cc (gfc_create_module_variable): Handle module
variable also when it is needed for the result specification
of a contained function.

gcc/testsuite/ChangeLog:

PR fortran/100273
* gfortran.dg/pr100273.f90: New test.

(cherry picked from commit 1f462b5072a5e82c35921f7e3bdf3959c4a49dc9)

Diff:
---
 gcc/fortran/trans-decl.cc  |  3 ++-
 gcc/testsuite/gfortran.dg/pr100273.f90 | 26 ++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 299764b08b25..bbc8e34de27b 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -5294,7 +5294,8 @@ gfc_create_module_variable (gfc_symbol * sym)
   /* Create the variable.  */
   pushdecl (decl);
   gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE
- || (sym->ns->parent->proc_name->attr.flavor == FL_MODULE
+ || ((sym->ns->parent->proc_name->attr.flavor == FL_MODULE
+  || sym->ns->parent->proc_name->attr.flavor == FL_PROCEDURE)
  && sym->fn_result_spec));
   DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
   rest_of_decl_compilation (decl, 1, 0);
diff --git a/gcc/testsuite/gfortran.dg/pr100273.f90 
b/gcc/testsuite/gfortran.dg/pr100273.f90
new file mode 100644
index ..f71947ad802d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr100273.f90
@@ -0,0 +1,26 @@
+! { dg-do compile }
+! PR fortran/100273 - ICE in gfc_create_module_variable
+!
+! Contributed by G.Steinmetz
+
+module m
+  implicit none
+contains
+  character(4) function g(k)
+integer :: k
+g = f(k)
+  contains
+function f(n)
+  character(3), parameter :: a(2) = ['1  ', '123']
+  integer :: n
+  character(len_trim(a(n))) :: f
+  f = 'abc'
+end
+  end
+end
+program p
+  use m 
+  implicit none
+  print *, '>>' // g(1) // '<<'
+  print *, '>>' // g(2) // '<<'
+end


[gcc r15-3745] c: fix crash when checking for compatibility of structures [PR116726]

2024-09-20 Thread Martin Uecker via Gcc-cvs
https://gcc.gnu.org/g:9227a64495d5594613604573b72422e8e3722fc5

commit r15-3745-g9227a64495d5594613604573b72422e8e3722fc5
Author: Martin Uecker 
Date:   Tue Sep 17 11:37:29 2024 +0200

c: fix crash when checking for compatibility of structures [PR116726]

When checking for compatibility of structure or union types in
tagged_types_tu_compatible_p, restore the old value of the pointer to
the top of the temporary cache after recursively calling comptypes_internal
when looping over the members of a structure of union.  While the next
iteration of the loop overwrites the pointer, I missed the fact that it can
be accessed again when types of function arguments are compared as part
of recursive type checking and the function is entered again.

PR c/116726

gcc/c/ChangeLog:

* c-typeck.cc (tagged_types_tu_compatible_p): Restore value
of the cache after recursing into comptypes_internal.

gcc/testsuite/ChangeLog:

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

Diff:
---
 gcc/c/c-typeck.cc   |  5 -
 gcc/testsuite/gcc.dg/pr116726.c | 18 ++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 58b2724b39e3..ba6d96d26b2b 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -1686,8 +1686,11 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree 
t2,
data->anon_field = !DECL_NAME (s1);
data->pointedto = false;
 
+   const struct tagged_tu_seen_cache *cache = data->cache;
data->cache = &entry;
-   if (!comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2), data))
+   bool ret = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2), 
data);
+   data->cache = cache;
+   if (!ret)
  return false;
 
tree st1 = TYPE_SIZE (TREE_TYPE (s1));
diff --git a/gcc/testsuite/gcc.dg/pr116726.c b/gcc/testsuite/gcc.dg/pr116726.c
new file mode 100644
index ..bb25efca5864
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr116726.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23" } */
+
+struct s1 {
+  int f1;
+};
+struct s2 {
+  int f2;
+};
+struct s1 f(struct s2 *);
+
+struct s1 {
+  int f1;
+};
+struct s2 {
+  int f2;
+};
+struct s1 f(struct s2 *);


[gcc r14-10696] c++: CWG 2789 and usings [PR116492]

2024-09-20 Thread Patrick Palka via Gcc-cvs
https://gcc.gnu.org/g:659f32ea9de57661f8a37dcfb0b9a01bfe29acce

commit r14-10696-g659f32ea9de57661f8a37dcfb0b9a01bfe29acce
Author: Patrick Palka 
Date:   Fri Sep 20 17:37:03 2024 -0400

c++: CWG 2789 and usings [PR116492]

For GCC 14, narrowly fix this PR by implementing the missing

  - if they are member functions, both are direct members of the same
class, and

part of CWG 2789 for constructors only.

PR c++/116492
DR 2789

gcc/cp/ChangeLog:

* call.cc (cand_parms_match): Return false for constructors that
come from different classes.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-inherit-ctor12.C: New test.

Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/call.cc   |  8 
 gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor12.C | 16 
 2 files changed, 24 insertions(+)

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 0f4eeeb53951..492d17b17446 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -12826,6 +12826,14 @@ cand_parms_match (z_candidate *c1, z_candidate *c2, 
pmatch match_kind)
&& DECL_FUNCTION_MEMBER_P (fn2)))
 /* Early escape.  */;
 
+  else if ((DECL_INHERITED_CTOR (fn1) || DECL_INHERITED_CTOR (fn2))
+  && (DECL_CONTEXT (strip_inheriting_ctors (fn1))
+  != DECL_CONTEXT (strip_inheriting_ctors (fn2
+/* This should really be checked for all member functions as per
+   CWG2789, but for GCC 14 we check this only for constructors since
+   without r15-3740 doing so would result in inconsistent handling
+   of object parameters (such as in concepts-memfun4.C).  */
+return false;
   /* CWG2789 is not adequate, it should specify corresponding object
  parameters, not same typed object parameters.  */
   else if (!object_parms_correspond (c1, fn1, c2, fn2))
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor12.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor12.C
new file mode 100644
index ..3e5dbfc37ad0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor12.C
@@ -0,0 +1,16 @@
+// PR c++/116492
+// CWG 2789
+// { dg-do compile { target c++20 } }
+
+template
+struct A {
+  A() requires true = delete;
+};
+
+struct B : A {
+  B();
+  using A::A;
+};
+
+B b; // OK, selects the non-inherited constructor over the more constrained
+ // inherited constructor.


[gcc r14-10697] c++: decltype(auto) deduction of statement-expression [PR116418]

2024-09-20 Thread Patrick Palka via Gcc-cvs
https://gcc.gnu.org/g:abdea396e12e66185d810435bbc363845cf4664a

commit r14-10697-gabdea396e12e66185d810435bbc363845cf4664a
Author: Patrick Palka 
Date:   Thu Sep 12 12:45:03 2024 -0400

c++: decltype(auto) deduction of statement-expression [PR116418]

r8-7538 for PR84968 made strip_typedefs_expr diagnose STATEMENT_LIST
so that we reject statement-expressions in noexcept-specifiers to
match our behavior in template arguments (which the parser diagnoses
directly).

Later r11-7452 made decltype(auto) deduction canonicalize the expression
(as an implementation detail) which in turn calls strip_typedefs_expr,
and so ever since we inadvertently reject decltype(auto) deduction of a
statement-expression.

This patch just removes the diagnostic in strip_typedefs_expr and instead
treats statement-expressions similar to lambda-expressions.  The function
doesn't seem like the right place for such a diagnostic and so it seems
easier to just accept rather than try to reject them in a suitable place.

PR c++/116418

gcc/cp/ChangeLog:

* tree.cc (strip_typedefs_expr) : Replace
this error path with ...
: ... this, returning the original tree.

gcc/testsuite/ChangeLog:

* g++.dg/eh/pr84968.C: No longer expect an ahead of time diagnostic
for the statement-expresssion.  Instantiate the template and expect
an incomplete type error instead.
* g++.dg/ext/stmtexpr26.C: New test.

Reviewed-by: Jason Merrill 
(cherry picked from commit 12bdcc3d7970860b9d66ed4dea203bde8fd68d4d)

Diff:
---
 gcc/cp/tree.cc|  5 +
 gcc/testsuite/g++.dg/eh/pr84968.C |  4 +++-
 gcc/testsuite/g++.dg/ext/stmtexpr26.C | 10 ++
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index d90244609c8a..a056237e8669 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -2008,12 +2008,9 @@ strip_typedefs_expr (tree t, bool *remove_attributes, 
unsigned int flags)
   }
 
 case LAMBDA_EXPR:
+case STMT_EXPR:
   return t;
 
-case STATEMENT_LIST:
-  error ("statement-expression in a constant expression");
-  return error_mark_node;
-
 default:
   break;
 }
diff --git a/gcc/testsuite/g++.dg/eh/pr84968.C 
b/gcc/testsuite/g++.dg/eh/pr84968.C
index 23c49f477a88..a6e21914eed1 100644
--- a/gcc/testsuite/g++.dg/eh/pr84968.C
+++ b/gcc/testsuite/g++.dg/eh/pr84968.C
@@ -9,7 +9,9 @@ struct S {
   void a()
 try {
 } catch (int ()
-noexcept (({ union b a; true; }))) // { dg-error "constant" }
+noexcept (({ union b a; true; }))) // { dg-error "'b a' has 
incomplete type" }
   {
   }
 };
+
+template void S::a(); // { dg-message "required from here" }
diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr26.C 
b/gcc/testsuite/g++.dg/ext/stmtexpr26.C
new file mode 100644
index ..2250df550d48
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/stmtexpr26.C
@@ -0,0 +1,10 @@
+// PR c++/116418
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+void foo ();
+template 
+void bar ()
+{
+  decltype(auto) v = ({ foo (); 3; });
+}


[gcc r15-3746] libstdc++: Document missing features for old std:string ABI [PR116777]

2024-09-20 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:82309222300acf68e345b32155df21e1b876144e

commit r15-3746-g82309222300acf68e345b32155df21e1b876144e
Author: Jonathan Wakely 
Date:   Fri Sep 20 17:35:48 2024 +0100

libstdc++: Document missing features for old std:string ABI [PR116777]

There are several features that are not supported when using the old
std::string ABI. It's possible that PR 81967 will get fixed, but the
missing C++20 features almost certainly won't be. Document this in the
manual.

libstdc++-v3/ChangeLog:

PR libstdc++/116777
* doc/xml/manual/using.xml: Document features that are not
supported for the gcc4-compatible ABI.
* doc/html/manual/using_dual_abi.html: Regenerate.

Diff:
---
 libstdc++-v3/doc/html/manual/using_dual_abi.html | 18 +++-
 libstdc++-v3/doc/xml/manual/using.xml| 26 +++-
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/using_dual_abi.html 
b/libstdc++-v3/doc/html/manual/using_dual_abi.html
index 916ac575f64b..939eedae3629 100644
--- a/libstdc++-v3/doc/html/manual/using_dual_abi.html
+++ b/libstdc++-v3/doc/html/manual/using_dual_abi.html
@@ -22,7 +22,7 @@
   of the macro is 1 which causes the new ABI to 
be active,
   so to use the old ABI you must explicitly define the macro to
   0 before including any library headers.
-  (Be aware that some GNU/Linux distributions configure GCC 5 differently so
+  (Be aware that some GNU/Linux distributions configured GCC 5 differently so
   that the default value of the macro is 0 and 
users must
   define it to 1 to enable the new ABI.)
  Although the changes were made for C++11 conformance, the choice of ABI
@@ -72,6 +72,22 @@
   Handlers for std::exception will always catch
   iostreams exceptions, because the old and new type both inherit from
   std::exception.
+
+  Some features are not supported when using the old ABI, including:
+  
+Using std::string::const_iterator for
+positional arguments to member functions such as
+std::string::erase.
+  
+Allocator propagation in std::string.
+  
+Using std::string at compile-time in
+constexpr functions.
+  
+Class std::chrono::time_zone and all 
related APIs.
+  
+The  header.
+  
 Troubleshooting
 If you get linker errors about undefined references to symbols
   that involve types in the std::__cxx11 namespace 
or the tag
   [abi:cxx11] then it probably indicates that you 
are trying to
diff --git a/libstdc++-v3/doc/xml/manual/using.xml 
b/libstdc++-v3/doc/xml/manual/using.xml
index 4e1c70040b56..89119f6fb2db 100644
--- a/libstdc++-v3/doc/xml/manual/using.xml
+++ b/libstdc++-v3/doc/xml/manual/using.xml
@@ -1368,7 +1368,7 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 
hello.cc -o test.exe
   of the macro is 1 which causes the new ABI to be active,
   so to use the old ABI you must explicitly define the macro to
   0 before including any library headers.
-  (Be aware that some GNU/Linux distributions configure GCC 5 differently so
+  (Be aware that some GNU/Linux distributions configured GCC 5 differently so
   that the default value of the macro is 0 and users must
   define it to 1 to enable the new ABI.)
 
@@ -1428,6 +1428,30 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 
hello.cc -o test.exe
   std::exception.
 
 
+
+  Some features are not supported when using the old ABI, including:
+  
+  
+Using std::string::const_iterator for
+positional arguments to member functions such as
+std::string::erase.
+  
+  
+Allocator propagation in std::string.
+  
+  
+Using std::string at compile-time in
+constexpr functions.
+  
+  
+Class std::chrono::time_zone and all related APIs.
+  
+  
+The  header.
+  
+  
+
+
 Troubleshooting
 
  If you get linker errors about undefined references to symbols


[gcc r15-3749] diagnostics: convert text hooks to use diagnostic_text_output_format [PR116613]

2024-09-20 Thread David Malcolm via Gcc-cvs
https://gcc.gnu.org/g:7da682c896f949259eaf820be17b5781df2cbead

commit r15-3749-g7da682c896f949259eaf820be17b5781df2cbead
Author: David Malcolm 
Date:   Fri Sep 20 18:51:55 2024 -0400

diagnostics: convert text hooks to use diagnostic_text_output_format 
[PR116613]

The diagnostic_starter and diagnostic_finalizer callbacks and most of
their support subroutines are only used by the "text" output format.

Emphasize this and reduce the binding with diagnostic_context
by renaming the callbacks to add "_text" in their names, and converting
the first param from diagnostic_context * to
diagnostic_text_output_output &.  Update the various subroutines used
by diagnostic starter/finalizer callbacks to also take a
diagnostic_text_output_output & rather than a diagnostic_context *.
Move m_includes and m_last_seen from the context to the text output.

Use the text_output's get_printer () rather than the context's
m_printer, which should ease the transition to multiple output sinks.

No functional change intended.

gcc/c-family/ChangeLog:
PR other/116613
* c-opts.cc: Include "diagnostic-format-text.h".
(c_diagnostic_finalizer): Rename to...
(c_diagnostic_text_finalizer): ...this.  Convert first param
from diagnostic_context * to diagnostic_text_output_format & and
update accordingly.
(c_common_diagnostics_set_defaults): Update for renamings.

gcc/ChangeLog:
PR other/116613
* coretypes.h (class diagnostic_text_output_format): Add forward
decl.
* diagnostic-format-json.cc
(json_output_format::after_diagnostic): New.
* diagnostic-format-sarif.cc
(sarif_output_format::after_diagnostic): New.
* diagnostic-format-text.cc: Use pragmas to ignore -Wformat-diag.
(diagnostic_text_output_format::~diagnostic_text_output_format):
Use get_printer.  Clean up m_includes_seen here, rather than
in ~diagnostic_context.
(diagnostic_text_output_format::on_report_diagnostic):  Use
get_printer.  Update for callback renamings and pass *this
to them, rather than &m_context.
(diagnostic_text_output_format::after_diagnostic): New.
(diagnostic_text_output_format::includes_seen_p): Move here
from diagnostic_context/diagnostic.cc.
(diagnostic_text_output_format::get_location_text): New.
(maybe_line_and_column): Move here from diagnostic.cc and make
non-static.
(diagnostic_text_output_format::report_current_module): Move
here from diagnostic_context/diagnostic.cc.
(default_diagnostic_text_starter): Move here from diagnostic.cc,
renaming from default_diagnostic_starter.
(default_diagnostic_text_finalizer): Likewise, renaming from
default_diagnostic_finalizer.
* diagnostic-format-text.h
(diagnostic_text_output_format::diagnostic_text_output_format):
Initialize m_last_module and m_includes_seen.
(diagnostic_text_output_format::after_diagnostic): New decl.
(diagnostic_text_output_format::build_prefix): New decl.
(diagnostic_text_output_format::report_current_module): New decl.
(diagnostic_text_output_format::append_note): New decl.
(diagnostic_text_output_format::file_name_as_prefix): New decl.
(diagnostic_text_output_format::print_path): New decl.
(diagnostic_text_output_format::show_column_p): New decl.
(diagnostic_text_output_format::get_location_text): New decl.
(diagnostic_text_output_format::includes_seen_p): New decl.
(diagnostic_text_output_format::show_any_path): New decl.
(diagnostic_text_output_format::m_last_module): New field.
(diagnostic_text_output_format::m_includes_seen): New field.
* diagnostic-format.h
(diagnostic_output_format::after_diagnostic): New vfunc.
(diagnostic_output_format::get_context): New.
(diagnostic_output_format::get_diagram_theme): New.
* diagnostic-macro-unwinding.cc: Include
"diagnostic-format-text.h".
(maybe_unwind_expanded_macro_loc): Convert first param from
diagnostic_context * to diagnostic_text_output_format & and update
accordingly.
(virt_loc_aware_diagnostic_finalizer): Likewise.
* diagnostic-macro-unwinding.h
(virt_loc_aware_diagnostic_finalizer): Likewise.
(maybe_unwind_expanded_macro_loc): Likewise.
* diagnostic-path.cc: Include "diagnostic-format-text.h".
(path_label::path_label): Drop "ctxt" param and add "colorize"
and "allow_emojis" params.  Update initializations.
 

[gcc r15-3751] analyzer: simplify dumps using tree_dump_pretty_printer [PR116613]

2024-09-20 Thread David Malcolm via Gcc-cvs
https://gcc.gnu.org/g:39f7703fffee0c1a8aa999b29ae52b2a31903715

commit r15-3751-g39f7703fffee0c1a8aa999b29ae52b2a31903715
Author: David Malcolm 
Date:   Fri Sep 20 18:51:55 2024 -0400

analyzer: simplify dumps using tree_dump_pretty_printer [PR116613]

There are numerous "dump" member functions in the analyzer with
copied-and-pasted logic.  Simplify them by moving the shared code
to a new class tree_dump_pretty_printer.

As well as reducing code duplication, this eliminates numerous
uses of pp_show_color (global_dc->m_printer), which should
ultimately help with supporting multiple diagnostic sinks.

No functional change intended.

gcc/analyzer/ChangeLog:
PR other/116613
* access-diagram.cc (access_range::dump): Simplify using
tree_dump_pretty_printer.
* call-details.cc (call_details::dump): Likewise.
* call-summary.cc (call_summary::dump): Likewise.
(call_summary_replay::dump): Likewise.
* checker-event.cc (checker_event::debug): Likewise.
* constraint-manager.cc (range::dump): Likewise.
(bounded_range::dump): Likewise.
(bounded_ranges::dump): Likewise.
(constraint_manager::dump): Likewise.
* engine.cc (exploded_node::dump): Likewise.
(exploded_path::dump): Likewise.
* program-point.cc (program_point::dump): Likewise.
* program-state.cc (extrinsic_state::dump_to_file): Likewise.
(sm_state_map::dump): Likewise.
(program_state::dump_to_file): Likewise.
* ranges.cc (symbolic_byte_offset::dump): Likewise.
(symbolic_byte_range::dump): Likewise.
* record-layout.cc (record_layout::dump): Likewise.
* region-model-reachability.cc (reachable_regions::dump):
Likewise.
* region-model.cc (region_to_value_map::dump): Likewise.
(region_model::dump): Likewise.
(model_merger::dump): Likewise.
* region.cc (region_offset::dump): Likewise.
(region::dump): Likewise.
* sm-malloc.cc (deallocator_set::dump): Likewise.
* store.cc (uncertainty_t::dump): Likewise.
(binding_key::dump): Likewise.
(bit_range::dump): Likewise.
(byte_range::dump): Likewise.
(binding_map::dump): Likewise.
(binding_cluster::dump): Likewise.
(store::dump): Likewise.
* supergraph.cc (superedge::dump): Likewise.
* svalue.cc (svalue::dump): Likewise.

gcc/ChangeLog:
PR other/116613
* text-art/dump.h (dump_to_file): Simplify using
tree_dump_pretty_printer.
* tree-diagnostic.h (class tree_dump_pretty_printer): New.

Signed-off-by: David Malcolm 

Diff:
---
 gcc/analyzer/access-diagram.cc|  6 +
 gcc/analyzer/call-details.cc  |  6 +
 gcc/analyzer/call-summary.cc  | 12 ++
 gcc/analyzer/checker-event.cc |  6 +
 gcc/analyzer/constraint-manager.cc| 24 ---
 gcc/analyzer/engine.cc| 12 ++
 gcc/analyzer/program-point.cc |  5 +---
 gcc/analyzer/program-state.cc | 19 +++-
 gcc/analyzer/ranges.cc| 12 ++
 gcc/analyzer/record-layout.cc |  5 +---
 gcc/analyzer/region-model-reachability.cc |  6 +
 gcc/analyzer/region-model.cc  | 18 +++
 gcc/analyzer/region.cc| 12 ++
 gcc/analyzer/sm-malloc.cc |  5 +---
 gcc/analyzer/store.cc | 38 ++-
 gcc/analyzer/supergraph.cc|  6 +
 gcc/analyzer/svalue.cc|  6 +
 gcc/text-art/dump.h   |  8 +--
 gcc/tree-diagnostic.h | 20 
 19 files changed, 55 insertions(+), 171 deletions(-)

diff --git a/gcc/analyzer/access-diagram.cc b/gcc/analyzer/access-diagram.cc
index ddeb45a94b24..4822ae392845 100644
--- a/gcc/analyzer/access-diagram.cc
+++ b/gcc/analyzer/access-diagram.cc
@@ -544,13 +544,9 @@ access_range::dump_to_pp (pretty_printer *pp, bool simple) 
const
 DEBUG_FUNCTION void
 access_range::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 void
diff --git a/gcc/analyzer/call-details.cc b/gcc/analyzer/call-details.cc
index e543eda347a5..a9c613bc1822 100644
--- a/gcc/analyzer/call-details.cc
+++ b/gcc/analyzer/call-details.cc
@@ -363,12 +363,8 @@ call_details::dump_to_pp (pretty_printer *pp, bool simple) 
const
 DEBUG_FUNCTION void
 

[gcc r15-3747] libstdc++: Avoid forming T* in unique_ptr(auto_ptr&&) constraints [PR116529]

2024-09-20 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:a001d515059ba4647169f8c17967d08bbe41cb7a

commit r15-3747-ga001d515059ba4647169f8c17967d08bbe41cb7a
Author: Jonathan Wakely 
Date:   Thu Aug 29 13:47:15 2024 +0100

libstdc++: Avoid forming T* in unique_ptr(auto_ptr&&) constraints 
[PR116529]

PR 116529 shows that std::unique_ptr is currently unusable
because the constructor taking std::auto_ptr (which is a non-standard
extension since C++17) tries to form the invalid type X&* during
overload resolution. We can use the `pointer` type in the constructor
constraints, instead of trying to form an invalid type. The
std::auto_ptr constructor can never actually match for the case where
element_type is a reference, so we just need it to produce a
substitution failure instead of being ill-formed.

LWG 4144 might make std::unique_ptr ill-formed, which would
invalidate this new test. We would have to remove this test in that
case. Using `pointer` in the constructor from std::auto_ptr would not be
needed to support the std::unique_ptr case, but would not cause
any harm either.

libstdc++-v3/ChangeLog:

PR libstdc++/116529
* include/bits/unique_ptr.h (unique_ptr(auto_ptr&&)):
Use pointer instead of T*.
* testsuite/20_util/unique_ptr/creation/116529.cc: New test.

Diff:
---
 libstdc++-v3/include/bits/unique_ptr.h |  5 ++--
 .../20_util/unique_ptr/creation/116529.cc  | 35 ++
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/unique_ptr.h 
b/libstdc++-v3/include/bits/unique_ptr.h
index 0f600db32f94..edcff78bff9f 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -379,8 +379,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
   /// Converting constructor from @c auto_ptr
-  template, is_same<_Dp, default_delete<_Tp
+  template,
+  is_same<_Dp, default_delete<_Tp
unique_ptr(auto_ptr<_Up>&& __u) noexcept;
 #pragma GCC diagnostic pop
 #endif
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/creation/116529.cc 
b/libstdc++-v3/testsuite/20_util/unique_ptr/creation/116529.cc
new file mode 100644
index ..323fc7cb27ce
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/creation/116529.cc
@@ -0,0 +1,35 @@
+// { dg-do run { target c++11 } }
+
+// Bug libstdc++/116529 - Construction of unique_ptr with reference type
+// is rejected because of auto_ptr constructor
+
+#include 
+#include 
+
+int count = 0;
+
+struct X
+{
+  ~X() { ++count; }
+};
+
+struct deleter : std::default_delete
+{
+  using pointer = X*;
+};
+
+void
+test01()
+{
+  {
+std::unique_ptr up(new X);
+// { dg-bogus "forming pointer to reference" "" { target *-*-* } 0 }
+VERIFY( count == 0 );
+  }
+  VERIFY( count == 1 );
+}
+
+int main()
+{
+  test01();
+}


[gcc r15-3752] diagnostics: add HTML output format as a plugin [PR116792]

2024-09-20 Thread David Malcolm via Gcc-cvs
https://gcc.gnu.org/g:48261bd26df624f0b906600fb0ef6864c7a7f895

commit r15-3752-g48261bd26df624f0b906600fb0ef6864c7a7f895
Author: David Malcolm 
Date:   Fri Sep 20 18:51:56 2024 -0400

diagnostics: add HTML output format as a plugin [PR116792]

This patch adds an experimental diagnostics output format that
writes HTML.  It isn't ready yet for end-users, but seems worth
keeping in the tree as I refactor the diagnostics subsystem, to
ensure that this code still builds, and to verify that it's possible to
implement new diagnostic output formats via GCC plugins. Hence
this patch merely adds it to the testsuite as an example of a GCC
plugin, rather than exposing it as a feature for end-users.

gcc/testsuite/ChangeLog:
PR other/116792
* gcc.dg/plugin/diagnostic-test-xhtml-1.c: New test.
* gcc.dg/plugin/diagnostic_plugin_xhtml_format.c: New test plugin.
* gcc.dg/plugin/plugin.exp (plugin_test_list): Add the above.

Signed-off-by: David Malcolm 

Diff:
---
 .../gcc.dg/plugin/diagnostic-test-xhtml-1.c|  19 +
 .../gcc.dg/plugin/diagnostic_plugin_xhtml_format.c | 866 +
 gcc/testsuite/gcc.dg/plugin/plugin.exp |   2 +
 3 files changed, 887 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-xhtml-1.c 
b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-xhtml-1.c
new file mode 100644
index ..da069ff4789d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-xhtml-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+int missing_semicolon (void)
+{
+  return 42
+}
+
+/* Verify some properties of the generated HTML.  */
+
+/* { dg-begin-multiline-output "" }
+
+http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
+http://www.w3.org/1999/xhtml";>
+  
+   { dg-end-multiline-output "" } */
+
+/* { dg-excess-errors "" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.c 
b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.c
new file mode 100644
index ..192288aff1bc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.c
@@ -0,0 +1,866 @@
+/* Verify that we can write a non-trivial diagnostic output format
+   as a plugin (XHTML).
+   Copyright (C) 2018-2024 Free Software Foundation, Inc.
+   Contributed by David Malcolm .
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+
+#include "config.h"
+#define INCLUDE_LIST
+#define INCLUDE_MAP
+#define INCLUDE_MEMORY
+#define INCLUDE_VECTOR
+#include "system.h"
+#include "coretypes.h"
+#include "diagnostic.h"
+#include "diagnostic-metadata.h"
+#include "diagnostic-path.h"
+#include "cpplib.h"
+#include "logical-location.h"
+#include "diagnostic-client-data-hooks.h"
+#include "diagnostic-diagram.h"
+#include "text-art/canvas.h"
+#include "diagnostic-format.h"
+#include "ordered-hash-map.h"
+#include "sbitmap.h"
+#include "make-unique.h"
+#include "selftest.h"
+#include "selftest-diagnostic.h"
+#include "selftest-diagnostic-show-locus.h"
+#include "text-range-label.h"
+#include "pretty-print-format-impl.h"
+#include "pretty-print-urlifier.h"
+#include "intl.h"
+#include "gcc-plugin.h"
+#include "plugin-version.h"
+
+namespace xml {
+
+/* Disable warnings about quoting issues in the pp_xxx calls below
+   that (intentionally) don't follow GCC diagnostic conventions.  */
+#if __GNUC__ >= 10
+#  pragma GCC diagnostic push
+#  pragma GCC diagnostic ignored "-Wformat-diag"
+#endif
+
+static void write_escaped_text (const char *text);
+
+struct node
+{
+  virtual ~node () {}
+  virtual void write_as_xml (pretty_printer *pp,
+int depth, bool indent) const = 0;
+  void dump (FILE *out) const;
+  void DEBUG_FUNCTION dump () const { dump (stderr); }
+};
+
+struct text : public node
+{
+  text (label_text str)
+  : m_str (std::move (str))
+  {}
+
+  void write_as_xml (pretty_printer *pp,
+int depth, bool indent) const final override;
+
+  label_text m_str;
+};
+
+struct node_with_children : public node
+{
+  void add_child (std::unique_ptr node);
+  void add_text (label_text str);
+
+  std::vector> m_children;
+};
+
+struct document : public node_with_children
+{
+  void write_as_xml (pretty_printer *pp,
+int depth, bool indent) const final override;
+};
+
+struct element : public node_with_children
+{
+  elemen

[gcc r15-3750] diagnostics: isolate SARIF output's pretty_printer [PR116613]

2024-09-20 Thread David Malcolm via Gcc-cvs
https://gcc.gnu.org/g:725231e16768bd9f16169b3b7e4cb5a98b251d1c

commit r15-3750-g725231e16768bd9f16169b3b7e4cb5a98b251d1c
Author: David Malcolm 
Date:   Fri Sep 20 18:51:55 2024 -0400

diagnostics: isolate SARIF output's pretty_printer [PR116613]

Add an m_printer to sarif_builder and use throughout, rather than
using the context's printer.  For now this is the same printer, but
eventually this should help with transitioning to multiple output sinks.

No functional change intended.

gcc/ChangeLog:
PR other/116613
* diagnostic-format-sarif.cc (sarif_builder::m_printer): New
field.
(sarif_invocation::add_notification_for_ice): Drop context param.
(sarif_invocation::prepare_to_flush): Convert param from context
to builder.
(sarif_result::on_nested_diagnostic): Drop context param.  Use
builder's printer.
(sarif_result::on_diagram): Drop context param.
(sarif_ice_notification::sarif_ice_notification): Drop context
param.  Use builder's printer.
(sarif_builder::sarif_builder): Initialize m_printer.
(sarif_builder::on_report_diagnostic): Drop context param.  Use
builder's printer.
(sarif_builder::emit_diagram): Drop context param.
(sarif_builder::flush_to_object): Use this rather than context
for call to prepare_to_flush.
(sarif_builder::make_result_object): Drop context param.  Use
builder's printer.
(sarif_builder::make_reporting_descriptor_object_for_warning):
Drop context param.
(sarif_builder::make_message_object_for_diagram): Likewise.
Use builder's printer.
(sarif_output_format::on_report_diagnostic): Drop context param
from call to sarif_builder::on_report_diagnostic.
(sarif_output_format::on_diagram): Drop context param from call to
sarif_builder::emit_diagram.
* diagnostic.h (diagnostic_conetxt::get_client_data_hooks): Make 
const.

Signed-off-by: David Malcolm 

Diff:
---
 gcc/diagnostic-format-sarif.cc | 116 ++---
 gcc/diagnostic.h   |   2 +-
 2 files changed, 51 insertions(+), 67 deletions(-)

diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc
index eda67a6f6583..6cd18cef6c89 100644
--- a/gcc/diagnostic-format-sarif.cc
+++ b/gcc/diagnostic-format-sarif.cc
@@ -166,10 +166,9 @@ public:
   sarif_invocation (sarif_builder &builder,
const char * const *original_argv);
 
-  void add_notification_for_ice (diagnostic_context &context,
-const diagnostic_info &diagnostic,
+  void add_notification_for_ice (const diagnostic_info &diagnostic,
 sarif_builder &builder);
-  void prepare_to_flush (diagnostic_context &context);
+  void prepare_to_flush (sarif_builder &builder);
 
 private:
   std::unique_ptr m_notifications_arr;
@@ -395,12 +394,10 @@ public:
   unsigned get_index_within_parent () const { return m_idx_within_parent; }
 
   void
-  on_nested_diagnostic (diagnostic_context &context,
-   const diagnostic_info &diagnostic,
+  on_nested_diagnostic (const diagnostic_info &diagnostic,
diagnostic_t orig_diag_kind,
sarif_builder &builder);
-  void on_diagram (diagnostic_context &context,
-  const diagnostic_diagram &diagram,
+  void on_diagram (const diagnostic_diagram &diagram,
   sarif_builder &builder);
 
   void
@@ -583,8 +580,7 @@ class sarif_replacement : public sarif_object {};
 class sarif_ice_notification : public sarif_location_manager
 {
 public:
-  sarif_ice_notification (diagnostic_context &context,
- const diagnostic_info &diagnostic,
+  sarif_ice_notification (const diagnostic_info &diagnostic,
  sarif_builder &builder);
 
   void
@@ -654,11 +650,9 @@ public:
 const char *main_input_filename_,
 bool formatted);
 
-  void on_report_diagnostic (diagnostic_context &context,
-const diagnostic_info &diagnostic,
+  void on_report_diagnostic (const diagnostic_info &diagnostic,
 diagnostic_t orig_diag_kind);
-  void emit_diagram (diagnostic_context &context,
-const diagnostic_diagram &diagram);
+  void emit_diagram (const diagnostic_diagram &diagram);
   void end_group ();
 
   std::unique_ptr take_current_result ()
@@ -685,8 +679,7 @@ public:
   std::unique_ptr
   make_message_object (const char *msg) const;
   std::unique_ptr
-  make_message_object_for_diagram (diagnostic_context &context,
-  const diagnostic_diagram &diagram);
+  make_message_object_for_diagram (const diagnostic_diagram &dia

[gcc r15-3748] analyzer: remove redundant 'pp' [PR116613]

2024-09-20 Thread David Malcolm via Gcc-cvs
https://gcc.gnu.org/g:37604edf37b3799e0203ede4dfa60d547322fdfc

commit r15-3748-g37604edf37b3799e0203ede4dfa60d547322fdfc
Author: David Malcolm 
Date:   Fri Sep 20 18:51:55 2024 -0400

analyzer: remove redundant 'pp' [PR116613]

diagnostic_manager::emit_saved_diagnostic makes a useless clone
of global_dc->m_printer; remove it.

No functional change intended.

gcc/analyzer/ChangeLog:
PR other/116613
* diagnostic-manager.cc (diagnostic_manager::emit_saved_diagnostic):
Remove remove redundant 'pp'.

Signed-off-by: David Malcolm 

Diff:
---
 gcc/analyzer/diagnostic-manager.cc | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/gcc/analyzer/diagnostic-manager.cc 
b/gcc/analyzer/diagnostic-manager.cc
index 4a5a95136156..2363ae5df19c 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -1561,8 +1561,6 @@ diagnostic_manager::emit_saved_diagnostic (const 
exploded_graph &eg,
sd.get_index (), sd.m_d->get_kind (), sd.m_snode->m_index);
   log ("num dupes: %i", sd.get_num_dupes ());
 
-  pretty_printer *pp = global_dc->m_printer->clone ();
-
   const exploded_path *epath = sd.get_best_epath ();
   gcc_assert (epath);
 
@@ -1645,7 +1643,6 @@ diagnostic_manager::emit_saved_diagnostic (const 
exploded_graph &eg,
  free (filename);
}
 }
-  delete pp;
 }
 
 /* Emit a "path" of events to EMISSION_PATH describing the exploded path


[gcc r12-10718] Fix small thinko in IPA mod/ref pass

2024-09-20 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:0f32c312508f11d2c6e9e363fa5b88d69eb9252c

commit r12-10718-g0f32c312508f11d2c6e9e363fa5b88d69eb9252c
Author: Eric Botcazou 
Date:   Fri Sep 20 12:32:13 2024 +0200

Fix small thinko in IPA mod/ref pass

When a memory copy operation is analyzed by analyze_ssa_name, if both the
load and store are made through the same SSA name, the store is overlooked.

gcc/
* ipa-modref.cc (modref_eaf_analysis::analyze_ssa_name): Always
process both the load and the store of a memory copy operation.

gcc/testsuite/
* gcc.dg/ipa/modref-4.c: New test.

Diff:
---
 gcc/ipa-modref.cc   |  3 ++-
 gcc/testsuite/gcc.dg/ipa/modref-4.c | 34 ++
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index d41de9c59c12..c3e3fd50d173 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -2599,8 +2599,9 @@ modref_eaf_analysis::analyze_ssa_name (tree name, bool 
deferred)
 is used arbitrarily.  */
  if (memory_access_to (gimple_assign_rhs1 (assign), name))
m_lattice[index].merge (deref_flags (0, false));
+
  /* Handle *name = *exp.  */
- else if (memory_access_to (gimple_assign_lhs (assign), name))
+ if (memory_access_to (gimple_assign_lhs (assign), name))
m_lattice[index].merge_direct_store ();
}
  /* Handle lhs = *name.  */
diff --git a/gcc/testsuite/gcc.dg/ipa/modref-4.c 
b/gcc/testsuite/gcc.dg/ipa/modref-4.c
new file mode 100644
index ..71ed1ca5f5b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/modref-4.c
@@ -0,0 +1,34 @@
+/* { dg-options "-O"  } */
+/* { dg-do run } */
+
+static __attribute__((noipa)) int foo (void)
+{
+  return 1;
+}
+
+int main (void)
+{
+  struct S { int a; int b; };
+  struct T { struct S s; };
+
+  struct T t = { { 0, 0 } };
+  struct T u;
+
+  __attribute__((noinline)) void bar (void)
+  {
+if (foo ())
+  {
+   u = t;
+/* OK with u.s.a = 0; */
+  }
+  }
+
+  u.s.a = 1;
+
+  bar ();
+
+  if (u.s.a != 0)
+__builtin_abort ();
+
+  return 0;
+}


[gcc r15-3738] testsuite: Update commandline for PR116628.c to use neoverse-v2 [PR116628]

2024-09-20 Thread Tamar Christina via Gcc-cvs
https://gcc.gnu.org/g:0189ab205aa86b8e67ae982294f0fe58aa9c4774

commit r15-3738-g0189ab205aa86b8e67ae982294f0fe58aa9c4774
Author: Tamar Christina 
Date:   Fri Sep 20 17:01:39 2024 +0100

testsuite: Update commandline for PR116628.c to use neoverse-v2 [PR116628]

The testcase for this tests needs Neoverse V2 to be used
since due to costing the other cost models don't pick this
particular SVE mode.

committed as obvious.

Thanks,
Tamar

gcc/testsuite/ChangeLog:

PR tree-optimization/116628
* gcc.dg/vect/pr116628.c: Update cmdline.

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr116628.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr116628.c 
b/gcc/testsuite/gcc.dg/vect/pr116628.c
index 4068c657ac55..a38ffb33365a 100644
--- a/gcc/testsuite/gcc.dg/vect/pr116628.c
+++ b/gcc/testsuite/gcc.dg/vect/pr116628.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target vect_float } */
 /* { dg-require-effective-target vect_masked_store } */
-/* { dg-additional-options "-Ofast -march=armv9-a" { target aarch64-*-* } } */
+/* { dg-additional-options "-Ofast -mcpu=neoverse-v2" { target aarch64-*-* } } 
*/
 
 typedef float c;
 c a[2000], b[0];


[gcc r15-3739] AArch64: Define VECTOR_STORE_FLAG_VALUE.

2024-09-20 Thread Tamar Christina via Gcc-cvs
https://gcc.gnu.org/g:33cb400b2e7266e65030869254366217e51494aa

commit r15-3739-g33cb400b2e7266e65030869254366217e51494aa
Author: Tamar Christina 
Date:   Fri Sep 20 17:03:54 2024 +0100

AArch64: Define VECTOR_STORE_FLAG_VALUE.

This defines VECTOR_STORE_FLAG_VALUE to CONST1_RTX for AArch64
so we simplify vector comparisons in AArch64.

With this enabled

res:
moviv0.4s, 0
cmeqv0.4s, v0.4s, v0.4s
ret

is simplified to:

res:
mvniv0.4s, 0
ret

gcc/ChangeLog:

* config/aarch64/aarch64.h (VECTOR_STORE_FLAG_VALUE): New.

gcc/testsuite/ChangeLog:

* gcc.dg/rtl/aarch64/vector-eq.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64.h | 10 ++
 gcc/testsuite/gcc.dg/rtl/aarch64/vector-eq.c | 29 
 2 files changed, 39 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 2dfb999bea53..a99e7bb6c477 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -156,6 +156,16 @@
 
 #define PCC_BITFIELD_TYPE_MATTERS  1
 
+/* Use the same RTL truth representation for vector elements as we do
+   for scalars.  This maintains the property that a comparison like
+   eq:V4SI is a composition of 4 individual eq:SIs, just like plus:V4SI
+   is a composition of 4 individual plus:SIs.
+
+   This means that Advanced SIMD comparisons are represented in RTL as
+   (neg (op ...)).  */
+
+#define VECTOR_STORE_FLAG_VALUE(MODE) CONST1_RTX (GET_MODE_INNER (MODE))
+
 #ifndef USED_FOR_TARGET
 
 /* Define an enum of all features (ISA modes, architectures and extensions).
diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/vector-eq.c 
b/gcc/testsuite/gcc.dg/rtl/aarch64/vector-eq.c
new file mode 100644
index ..8e0d7773620c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/aarch64/vector-eq.c
@@ -0,0 +1,29 @@
+/* { dg-do compile { target aarch64-*-* } } */
+/* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** foo:
+** mvniv0.4s, 0
+** ret
+*/
+__Uint32x4_t __RTL (startwith ("vregs")) foo (void)
+{
+(function "foo"
+  (insn-chain
+(block 2
+  (edge-from entry (flags "FALLTHRU"))
+  (cnote 1 [bb 2] NOTE_INSN_BASIC_BLOCK)
+  (cnote 2 NOTE_INSN_FUNCTION_BEG)
+  (cinsn 3 (set (reg:V4SI <0>) (const_vector:V4SI [(const_int 0) 
(const_int 0) (const_int 0) (const_int 0)])))
+  (cinsn 4 (set (reg:V4SI <1>) (reg:V4SI <0>)))
+  (cinsn 5 (set (reg:V4SI <2>)
+   (neg:V4SI (eq:V4SI (reg:V4SI <0>) (reg:V4SI <1>)
+  (cinsn 6 (set (reg:V4SI v0) (reg:V4SI <2>)))
+  (edge-to exit (flags "FALLTHRU"))
+)
+  )
+  (crtl (return_rtx (reg/i:V4SI v0)))
+)
+}
+


[gcc(refs/users/aoliva/heads/testme)] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
https://gcc.gnu.org/g:f88b4c43a2a478f5a7bc9b1185a9f0eec519f9b4

commit f88b4c43a2a478f5a7bc9b1185a9f0eec519f9b4
Author: Alexandre Oliva 
Date:   Thu Sep 19 06:43:22 2024 -0300

adjust probs after modified ifcombine

Diff:
---
 gcc/fold-const.h |  10 +
 gcc/testsuite/gcc.dg/field-merge-7.c |  23 ++
 gcc/tree-ssa-ifcombine.cc| 486 ---
 3 files changed, 427 insertions(+), 92 deletions(-)

diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index 3e3998b57b04..136764f5c7eb 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -258,6 +258,16 @@ extern void clear_type_padding_in_mask (tree, unsigned 
char *);
 extern bool clear_padding_type_may_have_padding_p (tree);
 extern bool arith_overflowed_p (enum tree_code, const_tree, const_tree,
const_tree);
+extern tree fold_truth_andor_maybe_separate (location_t loc,
+enum tree_code code,
+tree truth_type,
+enum tree_code lcode,
+tree ll_arg,
+tree lr_arg,
+enum tree_code rcode,
+tree rl_arg,
+tree rr_arg,
+tree *separatep);
 
 /* Class used to compare gimple operands.  */
 
diff --git a/gcc/testsuite/gcc.dg/field-merge-7.c 
b/gcc/testsuite/gcc.dg/field-merge-7.c
new file mode 100644
index ..728a29b6fafa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/field-merge-7.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ifcombine-details" } */
+
+/* Check that the third compare won't be combined with the first one.  */
+
+struct s {
+  char a, b;
+  int p;
+};
+
+struct s a = { 0, 0, 0 };
+struct s b = { 0, 0, 0 };
+
+int f () {
+  return (a.a != b.a || (a.p != b.p && a.b != b.b));
+}
+
+int g () {
+  return (a.a == b.a && (a.p == b.p || a.b == b.b));
+}
+
+/* { dg-final { scan-tree-dump-not "optimizing" "ifcombine" } } */
+/* { dg-final { scan-tree-dump-not "BIT_FIELD_REF" "ifcombine" } } */
diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index 79ccc70b2678..33e30d9f4f58 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa.h"
 #include "attribs.h"
 #include "asan.h"
+#include "bitmap.h"
 
 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
 #define LOGICAL_OP_NON_SHORT_CIRCUIT \
@@ -49,6 +50,28 @@ along with GCC; see the file COPYING3.  If not see
 false) >= 2)
 #endif
 
+/* Return TRUE iff COND is NULL, or the condition in it is constant.  */
+
+static bool
+constant_condition_p (gcond *cond)
+{
+  if (!cond)
+return true;
+
+  return (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
+ && CONSTANT_CLASS_P (gimple_cond_rhs (cond)));
+}
+
+/* Return FALSE iff the condition in the COND stmt that ends COND_BB is not
+   constant.  */
+
+static bool
+constant_condition_p (basic_block cond_bb)
+{
+  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
+  return constant_condition_p (cond);
+}
+
 /* This pass combines COND_EXPRs to simplify control flow.  It
currently recognizes bit tests and comparisons in chains that
represent logical and or logical or of two COND_EXPRs.
@@ -107,15 +130,38 @@ recognize_if_then_else (basic_block cond_bb,
   if (!*else_bb)
 *else_bb = e->dest;
 
-  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
-  if (!cond)
-return false;
+  return true;
+}
+
+/* Same as recognize_if_then_else, but check that the condition is not
+   constant.  It is not useful to combine constant conditions.  */
 
-  if (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
-  && CONSTANT_CLASS_P (gimple_cond_rhs (cond)))
+static bool
+recognize_if_then_else_nc (basic_block cond_bb,
+  basic_block *then_bb, basic_block *else_bb)
+{
+  return recognize_if_then_else (cond_bb, then_bb, else_bb)
+&& !constant_condition_p (cond_bb);
+}
+
+/* Same as recognize_if_then_else, but don't associate the blocks with then and
+   else, check both possibilities.  */
+
+static bool
+recognize_if_succs (basic_block cond_bb,
+   basic_block succ1, basic_block succ2)
+{
+  basic_block t, e;
+
+  if (EDGE_COUNT (cond_bb->succs) != 2)
 return false;
 
-  return true;
+  /* Find both succs.  */
+  t = EDGE_SUCC (cond_bb, 0)->dest;
+  e = EDGE_SUCC (cond_bb, 1)->dest;
+
+  return ((t == succ1 && e == succ2)
+ || (t == succ2 && e == succ1));
 }
 
 /* Verify if the basic block BB does not have side-effects.  Return
@@ -364,14 +410,28 @@ recognize_bits_test (gcond *cond, tree *name, tree *bits, 
bool inv)
 }
 
 
-/* Update profile after code in outer_cond_bb was adjusted so
-   out

[gcc/aoliva/heads/testme] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
The branch 'aoliva/heads/testme' was updated to point to:

 f88b4c43a2a4... adjust probs after modified ifcombine

It previously pointed to:

 7660c0400ee5... adjust probs after modified ifcombine

Diff:

!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
---

  7660c04... adjust probs after modified ifcombine


Summary of changes (added commits):
---

  f88b4c4... adjust probs after modified ifcombine


[gcc r15-3754] libstdc++: fix C header include guards

2024-09-20 Thread Jason Merrill via Libstdc++-cvs
https://gcc.gnu.org/g:2484ba167e1c4a52d4989b71e1f5d4d27755500f

commit r15-3754-g2484ba167e1c4a52d4989b71e1f5d4d27755500f
Author: Jason Merrill 
Date:   Mon Sep 9 12:35:37 2024 -0400

libstdc++: fix C header include guards

Ever since the c_global and c_compatibility directories were added in
r122533, the include guards have been oddly late in the files, with no
comment about why that might be either in the commit message or the files
themselves.  I don't see any justification for this; it seems like a
scripting error in creating these files based on the ones in include/c.

libstdc++-v3/ChangeLog:

* include/c_compatibility/ctype.h
* include/c_compatibility/errno.h
* include/c_compatibility/float.h
* include/c_compatibility/iso646.h
* include/c_compatibility/limits.h
* include/c_compatibility/locale.h
* include/c_compatibility/setjmp.h
* include/c_compatibility/signal.h
* include/c_compatibility/stdarg.h
* include/c_compatibility/stdbool.h
* include/c_compatibility/stddef.h
* include/c_compatibility/stdio.h
* include/c_compatibility/string.h
* include/c_compatibility/tgmath.h
* include/c_compatibility/time.h
* include/c_compatibility/uchar.h
* include/c_compatibility/wchar.h
* include/c_compatibility/wctype.h
* include/c_global/ccomplex
* include/c_global/cctype
* include/c_global/cerrno
* include/c_global/cfloat
* include/c_global/climits
* include/c_global/clocale
* include/c_global/cmath
* include/c_global/csetjmp
* include/c_global/csignal
* include/c_global/cstdalign
* include/c_global/cstdarg
* include/c_global/cstdbool
* include/c_global/cstdio
* include/c_global/cstdlib
* include/c_global/cstring
* include/c_global/ctgmath
* include/c_global/ctime
* include/c_global/cwchar
* include/c_global/cwctype: Move header guard before #includes.

Diff:
---
 libstdc++-v3/include/c_compatibility/ctype.h   | 4 ++--
 libstdc++-v3/include/c_compatibility/errno.h   | 4 ++--
 libstdc++-v3/include/c_compatibility/float.h   | 4 ++--
 libstdc++-v3/include/c_compatibility/iso646.h  | 4 ++--
 libstdc++-v3/include/c_compatibility/limits.h  | 4 ++--
 libstdc++-v3/include/c_compatibility/locale.h  | 4 ++--
 libstdc++-v3/include/c_compatibility/setjmp.h  | 4 ++--
 libstdc++-v3/include/c_compatibility/signal.h  | 4 ++--
 libstdc++-v3/include/c_compatibility/stdarg.h  | 4 ++--
 libstdc++-v3/include/c_compatibility/stdbool.h | 6 +++---
 libstdc++-v3/include/c_compatibility/stddef.h  | 4 ++--
 libstdc++-v3/include/c_compatibility/stdio.h   | 4 ++--
 libstdc++-v3/include/c_compatibility/string.h  | 4 ++--
 libstdc++-v3/include/c_compatibility/tgmath.h  | 6 +++---
 libstdc++-v3/include/c_compatibility/time.h| 4 ++--
 libstdc++-v3/include/c_compatibility/uchar.h   | 4 ++--
 libstdc++-v3/include/c_compatibility/wchar.h   | 4 ++--
 libstdc++-v3/include/c_compatibility/wctype.h  | 4 ++--
 libstdc++-v3/include/c_global/ccomplex | 4 ++--
 libstdc++-v3/include/c_global/cctype   | 6 +++---
 libstdc++-v3/include/c_global/cerrno   | 6 +++---
 libstdc++-v3/include/c_global/cfloat   | 6 +++---
 libstdc++-v3/include/c_global/climits  | 6 +++---
 libstdc++-v3/include/c_global/clocale  | 6 +++---
 libstdc++-v3/include/c_global/cmath| 6 +++---
 libstdc++-v3/include/c_global/csetjmp  | 6 +++---
 libstdc++-v3/include/c_global/csignal  | 6 +++---
 libstdc++-v3/include/c_global/cstdalign| 7 +++
 libstdc++-v3/include/c_global/cstdarg  | 6 +++---
 libstdc++-v3/include/c_global/cstdbool | 7 +++
 libstdc++-v3/include/c_global/cstdio   | 6 +++---
 libstdc++-v3/include/c_global/cstdlib  | 6 +++---
 libstdc++-v3/include/c_global/cstring  | 6 +++---
 libstdc++-v3/include/c_global/ctgmath  | 3 +--
 libstdc++-v3/include/c_global/ctime| 6 +++---
 libstdc++-v3/include/c_global/cwchar   | 6 +++---
 libstdc++-v3/include/c_global/cwctype  | 6 +++---
 37 files changed, 92 insertions(+), 95 deletions(-)

diff --git a/libstdc++-v3/include/c_compatibility/ctype.h 
b/libstdc++-v3/include/c_compatibility/ctype.h
index 7b57a4d118a3..d975dff15295 100644
--- a/libstdc++-v3/include/c_compatibility/ctype.h
+++ b/libstdc++-v3/include/c_compatibility/ctype.h
@@ -26,11 +26,11 @@
  *  This is a Standard C++ Library header.
  */
 
-#include 
-
 #ifndef _GLIBCXX_CTYPE_H
 #define _GLIBCXX_CTYPE_H 1
 
+#include 
+
 #ifdef _GLIBCXX_NAMESPACE_C
 using std::isalnum;
 using std::isalpha;
diff --git a/libstdc++-v3/include/c_compatibility/errno.

[gcc(refs/users/aoliva/heads/testme)] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
https://gcc.gnu.org/g:9919ba13180b34d127c45b97117bae0b9036dc13

commit 9919ba13180b34d127c45b97117bae0b9036dc13
Author: Alexandre Oliva 
Date:   Thu Sep 19 06:43:22 2024 -0300

adjust probs after modified ifcombine

Diff:
---
 gcc/tree-ssa-ifcombine.cc | 403 +-
 1 file changed, 323 insertions(+), 80 deletions(-)

diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index 79ccc70b2678..79f89570acb6 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa.h"
 #include "attribs.h"
 #include "asan.h"
+#include "bitmap.h"
 
 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
 #define LOGICAL_OP_NON_SHORT_CIRCUIT \
@@ -49,6 +50,28 @@ along with GCC; see the file COPYING3.  If not see
 false) >= 2)
 #endif
 
+/* Return TRUE iff COND is NULL, or the condition in it is constant.  */
+
+static bool
+constant_condition_p (gcond *cond)
+{
+  if (!cond)
+return true;
+
+  return (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
+ && CONSTANT_CLASS_P (gimple_cond_rhs (cond)));
+}
+
+/* Return FALSE iff the condition in the COND stmt that ends COND_BB is not
+   constant.  */
+
+static bool
+constant_condition_p (basic_block cond_bb)
+{
+  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
+  return constant_condition_p (cond);
+}
+
 /* This pass combines COND_EXPRs to simplify control flow.  It
currently recognizes bit tests and comparisons in chains that
represent logical and or logical or of two COND_EXPRs.
@@ -107,12 +130,7 @@ recognize_if_then_else (basic_block cond_bb,
   if (!*else_bb)
 *else_bb = e->dest;
 
-  gcond *cond = safe_dyn_cast  (*gsi_last_bb (cond_bb));
-  if (!cond)
-return false;
-
-  if (CONSTANT_CLASS_P (gimple_cond_lhs (cond))
-  && CONSTANT_CLASS_P (gimple_cond_rhs (cond)))
+  if (constant_condition_p (cond_bb))
 return false;
 
   return true;
@@ -364,14 +382,27 @@ recognize_bits_test (gcond *cond, tree *name, tree *bits, 
bool inv)
 }
 
 
-/* Update profile after code in outer_cond_bb was adjusted so
-   outer_cond_bb has no condition.  */
+/* Update profile after code in either outer_cond_bb or inner_cond_bb was
+   adjusted so that it has no condition.  */
 
 static void
 update_profile_after_ifcombine (basic_block inner_cond_bb,
basic_block outer_cond_bb)
 {
-  edge outer_to_inner = find_edge (outer_cond_bb, inner_cond_bb);
+  /* In the following we assume that inner_cond_bb has single predecessor.  */
+  gcc_assert (single_pred_p (inner_cond_bb));
+
+  basic_block outer_to_inner_bb = inner_cond_bb;
+  profile_probability prob = profile_probability::always ();
+  for (basic_block parent = single_pred (outer_to_inner_bb);
+   parent != outer_cond_bb;
+   parent = single_pred (outer_to_inner_bb))
+{
+  prob *= find_edge (parent, outer_to_inner_bb)->probability;
+  outer_to_inner_bb = parent;
+}
+
+  edge outer_to_inner = find_edge (outer_cond_bb, outer_to_inner_bb);
   edge outer2 = (EDGE_SUCC (outer_cond_bb, 0) == outer_to_inner
 ? EDGE_SUCC (outer_cond_bb, 1)
 : EDGE_SUCC (outer_cond_bb, 0));
@@ -382,29 +413,62 @@ update_profile_after_ifcombine (basic_block inner_cond_bb,
 std::swap (inner_taken, inner_not_taken);
   gcc_assert (inner_taken->dest == outer2->dest);
 
-  /* In the following we assume that inner_cond_bb has single predecessor.  */
-  gcc_assert (single_pred_p (inner_cond_bb));
+  if (constant_condition_p (outer_cond_bb))
+{
+  gcc_checking_assert (outer_to_inner_bb == inner_cond_bb);
 
-  /* Path outer_cond_bb->(outer2) needs to be merged into path
- outer_cond_bb->(outer_to_inner)->inner_cond_bb->(inner_taken)
- and probability of inner_not_taken updated.  */
+  /* Path outer_cond_bb->(outer2) needs to be merged into path
+outer_cond_bb->(outer_to_inner)->inner_cond_bb->(inner_taken)
+and probability of inner_not_taken updated.  */
 
-  inner_cond_bb->count = outer_cond_bb->count;
+  inner_cond_bb->count = outer_cond_bb->count;
 
-  /* Handle special case where inner_taken probability is always. In this case
- we know that the overall outcome will be always as well, but combining
- probabilities will be conservative because it does not know that
- outer2->probability is inverse of outer_to_inner->probability.  */
-  if (inner_taken->probability == profile_probability::always ())
-;
-  else
-inner_taken->probability = outer2->probability + 
outer_to_inner->probability
-  * inner_taken->probability;
-  inner_not_taken->probability = profile_probability::always ()
-- inner_taken->probability;
+  /* Handle special case where inner_taken probability is always. In this
+case we know that the overall outcome will be always as well, but
+combining probabilities

[gcc/aoliva/heads/testme] adjust probs after modified ifcombine

2024-09-20 Thread Alexandre Oliva via Gcc-cvs
The branch 'aoliva/heads/testme' was updated to point to:

 9919ba13180b... adjust probs after modified ifcombine

It previously pointed to:

 90e42ef87e8f... adjust probs after modified ifcombine

Diff:

!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
---

  90e42ef... adjust probs after modified ifcombine


Summary of changes (added commits):
---

  9919ba1... adjust probs after modified ifcombine


[gcc r14-10695] Fortran: fix ICE in gfc_create_module_variable [PR100273]

2024-09-20 Thread Harald Anlauf via Gcc-cvs
https://gcc.gnu.org/g:cf8f6aa2a0e4378cec0f9bdbde8cd9a2ea3fb3e5

commit r14-10695-gcf8f6aa2a0e4378cec0f9bdbde8cd9a2ea3fb3e5
Author: Harald Anlauf 
Date:   Thu Sep 5 21:30:25 2024 +0200

Fortran: fix ICE in gfc_create_module_variable [PR100273]

gcc/fortran/ChangeLog:

PR fortran/100273
* trans-decl.cc (gfc_create_module_variable): Handle module
variable also when it is needed for the result specification
of a contained function.

gcc/testsuite/ChangeLog:

PR fortran/100273
* gfortran.dg/pr100273.f90: New test.

(cherry picked from commit 1f462b5072a5e82c35921f7e3bdf3959c4a49dc9)

Diff:
---
 gcc/fortran/trans-decl.cc  |  3 ++-
 gcc/testsuite/gfortran.dg/pr100273.f90 | 26 ++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 1a319b27449b..7a38151f 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -5459,7 +5459,8 @@ gfc_create_module_variable (gfc_symbol * sym)
   /* Create the variable.  */
   pushdecl (decl);
   gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE
- || (sym->ns->parent->proc_name->attr.flavor == FL_MODULE
+ || ((sym->ns->parent->proc_name->attr.flavor == FL_MODULE
+  || sym->ns->parent->proc_name->attr.flavor == FL_PROCEDURE)
  && sym->fn_result_spec));
   DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
   rest_of_decl_compilation (decl, 1, 0);
diff --git a/gcc/testsuite/gfortran.dg/pr100273.f90 
b/gcc/testsuite/gfortran.dg/pr100273.f90
new file mode 100644
index ..f71947ad802d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr100273.f90
@@ -0,0 +1,26 @@
+! { dg-do compile }
+! PR fortran/100273 - ICE in gfc_create_module_variable
+!
+! Contributed by G.Steinmetz
+
+module m
+  implicit none
+contains
+  character(4) function g(k)
+integer :: k
+g = f(k)
+  contains
+function f(n)
+  character(3), parameter :: a(2) = ['1  ', '123']
+  integer :: n
+  character(len_trim(a(n))) :: f
+  f = 'abc'
+end
+  end
+end
+program p
+  use m 
+  implicit none
+  print *, '>>' // g(1) // '<<'
+  print *, '>>' // g(2) // '<<'
+end


[gcc r15-3744] c++: CWG 2789 and reversed operator candidates

2024-09-20 Thread Patrick Palka via Gcc-cvs
https://gcc.gnu.org/g:1f70503232d4183b4b58f2910c460569d05907b9

commit r15-3744-g1f70503232d4183b4b58f2910c460569d05907b9
Author: Patrick Palka 
Date:   Fri Sep 20 15:41:42 2024 -0400

c++: CWG 2789 and reversed operator candidates

As a follow-up to r15-3741-gee3efe06c9c49c, which was specifically
concerned with usings, it seems the CWG 2789 refinement should also
compare contexts of a reversed vs non-reversed (member) candidate
during operator overload resolution.

DR 2789

gcc/cp/ChangeLog:

* call.cc (cand_parms_match): Check for matching class contexts
even in the reversed case.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-memfun4.C: Adjust expected result
involving reversed candidate.

Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/call.cc| 11 +++
 gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C |  6 +++---
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index f2ce50857ece..70783baac242 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -12865,10 +12865,6 @@ cand_parms_match (z_candidate *c1, z_candidate *c2, 
pmatch match_kind)
}
 }
 
-  else if (reversed)
-return (reversed_match (c1, c2)
-   && reversed_match (c2, c1));
-
   tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn1));
   tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (fn2));
 
@@ -12880,6 +12876,10 @@ cand_parms_match (z_candidate *c1, z_candidate *c2, 
pmatch match_kind)
   if (base1 != base2)
return false;
 
+  if (reversed)
+   return (reversed_match (c1, c2)
+   && reversed_match (c2, c1));
+
   /* Use object_parms_correspond to simplify comparing iobj/xobj/static
 member functions.  */
   if (!object_parms_correspond (fn1, fn2, base1))
@@ -12897,6 +12897,9 @@ cand_parms_match (z_candidate *c1, z_candidate *c2, 
pmatch match_kind)
   parms1 = skip_parms (fn1, parms1);
   parms2 = skip_parms (fn2, parms2);
 }
+  else if (reversed)
+return (reversed_match (c1, c2)
+   && reversed_match (c2, c1));
   return compparms (parms1, parms2);
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C
index cf7f13c007d1..d849e9129a3b 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-memfun4.C
@@ -91,7 +91,7 @@ namespace N1 {
 
   A<> a;
   B<> b;
-  // when comparing the A op== to the reversed B op==, we compare them in
-  // reverse order, so they match, and we choose the more constrained.
-  static_assert (a == b);
+  // A op== and B op== are defined in different classes so constraints
+  // aren't considered, and the tie is broken via reversedness.
+  static_assert (!(a == b));
 }


[gcc r15-3736] c++, coroutines: Rework the ramp codegen.

2024-09-20 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:cbe1b1c6c7408b20aa899c5e9c607c706cee8ca0

commit r15-3736-gcbe1b1c6c7408b20aa899c5e9c607c706cee8ca0
Author: Iain Sandoe 
Date:   Tue Aug 27 16:38:10 2024 +0100

c++, coroutines: Rework the ramp codegen.

Now that we have separated the codegen of the ramp, actor and
destroy functions, we no longer need to manage the scopes for
variables manually.

This introduces a helper function that allows us to build a
local var with a DECL_VALUE_EXPR that relates to the coroutine
state frame entry.

This fixes a latent issue where we would generate guard vars
when exceptions were disabled.

gcc/cp/ChangeLog:

* coroutines.cc (coro_build_artificial_var_with_dve): New.
(coro_build_and_push_artificial_var): New.
(coro_build_and_push_artificial_var_with_dve): New.
(analyze_fn_parms): Ensure that frame entries cannot clash
with local variables.
(build_coroutine_frame_delete_expr): Amend comment.
(cp_coroutine_transform::build_ramp_function): Rework to
avoid manual management of variables and scopes.

Signed-off-by: Iain Sandoe 

Diff:
---
 gcc/cp/coroutines.cc | 288 +++
 1 file changed, 150 insertions(+), 138 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 002d575f3324..70c9094d1d19 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1726,6 +1726,8 @@ coro_build_artificial_var (location_t loc, tree name, 
tree type, tree ctx,
   return res;
 }
 
+/* As above, except allowing the name to be a string.  */
+
 static tree
 coro_build_artificial_var (location_t loc, const char *name, tree type,
   tree ctx, tree init)
@@ -1734,6 +1736,51 @@ coro_build_artificial_var (location_t loc, const char 
*name, tree type,
type, ctx, init);
 }
 
+/* As for coro_build_artificial_var, except that we push this decl into
+   the current binding scope and add the decl_expr.  */
+
+static tree
+coro_build_and_push_artificial_var (location_t loc, const char *name,
+   tree type, tree ctx, tree init)
+{
+  tree v = coro_build_artificial_var (loc, name, type, ctx, init);
+  v = pushdecl (v);
+  add_decl_expr (v);
+  return v;
+}
+
+/* Build a var NAME of TYPE in CTX and with INIT; add a DECL_VALUE_EXPR that
+   refers to BASE.FIELD.  */
+
+static tree
+coro_build_artificial_var_with_dve (location_t loc, tree name, tree type,
+   tree ctx, tree init, tree base,
+   tree field = NULL_TREE)
+{
+  tree v = coro_build_artificial_var (loc, name, type, ctx, init);
+  if (field == NULL_TREE)
+field = name;
+  tree dve  = coro_build_frame_access_expr (base, field, true,
+   tf_warning_or_error);
+  SET_DECL_VALUE_EXPR (v, dve);
+  DECL_HAS_VALUE_EXPR_P (v) = true;
+  return v;
+}
+
+/* As for coro_build_artificial_var_with_dve, but push into the current binding
+   scope and add the decl_expr.  */
+
+static tree
+coro_build_and_push_artificial_var_with_dve (location_t loc, tree name,
+tree type, tree ctx, tree init,
+tree base, tree field = NULL_TREE)
+{
+  tree v = coro_build_artificial_var_with_dve (loc, name, type, ctx, init,
+  base, field);
+  v = pushdecl (v);
+  add_decl_expr (v);
+  return v;
+}
 
 /*  2. Create a named label in the specified context.  */
 
@@ -3849,8 +3896,10 @@ analyze_fn_parms (tree orig, hash_map 
*param_uses)
  when we see uses.  */
   bool lambda_p = LAMBDA_FUNCTION_P (orig);
 
-  unsigned no_name_parm = 0;
-  for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; arg = DECL_CHAIN (arg))
+  /* Count the param copies from 1 as per the std.  */
+  unsigned parm_num = 1;
+  for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
+   ++parm_num, arg = DECL_CHAIN (arg))
 {
   bool existed;
   param_info &parm = param_uses->get_or_insert (arg, &existed);
@@ -3885,16 +3934,16 @@ analyze_fn_parms (tree orig, hash_map 
*param_uses)
   tree name = DECL_NAME (arg);
   if (!name)
{
- char *buf = xasprintf ("_Coro_unnamed_parm_%d", no_name_parm++);
+ char *buf = xasprintf ("_Coro_q%u___unnamed", parm_num);
  name = get_identifier (buf);
  free (buf);
}
   parm.field_id = name;
-
   if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (parm.frame_type))
{
- char *buf = xasprintf ("%s%s_live", DECL_NAME (arg) ? "_Coro_" : "",
-IDENTIFIER_POINTER (name));
+ char *buf = xasprintf ("_Coro_q%u_%s_live", parm_num,
+DECL_NAME (arg) ? IDENTIFIER_POINTER (name)
+   

[gcc r15-3737] Darwin: Allow for as versions that need '-' for std in.

2024-09-20 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:33ccc1314dcdb0b988a9276ca6b6ce9b07bea21e

commit r15-3737-g33ccc1314dcdb0b988a9276ca6b6ce9b07bea21e
Author: Iain Sandoe 
Date:   Wed Sep 18 17:46:32 2024 +0100

Darwin: Allow for as versions that need '-' for std in.

Recent versions of Xcode as require a dash to read from standard
input.  We can use this on all supported OS versions so make it
unconditional.  Patch from Mark Mentovai.

gcc/ChangeLog:

* config/darwin.h (AS_NEEDS_DASH_FOR_PIPED_INPUT): New.

Signed-off-by: Iain Sandoe 

Diff:
---
 gcc/config/darwin.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index 377599074a75..0d8886c026c6 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -648,6 +648,8 @@ extern GTY(()) int darwin_ms_struct;
 #define ASM_OPTIONS "%{v} %{w:-W} %{I*}"
 #endif
 
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
+
 /* Default Darwin ASM_SPEC, very simple. */
 #define ASM_SPEC \
 "%{static} -arch %(darwin_arch) " \