[PATCH] Handle SLP build operand swapping for ternaries and calls

2025-06-30 Thread Richard Biener
The following adds SLP build operand swapping for .FMA which is
a ternary operator and a call.  The current code only handles
binary operators in assignments, thus the patch extends this to
handle both calls and assignments as well as binary and ternary
operators.

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

Richard.

* tree-vect-slp.cc (vect_build_slp_2): Handle ternary
and call operators when swapping operands.

* gcc.target/i386/vect-pr82426.c: Pass explicit -ffp-contract=fast.
* gcc.target/i386/vect-pr82426-2.c: New testcase variant with
-ffp-contract=on.
---
 .../gcc.target/i386/vect-pr82426-2.c  | 31 
 gcc/testsuite/gcc.target/i386/vect-pr82426.c  |  2 +-
 gcc/tree-vect-slp.cc  | 37 ++-
 3 files changed, 60 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/vect-pr82426-2.c

diff --git a/gcc/testsuite/gcc.target/i386/vect-pr82426-2.c 
b/gcc/testsuite/gcc.target/i386/vect-pr82426-2.c
new file mode 100644
index 000..525940866ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-pr82426-2.c
@@ -0,0 +1,31 @@
+/* i?86 does not have V2SF, x32 does though.  */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O3 -mavx -mfma -ffp-contract=on" } */
+
+struct Matrix
+{
+  float m11;
+  float m12;
+  float m21;
+  float m22;
+  float dx;
+  float dy;
+};
+
+struct Matrix multiply(const struct Matrix *a, const struct Matrix *b)
+{
+  struct Matrix out;
+  out.m11 = a->m11*b->m11 + a->m12*b->m21;
+  out.m12 = a->m11*b->m12 + a->m12*b->m22;
+  out.m21 = a->m21*b->m11 + a->m22*b->m21;
+  out.m22 = a->m21*b->m12 + a->m22*b->m22;
+
+  out.dx = a->dx*b->m11  + a->dy*b->m21 + b->dx;
+  out.dy = a->dx*b->m12  + a->dy*b->m22 + b->dy;
+  return out;
+}
+
+/* The whole kernel should be vectorized with V4SF and V2SF operations.  */
+/* { dg-final { scan-assembler-times "vadd" 1 } } */
+/* { dg-final { scan-assembler-times "vmul" 2 } } */
+/* { dg-final { scan-assembler-times "vfma" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/vect-pr82426.c 
b/gcc/testsuite/gcc.target/i386/vect-pr82426.c
index 03b10adff9b..8ce8fe78a91 100644
--- a/gcc/testsuite/gcc.target/i386/vect-pr82426.c
+++ b/gcc/testsuite/gcc.target/i386/vect-pr82426.c
@@ -1,6 +1,6 @@
 /* i?86 does not have V2SF, x32 does though.  */
 /* { dg-do compile { target { ! ia32 } } } */
-/* { dg-options "-O3 -mavx -mfma" } */
+/* { dg-options "-O3 -mavx -mfma -ffp-contract=fast" } */
 
 struct Matrix
 {
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 6842ca90f1c..a69cbb92739 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -2853,9 +2853,10 @@ out:
  && matches[0]
  /* ???  For COND_EXPRs we can swap the comparison operands
 as well as the arms under some constraints.  */
- && nops == 2
+ && (nops == 2 || nops == 3)
  && oprnds_info[1]->first_dt == vect_internal_def
- && is_gimple_assign (stmt_info->stmt)
+ && (is_gimple_assign (stmt_info->stmt)
+ || is_gimple_call (stmt_info->stmt))
  /* Swapping operands for reductions breaks assumptions later on.  */
  && STMT_VINFO_REDUC_IDX (stmt_info) == -1)
{
@@ -2870,14 +2871,32 @@ out:
continue;
  stmt_vec_info stmt_info = stmts[j];
  /* Verify if we can swap operands of this stmt.  */
- gassign *stmt = dyn_cast  (stmt_info->stmt);
- if (!stmt
- || !commutative_tree_code (gimple_assign_rhs_code (stmt)))
+ if (gassign *stmt = dyn_cast  (stmt_info->stmt))
{
- if (!swap_not_matching)
-   goto fail;
- swap_not_matching = false;
- break;
+ tree_code code = gimple_assign_rhs_code (stmt);
+ if (! commutative_tree_code (code)
+ && ! commutative_ternary_tree_code (code))
+   {
+ if (!swap_not_matching)
+   goto fail;
+ swap_not_matching = false;
+ break;
+   }
+   }
+ else if (gcall *call = dyn_cast  (stmt_info->stmt))
+   {
+ internal_fn fn = (gimple_call_internal_p (call)
+   ? gimple_call_internal_fn (call)
+   : IFN_LAST);
+ if ((! commutative_binary_fn_p (fn)
+  && ! commutative_ternary_fn_p (fn))
+ || first_commutative_argument (fn) != 0)
+   {
+ if (!swap_not_matching)
+   goto fail;
+ swap_not_matching = false;
+ 

Re: [PATCH] RISC-V: Vector-scalar negate-multiply-(subtract-)accumulate [PR119100]

2025-06-30 Thread Paul-Antoine Arras

On 30/06/2025 08:16, Robin Dapp wrote:

This is failing pre-commit testing:


linux rv64gcv lp64d medlow multilib:

FAIL: gcc.target/riscv/rvv/base/bug-4.c (internal compiler error: in 
extract_insn, at recog.cc:2882)

FAIL: gcc.target/riscv/rvv/base/bug-4.c (test for excess errors)
linux rv32gcv ilp32d medlow multilib:

FAIL: gcc.target/riscv/rvv/base/bug-4.c (internal compiler error: in 
extract_insn, at recog.cc:2882)

FAIL: gcc.target/riscv/rvv/base/bug-4.c (test for excess errors)
newlib rv64gcv lp64d medlow multilib:

FAIL: gcc.target/riscv/rvv/base/bug-4.c (internal compiler error: in 
extract_insn, at recog.cc:2882)

FAIL: gcc.target/riscv/rvv/base/bug-4.c (test for excess errors)


I think this is because the CI used a commit before PA's fix, so suffers 
from the same issue the last patch did (considering a ternop's operands 
interchangeable).


It looks good to me as it's mechanical and basically similar as the last 
patch.
I'd say it's good to go if Paul-Antoine has verified this is not another 
issue.




I rebased and reran the testsuite. I found no regression so pushed it to 
master.


Thanks,
--
PA


Re: [PATCH V3] x86: Enable separate shrink wrapping

2025-06-30 Thread H.J. Lu
On Tue, Jun 17, 2025 at 10:33 PM Uros Bizjak  wrote:
>
> On Tue, Jun 17, 2025 at 4:03 PM Cui, Lili  wrote:
> >
> > From: Lili Cui 
> >
> > Hi Uros,
> >
> > This is patch v3, the main changes are as follows.
> >
> > 1. Added a pro_epilogue_adjust_stack_add_nocc in i386.md to add memory
clobber for lea/mov.
> > 2. Adjusted some formatting issues.
> > 3. Added scan-rtl-dumps for ia32 in shrink_wrap_separate.C.
> >
> > Collected spec2017 performance on ZNVER5, EMR and ICELAKE. No
performance regression was observed.
> > For O2 multi-copy :
> > 511.povray_r improved by 2.8% on ZNVER5.
> > 511.povray_r improved by 4.2% on EMR
> >
> > Bootstrapped & regtested on x86-64-pc-linux-gnu.
> > Use this patch to build the latest Linux kernel and boot successfully.
> >
> > Thanks,
> > Lili.
> >
> >
> > This commit implements the target macros (TARGET_SHRINK_WRAP_*) that
> > enable separate shrink wrapping for function prologues/epilogues in
> > x86.
> >
> > When performing separate shrink wrapping, we choose to use mov instead
> > of push/pop, because using push/pop is more complicated to handle rsp
> > adjustment and may lose performance, so here we choose to use mov, which
> > has a small impact on code size, but guarantees performance.
> >
> > Using mov means we need to use sub/add to maintain the stack frame. In
> > some special cases, we need to use lea to prevent affecting EFlags.
> >
> > Avoid inserting sub between test-je-jle to change EFlags, lea should be
> > used here.
> >
> > foo:
> > xorl%eax, %eax
> > testl   %edi, %edi
> > je  .L11
> > sub $16, %rsp  --> leaq-16(%rsp), %rsp
> > movq%r13, 8(%rsp)
> > movl$1, %r13d
> > jle .L4
> >
> > Tested against SPEC CPU 2017, this change always has a net-positive
> > effect on the dynamic instruction count.  See the following table for
> > the breakdown on how this reduces the number of dynamic instructions
> > per workload on a like-for-like (with/without this commit):
> >
> > instruction count   basewith commit (commit-base)/commit
> > 502.gcc_r   98666845943 96891561634 -1.80%
> > 526.blender_r   6.21226E+11 6.12992E+11 -1.33%
> > 520.omnetpp_r   1.1241E+11  1.11093E+11 -1.17%
> > 500.perlbench_r 1271558717  1263268350  -0.65%
> > 523.xalancbmk_r 2.20103E+11 2.18836E+11 -0.58%
> > 531.deepsjeng_r 2.73591E+11 2.72114E+11 -0.54%
> > 500.perlbench_r 64195557393 63881512409 -0.49%
> > 541.leela_r 2.99097E+11 2.98245E+11 -0.29%
> > 548.exchange2_r 1.27976E+11 1.27784E+11 -0.15%
> > 527.cam4_r  88981458425 7334679 -0.11%
> > 554.roms_r  2.60072E+11 2.59809E+11 -0.10%
> >
> > Collected spec2017 performance on ZNVER5, EMR and ICELAKE. No
performance regression was observed.
> >
> > For O2 multi-copy :
> > 511.povray_r improved by 2.8% on ZNVER5.
> > 511.povray_r improved by 4% on EMR
> > 511.povray_r improved by 3.3 % ~ 4.6% on ICELAKE.
> >
> > gcc/ChangeLog:
> >
> > * config/i386/i386-protos.h (ix86_get_separate_components):
> > New function.
> > (ix86_components_for_bb): Likewise.
> > (ix86_disqualify_components): Likewise.
> > (ix86_emit_prologue_components): Likewise.
> > (ix86_emit_epilogue_components): Likewise.
> > (ix86_set_handled_components): Likewise.
> > * config/i386/i386.cc (save_regs_using_push_pop):
> > Split from ix86_compute_frame_layout.
> > (ix86_compute_frame_layout):
> > Use save_regs_using_push_pop.
> > (pro_epilogue_adjust_stack):
> > Use gen_pro_epilogue_adjust_stack_add_nocc.
> > (ix86_expand_prologue): Add some assertions and adjust
> > the stack frame at the beginning of the prolog for shrink
> > wrapping separate.
> > (ix86_emit_save_regs_using_mov):
> > Skip registers that are wrapped separately.
> > (ix86_emit_restore_regs_using_mov): Likewise.
> > (ix86_expand_epilogue): Add some assertions and set
> > restore_regs_via_mov to true for shrink wrapping separate.
> > (ix86_get_separate_components): New function.
> > (ix86_components_for_bb): Likewise.
> > (ix86_disqualify_components): Likewise.
> > (ix86_emit_prologue_components): Likewise.
> > (ix86_emit_epilogue_components): Likewise.
> > (ix86_set_handled_components): Likewise.
> > (TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS): Define.
> > (TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB): Likewise.
> > (TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS): Likewise.
> > (TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS): Likewise.
> > (TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS): Likewise.
> > (TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS): Likewise.
> > * c

Re: [PATCH 1/1] libstdc++: Implement default_accessor from mdspan.

2025-06-30 Thread Luc Grosheintz




On 6/30/25 09:58, Tomasz Kaminski wrote:

On Mon, Jun 30, 2025 at 9:25 AM Luc Grosheintz 
wrote:


libstdc++-v3/ChangeLog:

 * include/std/mdspan (default_accessor): New class.
 * src/c++23/std.cc.in: Register default_accessor.
 * testsuite/23_containers/mdspan/accessors/default.cc: New test.
 * testsuite/23_containers/mdspan/accessors/default_neg.cc: New
test.

Signed-off-by: Luc Grosheintz 
---

Version of v5 with all local changes included.


LGTM, tested locally and now running a full test suite.
Once it will get approval from Jonathan, I will handle merging it.


Fingers crossed! Thank you for your patience and I apologize for
the sequence of silly mistakes.






  libstdc++-v3/include/std/mdspan   | 31 ++
  libstdc++-v3/src/c++23/std.cc.in  |  3 +-
  .../23_containers/mdspan/accessors/default.cc | 99 +++
  .../mdspan/accessors/default_neg.cc   | 23 +
  4 files changed, 155 insertions(+), 1 deletion(-)
  create mode 100644
libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
  create mode 100644
libstdc++-v3/testsuite/23_containers/mdspan/accessors/default_neg.cc

diff --git a/libstdc++-v3/include/std/mdspan
b/libstdc++-v3/include/std/mdspan
index 6dc2441f80b..c72a64094b7 100644
--- a/libstdc++-v3/include/std/mdspan
+++ b/libstdc++-v3/include/std/mdspan
@@ -1004,6 +1004,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
[[no_unique_address]] _S_strides_t _M_strides;
  };

+  template
+struct default_accessor
+{
+  static_assert(!is_array_v<_ElementType>,
+   "ElementType must not be an array type");
+  static_assert(!is_abstract_v<_ElementType>,
+   "ElementType must not be an abstract class type");
+
+  using offset_policy = default_accessor;
+  using element_type = _ElementType;
+  using reference = element_type&;
+  using data_handle_type = element_type*;
+
+  constexpr
+  default_accessor() noexcept = default;
+
+  template
+   requires is_convertible_v<_OElementType(*)[], element_type(*)[]>
+   constexpr
+   default_accessor(default_accessor<_OElementType>) noexcept
+   { }
+
+  constexpr reference
+  access(data_handle_type __p, size_t __i) const noexcept
+  { return __p[__i]; }
+
+  constexpr data_handle_type
+  offset(data_handle_type __p, size_t __i) const noexcept
+  { return __p + __i; }
+};
+
  _GLIBCXX_END_NAMESPACE_VERSION
  }
  #endif
diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/
std.cc.in
index 9336118f5d9..e692caaa5f9 100644
--- a/libstdc++-v3/src/c++23/std.cc.in
+++ b/libstdc++-v3/src/c++23/std.cc.in
@@ -1850,7 +1850,8 @@ export namespace std
using std::layout_left;
using std::layout_right;
using std::layout_stride;
-  // FIXME layout_left_padded, layout_right_padded, default_accessor and
mdspan
+  using std::default_accessor;
+  // FIXME layout_left_padded, layout_right_padded, aligned_accessor and
mdspan
  }
  #endif

diff --git
a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
new file mode 100644
index 000..c036f8ad10f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
@@ -0,0 +1,99 @@
+// { dg-do run { target c++23 } }
+#include 
+
+#include 
+
+constexpr size_t dyn = std::dynamic_extent;
+
+template
+  constexpr void
+  test_accessor_policy()
+  {
+static_assert(std::copyable);
+static_assert(std::is_nothrow_move_constructible_v);
+static_assert(std::is_nothrow_move_assignable_v);
+static_assert(std::is_nothrow_swappable_v);
+  }
+
+constexpr bool
+test_access()
+{
+  std::default_accessor accessor;
+  std::array a{10, 11, 12, 13, 14};
+  VERIFY(accessor.access(a.data(), 0) == 10);
+  VERIFY(accessor.access(a.data(), 4) == 14);
+  return true;
+}
+
+constexpr bool
+test_offset()
+{
+  std::default_accessor accessor;
+  std::array a{10, 11, 12, 13, 14};
+  VERIFY(accessor.offset(a.data(), 0) == a.data());
+  VERIFY(accessor.offset(a.data(), 4) == a.data() + 4);
+  return true;
+}
+
+class Base
+{ };
+
+class Derived : public Base
+{ };
+
+constexpr void
+test_ctor()
+{
+  // T -> T
+
static_assert(std::is_nothrow_constructible_v,
+
  std::default_accessor>);
+  static_assert(std::is_convertible_v,
+ std::default_accessor>);
+
+  // T -> const T
+  static_assert(std::is_convertible_v,
+ std::default_accessor>);
+  static_assert(std::is_convertible_v,
+ std::default_accessor>);
+
+  // const T -> T
+  static_assert(!std::is_constructible_v,
+std::default_accessor>);
+  static_assert(!std::is_constructible_v,
+std::default_accessor>);
+
+  // T <-> volatile T
+  static_assert(std::is_convertible_v,
+

Re: [PATCH v2] tree-optimization/120780: Support object size for containing objects

2025-06-30 Thread Richard Biener
On Fri, Jun 27, 2025 at 2:39 PM Siddhesh Poyarekar  wrote:
>
> MEM_REF cast of a subobject to its containing object has negative
> offsets, which objsz sees as an invalid access.  Support this use case
> by peeking into the structure to validate that the containing object
> indeed contains a type of the subobject at that offset and if present,
> adjust the wholesize for the object to allow the negative offset.
>
> gcc/ChangeLog:
>
> PR tree-optimization/120780
> * tree-object-size.cc (inner_at_offset,
> get_wholesize_for_memref): New functions.
> (addr_object_size): Call GET_WHOLESIZE_FOR_MEMREF.
>
> gcc/testsuite/ChangeLog:
>
> PR tree-optimization/120780
> * gcc.dg/builtin-dynamic-object-size-pr120780.c: New test case.
>
> Signed-off-by: Siddhesh Poyarekar 
> ---
>
> Testing notes:
>
> - Local tests continue to look good.
> - Bootstraps in progress.
>
>  .../builtin-dynamic-object-size-pr120780.c| 233 ++
>  gcc/tree-object-size.cc   |  83 ++-
>  2 files changed, 315 insertions(+), 1 deletion(-)
>  create mode 100644 
> gcc/testsuite/gcc.dg/builtin-dynamic-object-size-pr120780.c
>
> diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-pr120780.c 
> b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-pr120780.c
> new file mode 100644
> index 000..0d6593ec828
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-pr120780.c
> @@ -0,0 +1,233 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +
> +#include "builtin-object-size-common.h"
> +typedef __SIZE_TYPE__ size_t;
> +#define NUM_MCAST_RATE 6
> +
> +#define MIN(a,b) ((a) < (b) ? (a) : (b))
> +#define MAX(a,b) ((a) > (b) ? (a) : (b))
> +
> +struct inner
> +{
> +  int dummy[4];
> +};
> +
> +struct container
> +{
> +  int mcast_rate[NUM_MCAST_RATE];
> +  struct inner mesh;
> +};
> +
> +static void
> +test1_child (struct inner *ifmsh, size_t expected)
> +{
> +  struct container *sdata =
> +(struct container *) ((void *) ifmsh
> + - __builtin_offsetof (struct container, mesh));
> +
> +  if (__builtin_dynamic_object_size (sdata->mcast_rate, 1)
> +  != sizeof (sdata->mcast_rate))
> +FAIL ();
> +
> +  if (__builtin_dynamic_object_size (&sdata->mesh, 1) != expected)
> +FAIL ();
> +}
> +
> +void
> +__attribute__((noinline))
> +test1 (size_t sz)
> +{
> +  struct container *sdata = __builtin_malloc (sz);
> +  struct inner *ifmsh = &sdata->mesh;
> +
> +  test1_child (ifmsh,
> +  (sz > sizeof (sdata->mcast_rate)
> +   ? sz - sizeof (sdata->mcast_rate) : 0));
> +
> +  __builtin_free (sdata);
> +}
> +
> +struct container2
> +{
> +  int mcast_rate[NUM_MCAST_RATE];
> +  union
> +{
> +  int dummy;
> +  double dbl;
> +  struct inner mesh;
> +} u;
> +};
> +
> +static void
> +test2_child (struct inner *ifmsh, size_t sz)
> +{
> +  struct container2 *sdata =
> +(struct container2 *) ((void *) ifmsh
> +  - __builtin_offsetof (struct container2, u.mesh));
> +
> +  if (__builtin_dynamic_object_size (sdata->mcast_rate, 1)
> +  != sizeof (sdata->mcast_rate))
> +FAIL ();
> +
> +  size_t diff = sizeof (*sdata) - sz;
> +  size_t expected = MIN(sizeof (double), MAX (sizeof (sdata->u), diff) - 
> diff);
> +
> +  if (__builtin_dynamic_object_size (&sdata->u.dbl, 1) != expected)
> +FAIL ();
> +
> +  expected = MAX (sizeof (sdata->u.mesh), diff) - diff;
> +  if (__builtin_dynamic_object_size (&sdata->u.mesh, 1) != expected)
> +FAIL ();
> +}
> +
> +void
> +__attribute__((noinline))
> +test2 (size_t sz)
> +{
> +  struct container2 *sdata = __builtin_malloc (sz);
> +  struct inner *ifmsh = &sdata->u.mesh;
> +
> +  test2_child (ifmsh, sz);;
> +
> +  __builtin_free (sdata);
> +}
> +
> +struct container3
> +{
> +  int mcast_rate[NUM_MCAST_RATE];
> +  char mesh[8];
> +};
> +
> +static void
> +test3_child (char ifmsh[], size_t expected)
> +{
> +  struct container3 *sdata =
> +(struct container3 *) ((void *) ifmsh
> +  - __builtin_offsetof (struct container3, mesh));
> +
> +  if (__builtin_dynamic_object_size (sdata->mcast_rate, 1)
> +  != sizeof (sdata->mcast_rate))
> +FAIL ();
> +
> +  if (__builtin_dynamic_object_size (sdata->mesh, 1) != expected)
> +FAIL ();
> +}
> +
> +void
> +__attribute__((noinline))
> +test3 (size_t sz)
> +{
> +  struct container3 *sdata = __builtin_malloc (sz);
> +  char *ifmsh = sdata->mesh;
> +  size_t diff = sizeof (*sdata) - sz;
> +
> +  test3_child (ifmsh, MAX(sizeof (sdata->mesh), diff) - diff);
> +
> +  __builtin_free (sdata);
> +}
> +
> +
> +struct container4
> +{
> +  int mcast_rate[NUM_MCAST_RATE];
> +  struct
> +{
> +  int dummy;
> +  struct inner mesh;
> +} s;
> +};
> +
> +static void
> +test4_child (struct inner *ifmsh, size_t expected)
> +{
> +  struct container4 *sdata =
> +(struct container4 *) ((void *) ifmsh
> +  - __b

Re: [PATCH 1/2] allow contraction to synthetic single-element vector FMA

2025-06-30 Thread Richard Biener
On Mon, Jun 30, 2025 at 9:54 AM Richard Biener
 wrote:
>
> On Fri, Jun 27, 2025 at 3:45 PM Alexander Monakov  wrote:
> >
> >
> > On Fri, 27 Jun 2025, Richard Biener wrote:
> >
> > > > I am testing partial fixes for these issues.
> > >
> > > Can you check again after r16-1731-g08bdb6b4a32f1f?
> >
> > Certainly.  There's no more fmaddsub-related testsuite failures, and only
> > three tests need adjustment on x86.
> >
> > * gcc.target/i386/pr116979.c
> >
> > Here we check that FMA is used for complex multiplication. This is a case
> > where use of FMA is detrimental for accuracy, but I guess we can choose
> > to preserve the status quo. I can look into teaching
> > expand_complex_multiplication to emit FMAs.
>
> Yeah, I guess that's within -ffp-contract=on constraints.  When you say it's
> detrimental for accuracy, is that a general statement for complex multiply
> lowering?  If so we possibly do not want FMAs?
>
> > gcc.target/i386/vect-pr82426.c
> >
> > Here we check that 2x2 matrix multiplication ends up using a specific mix
> > of plain mul/adds and FMAs, and SLP is having difficulties. Generally
> > we are doing poorer job compared to LLVM here, either with or without
> > early FMAs. Do you want a separate bugreport for this?
>
> Yeah, it seems to be a lack of operand swizzling support for ternary
> commutative ops and for swapping ops of calls.  So yes, please open
> a separate bugreport for this.  I'll see what I can do there.

I have fixed this and filed two remaining corner cases not handled
as PR120885 and PR120886, but I think both are unrelated to the
task at hand.

So no need to open a bugreport anymore.

> > gcc.target/i386/intrinsics_opt-1.c
> >
> > Here we check that SSE addss and mulss intrinsics are combined into an
> > FMA. Clearly a case where unrestricted contraction needs to be enabled
> > explicitly via -ffp-contract=fast or such (but also, I'd say it is a
> > questionable transform considering the source had intrinsics).
>
> Yep, I'd expect there are some cases where we would need to add
> -ffp-contract=fast
> when we switch the default.

It might also seem we'd lose coverage for -ffp-contract=fast in some cases.
I'm unsure what to do here besides looking for the fallout of -ffp-contract=off
and duplicating all testcases to run with both -ffp-contract=on and
-ffp-contract=fast?

Not the first time I wish we'd have sth like

/* { dg-torture { { -ffp-contract=fast } { -ffp-contract=on } } } */

and possibly dg-additional-torture to amend what's done with dg-torture.exp,
dg-torture there might produce a cross-product of both torture sets.

Richard.

>
> Thanks,
> Richard.
>
> > --- 8< ---
> >
> > From acf83683b03653e3317a30a549cecd3bde49a325 Mon Sep 17 00:00:00 2001
> > From: Alexander Monakov 
> > Date: Mon, 12 May 2025 23:23:42 +0300
> > Subject: [PATCH] c-family: switch away from -ffp-contract=fast
> >
> > Unrestricted FMA contraction, combined with optimizations that create
> > copies of expressions, is causing hard-to-debug issues such as PR106902.
> > Since we implement conformant contraction now, switch C and C++ from
> > -ffp-contract=fast to either =off (under -std=c[++]NN like before, also
> > for C++ now), or =on (under -std=gnu[++]NN).  Keep -ffp-contract=fast
> > when -funsafe-math-optimizations (or -ffast-math, -Ofast) is active.
> >
> > In other words,
> >
> > - -ffast-math: no change, unrestricted contraction like before;
> > - standards compliant mode for C: no change, no contraction;
> > - ditto, for C++: align with C (no contraction);
> > - otherwise, switch C and C++ from -ffp-contract=fast to =on.
> >
> > gcc/c-family/ChangeLog:
> >
> > * c-opts.cc (c_common_post_options): Adjust handling of
> > flag_fp_contract_mode.
> >
> > gcc/ChangeLog:
> >
> > * doc/invoke.texi (-ffp-contract): Describe new defaults.
> > (-funsafe-math-optimizations): Add -ffp-contract=fast.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gcc.target/i386/pr116979.c: Add -ffp-contract=fast to flags.
> > * gcc.target/i386/vect-pr82426.c: Ditto.
> > * gcc.target/i386/intrinsics_opt-1.c: Ditto.
> > ---
> >  gcc/c-family/c-opts.cc   | 11 ++-
> >  gcc/doc/invoke.texi  | 10 ++
> >  gcc/testsuite/gcc.target/i386/intrinsics_opt-1.c |  2 +-
> >  gcc/testsuite/gcc.target/i386/pr116979.c |  2 +-
> >  gcc/testsuite/gcc.target/i386/vect-pr82426.c |  2 +-
> >  5 files changed, 11 insertions(+), 16 deletions(-)
> >
> > diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
> > index 3ee9444cbe..40aba4dcc1 100644
> > --- a/gcc/c-family/c-opts.cc
> > +++ b/gcc/c-family/c-opts.cc
> > @@ -877,15 +877,8 @@ c_common_post_options (const char **pfilename)
> >  flag_excess_precision = (flag_iso ? EXCESS_PRECISION_STANDARD
> >  : EXCESS_PRECISION_FAST);
> >
> > -  /* ISO C restricts floating-point expression contraction to within
> > - source-language 

Re: [PATCH 1/2] libstdc++: Use ranges::iter_move in ranges::unique [PR120789]

2025-06-30 Thread Tomasz Kaminski
On Fri, Jun 27, 2025 at 4:45 AM Patrick Palka  wrote:

> Tested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps
> 15/14?
>
Both look good to me thanks.


>
> -- >8 --
>
> PR libstdc++/120789
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/ranges_algo.h (__unique_fn::operator()): Use
> ranges::iter_move(iter) instead of std::move(*iter).
> * testsuite/25_algorithms/unique/120789.cc: New test.
> ---
>  libstdc++-v3/include/bits/ranges_algo.h   |  2 +-
>  .../testsuite/25_algorithms/unique/120789.cc  | 36 +++
>  2 files changed, 37 insertions(+), 1 deletion(-)
>  create mode 100644 libstdc++-v3/testsuite/25_algorithms/unique/120789.cc
>
> diff --git a/libstdc++-v3/include/bits/ranges_algo.h
> b/libstdc++-v3/include/bits/ranges_algo.h
> index 83eaa7da28b9..3590c501c4cd 100644
> --- a/libstdc++-v3/include/bits/ranges_algo.h
> +++ b/libstdc++-v3/include/bits/ranges_algo.h
> @@ -1454,7 +1454,7 @@ namespace ranges
>   if (!std::__invoke(__comp,
>  std::__invoke(__proj, *__dest),
>  std::__invoke(__proj, *__first)))
> -   *++__dest = std::move(*__first);
> +   *++__dest = ranges::iter_move(__first);
> return {++__dest, __first};
>}
>
> diff --git a/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc
> b/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc
> new file mode 100644
> index ..24b107132473
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc
> @@ -0,0 +1,36 @@
> +// PR libstdc++/120789 - ranges::unique should use ranges::iter_move
> +// { dg-do compile { target c++20 } }
> +
> +#include 
> +
> +struct A
> +{
> +  bool operator==(const A&) const;
> +};
> +
> +struct B
> +{
> +  B(B&&) = delete;
> +  B& operator=(const A&) const;
> +
> +  operator A() const;
> +  bool operator==(const B&) const;
> +};
> +
> +struct I
> +{
> +  using value_type = A;
> +  using difference_type = int;
> +  B operator*() const;
> +  I& operator++();
> +  I operator++(int);
> +  bool operator==(const I&) const;
> +  friend A iter_move(const I&);
> +};
> +
> +void
> +test01()
> +{
> +  std::ranges::subrange r;
> +  auto [begin, end] = std::ranges::unique(r);
> +}
> --
> 2.50.0.131.gcf6f63ea6b
>
>


Re: [PATCH] fold-mem-offsets: Convert from DF to RTL-SSA

2025-06-30 Thread Richard Sandiford
Christoph Müllner  writes:
> This patch converts the fold-mem-offsets pass from DF to RTL-SSA.
> Along with this conversion, the way the pass collects information
> was completely reworked.  Instead of visiting each instruction multiple
> times, this is now down only once.
>
> Most significant changes are:
> * The pass operates mainly on insn_info objects from RTL-SSA.
> * Single iteration over all nondebug INSNs for identification
>   of fold-mem-roots.  Then walk of the fold-mem-roots' DEF-chain
>   to collect foldable constants.
> * The class fold_mem_info holds vectors for the DEF-chain of
>   the to-be-folded INSNs (fold_agnostic_insns, which don't need
>   to be adjusted, and fold_insns, which need their constant to
>   be set to zero).
> * Introduction of a single-USE mode, which only collects DEFs,
>   that have a single USE and therefore are safe to transform
>   (the fold-mem-root will be the final USE).  This mode is fast
>   and will always run (unless disabled via -fno-fold-mem-offsets).
> * Introduction of a multi-USE mode, which allows DEFs to have
>   multiple USEs, but all USEs must be part of any fold-mem-root's
>   DEF-chain.  The analysis of all USEs is expensive and therefore,
>   this mode is disabled for highly connected CFGs.  Note, that
>   multi-USE mode will miss some opportunities that the single-USE
>   mode finds (e.g. multi-USE mode fails for fold-mem-offsets-3.c).
>
> The following testing was done:
> * Bootstrapped and regtested on aarch64-linux and x86-64-linux.
> * Regtested on riscv64-linux.
> * SPEC CPU 2017 tested on aarch64 and riscv64-linux.
>
> The number of applied optimizations of different versions/modes
> of fold-mem-offsets in SPEC CPU2017 on RISC-V rv64gc_zba_zbb_zbs
> is as follows:
>
> Upstream:
>   500.perlbench_r: 169
>   502.gcc_r: 624
>   520.omnetpp_r: 1301
>   523.xalancbmk_r: 23
>   525.x264_r: 705
>   531.deepsjeng_r: 36
>   541.leela_r: 19
>   548.exchange2: 90
>   557.xz_r: 11
>   SUM: 2151
>
> New single-USE:
>   500.perlbench_r: 70
>   502.gcc_r: 263
>   520.omnetpp_r: 1100
>   523.xalancbmk_r: 10
>   525.x264_r: 95
>   531.deepsjeng_r: 19
>   541.leela_r: 252
>   548.exchange2: 13
>   557.xz_r: 11
>   SUM: 1833
>
> New multi-USE:
>   500.perlbench_r: 186
>   502.gcc_r: 744
>   520.omnetpp_r: 1187
>   523.xalancbmk_r: 22
>   525.x264_r: 985
>   531.deepsjeng_r: 21
>   541.leela_r: 87
>   548.exchange2: 63
>   557.xz_r: 23
>   SUM: 3318
>
> New single-USE then multi-USE:
>   500.perlbench_r: 192
>   502.gcc_r: 761
>   520.omnetpp_r: 1673
>   523.xalancbmk_r: 22
>   525.x264_r: 995
>   531.deepsjeng_r: 21
>   541.leela_r: 252
>   548.exchange2: 63
>   557.xz_r: 23
>   SUM: 4002
>
> A compile time analysis with `/bin/time -v ./install/usr/local/bin/gcc -O2 
> all.i`
> (all.i from PR117922) shows:
> * -fno-fold-mem-offsets:  289 s (user time) / 15572436 kBytes (max resident 
> set size)
> * -ffold-mem-offsets: 339 s (user time) / 23606516 kBytes (max resident 
> set size)
> Adding -fexpensive-optimizations to enable multi-USE mode does not have
> an impact on the duration or the memory footprint.
>
> SPEC CPU 2017 showed no significant performance impact on aarch64-linux.
>
> gcc/ChangeLog:
>
>   PR rtl-optimization/117922
>   * fold-mem-offsets.cc (INCLUDE_ALGORITHM): Added definition.
>   (INCLUDE_FUNCTIONAL): Likewise.
>   (INCLUDE_ARRAY): Likewise.
>   (class pass_fold_mem_offsets): Moved to bottom of file.
>   (get_fold_mem_offset_root): Converted to RTL-SSA.
>   (get_single_def_in_bb): Converted to RTL-SSA.
>   (get_uses): New.
>   (has_foldable_uses_p): Converted to RTL-SSA.
>   (fold_offsets): Converted to RTL-SSA.
>   (fold_offsets_1): Converted to RTL-SSA.
>   (get_fold_mem_root): Removed.
>   (do_check_validity): New.
>   (do_analysis): Removed.
>   (insn_uses_not_in_bitmap): New.
>   (do_fold_info_calculation): Removed.
>   (drop_unsafe_candidates): New.
>   (do_commit_offset): Converted to RTL-SSA.
>   (compute_validity_closure): Removed.
>   (do_commit_insn): Changed to change INSN in place.
>   (fold_mem_offsets_single_use): New.
>   (fold_mem_offsets_multi_use): New.
>   (pass_fold_mem_offsets::execute): Moved to bottom of file.
>   (fold_mem_offsets): New.
>
> Signed-off-by: Christoph Müllner 
> ---
>  gcc/fold-mem-offsets.cc | 1138 ---
>  1 file changed, 596 insertions(+), 542 deletions(-)

Thanks for doing this.  I have some specific comments below, but my
main general comment is this:

When using rtl-ssa, changes to instructions should happen through the
rtl-ssa changes framework, since that keeps the metadata up-to-date.
It also ensures that (for example) uses in debug instructions are not
accidentally left behind.

As part of this, I think it would be better to make all the rtl insn
changes tentatively *before* checking validity, rather than building
up a list of rtl insns that needs to be chang

[r16-1742 Regression] FAIL: 25_algorithms/inplace_merge/constrained.cc -std=gnu++26 (test for excess errors) on Linux/x86_64

2025-06-30 Thread haochen.jiang
On Linux/x86_64,

9d3467a14bbd75469f114b047590ebbffa4a9c8b is the first bad commit
commit 9d3467a14bbd75469f114b047590ebbffa4a9c8b
Author: Patrick Palka 
Date:   Fri Jun 27 13:53:26 2025 -0400

libstdc++: Directly implement ranges::inplace_merge [PR100795]

caused

FAIL: 25_algorithms/inplace_merge/constrained.cc  -std=gnu++20 (test for excess 
errors)
FAIL: 25_algorithms/inplace_merge/constrained.cc  -std=gnu++26 (test for excess 
errors)

with GCC configured with

../../gcc/configure 
--prefix=/export/users3/haochenj/src/gcc-bisect/master/master/r16-1742/usr 
--enable-clocale=gnu --with-system-zlib --with-demangler-in-ld 
--with-fpmath=sse --enable-languages=c,c++,fortran --enable-cet --without-isl 
--enable-libmpx x86_64-linux --disable-bootstrap

To reproduce:

$ cd {build_dir}/x86_64-linux/libstdc++-v3/testsuite && make check 
RUNTESTFLAGS="conformance.exp=25_algorithms/inplace_merge/constrained.cc 
--target_board='unix{-m64\ -march=cascadelake}'"

(Please do not reply to this email, for question about this report, contact me 
at haochen dot jiang at intel.com.)
(If you met problems with cascadelake related, disabling AVX512F in command 
line might save that.)
(However, please make sure that there is no potential problems with AVX512.)


Re: [PATCH v6 1/3][Middle-end] Provide more contexts for -Warray-bounds, -Wstringop-*warning messages due to code movements from compiler transformation (Part 1) [PR109071, PR85788, PR88771, PR106762,

2025-06-30 Thread Richard Biener
On Fri, Jun 27, 2025 at 3:39 PM Qing Zhao  wrote:
>
> Hi,
>
> A status update on this patch:  (Actually a good news!)
>
> > On Jun 10, 2025, at 11:32, Qing Zhao  wrote:
> >
> >
> >
> 
> >>>
> >>> It's difficult to do any meaningful pruning I think.  Consider
> >>>
> >>> if (i == -1)
> >>>   tem = a[i];
> >>>
> >>> when we transform this to
> >>>
> >>> if (i == -1)
> >>>  tem = a[-1];
> >>>
> >>> and report the out-of-bounds access then we've lost the fact
> >>> that -1 was originally 'i' and there's an interesting condition on that
> >>> variable.  So unless we preserve some kind of optimization history
> >>> on a stmt like the above we are lost.  The same is true for
> >>> "altered" control edges where the most interesting are again those
> >>> that are elided by optimization (the implied true/false conditions).
> >>>
> >>> That said, I would expect the user to not use -fdiagnostics-show-context 
> >>> by
> >>> default but instead when being puzzled about a diagnostic, turn it on
> >>> on-demand.  So it's probably useful to report all of the chain or maybe
> >>> have -fdiagnostic-show-context=N with N limiting the depth (or a separate
> >>> knob for this).
> >>>
> >>> When there's still 'i' in a[i] but we figured out a range then we can see
> >>> to do 1. to gather conditions that we consider.  The backwards threader
> >>> has "interestingness" heuristics that could eventually be repurposed.
> >>> The "good" thing is that once we decide to emit a diagnostic it's fair
> >>> to spend quite some cycles on improving it.
> >>
> >> So as a summary I'd say we'd want to have -fdiagnostic-show-context
> >> (=1 for now) and simply display the immediate control condition for
> >> the select diagnostics your patch series handled and start from there,
> >> adding test coverage where that's useful (like for my simple a[i] example
> >> above) and see in what cases that's lacking.
> >
> > Thanks for the summary, I agree.
> >
> > The following is my plan:
> >
> > 1. The first working version of -fdiagnostic-show-context=N should cover 
> > all the current
> > known testing cases: all the PRs and your testing case and Kees’s new 
> > testing case.
>
> I tried the following very simple heuristic to form the diagnostic path in my 
> current working-in-progress patch:
>
>   /* Starting from cur_bb, backtrace the CFG through the single predecessor
> to form the path. For example:
>  B2
> /  \
>V\
>   B3 \
>   / \ \
>  V   \>V
>  B4B7
>
> In the above CFG, if the STMT is in B4, we backtrace to its single
> predecessor B3 first, and then back to B3's single predecessor B2,
> till there is no single predecessor anymore, or the # of backtrace
> depth exceeds the value of flag_diagnostics_show_context.

Good.  Then we are sure we stop at a dominator of B4.

> For each single predecessor block, locate the conditional statement
> in the end of the block. determine whether the STMT is on the taken
> path of the condition. Add these two information to each event of
> the path.  */
>
>
> The good news is:  With the above simple heuristic and a simple back tracing 
> of  the CFG, all the
> current testing cases for the following PRs passed without any issue:
>
> PR109071
> PR88771
> PR85788
> PR108770
> PR106762
> PR115274
> PR117179

Nice.  An incremental improvement would be to instead of handling
single predecessors, skip to the immediate dominator - this way
uninteresting intermediate CFG is skipped.  This might be confusing
and the next "step" could be very far away, not sure how to best
handle this.  But it would handle intermediate conditional code, like

  if (i < 10)
{
   if (dollar)
 printf ("dollar");
   else
 printf ("euro");
   printf ("%d", amout[i]);
}

where you'd not able to go up to if (i < 10).  Maybe a simple heuristic
on number of line to not skip too far works, or simply ignore this
for now, or simply only use immediate dominators for the first
condition to be printed?

Thanks,
Richard.

> I will continue working on this to add more testing cases and also more 
> warnings per the following discussion:
> https://gcc.gnu.org/pipermail/gcc-patches/2025-May/684126.html
> https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686323.html
> https://gcc.gnu.org/pipermail/gcc-patches/2025-June/685852.html
> https://gcc.gnu.org/pipermail/gcc-patches/2025-June/685854.html
>
> Let me know if you have any comments or suggestions.
>
> Thanks a lot for all the help.
>
> Qing
> >
> > 2. Then we can improve it later if new uncovered testing case is reported.
> >
> > Is this reasonable?
> >
> > Qing
> >>
> >> Richard.
> >>
> >
> >>
>


Re: [PATCH 1/1] libstdc++: Implement default_accessor from mdspan.

2025-06-30 Thread Tomasz Kaminski
On Mon, Jun 30, 2025 at 9:58 AM Tomasz Kaminski  wrote:

>
>
> On Mon, Jun 30, 2025 at 9:25 AM Luc Grosheintz 
> wrote:
>
>> libstdc++-v3/ChangeLog:
>>
>> * include/std/mdspan (default_accessor): New class.
>> * src/c++23/std.cc.in: Register default_accessor.
>> * testsuite/23_containers/mdspan/accessors/default.cc: New test.
>> * testsuite/23_containers/mdspan/accessors/default_neg.cc: New
>> test.
>>
>> Signed-off-by: Luc Grosheintz 
>> ---
>>
>> Version of v5 with all local changes included.
>>
> LGTM, tested locally and now running a full test suite.
> Once it will get approval from Jonathan, I will handle merging it.
>
All test passed.

>
>
>>
>>  libstdc++-v3/include/std/mdspan   | 31 ++
>>  libstdc++-v3/src/c++23/std.cc.in  |  3 +-
>>  .../23_containers/mdspan/accessors/default.cc | 99 +++
>>  .../mdspan/accessors/default_neg.cc   | 23 +
>>  4 files changed, 155 insertions(+), 1 deletion(-)
>>  create mode 100644
>> libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
>>  create mode 100644
>> libstdc++-v3/testsuite/23_containers/mdspan/accessors/default_neg.cc
>>
>> diff --git a/libstdc++-v3/include/std/mdspan
>> b/libstdc++-v3/include/std/mdspan
>> index 6dc2441f80b..c72a64094b7 100644
>> --- a/libstdc++-v3/include/std/mdspan
>> +++ b/libstdc++-v3/include/std/mdspan
>> @@ -1004,6 +1004,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>[[no_unique_address]] _S_strides_t _M_strides;
>>  };
>>
>> +  template
>> +struct default_accessor
>> +{
>> +  static_assert(!is_array_v<_ElementType>,
>> +   "ElementType must not be an array type");
>> +  static_assert(!is_abstract_v<_ElementType>,
>> +   "ElementType must not be an abstract class type");
>> +
>> +  using offset_policy = default_accessor;
>> +  using element_type = _ElementType;
>> +  using reference = element_type&;
>> +  using data_handle_type = element_type*;
>> +
>> +  constexpr
>> +  default_accessor() noexcept = default;
>> +
>> +  template
>> +   requires is_convertible_v<_OElementType(*)[], element_type(*)[]>
>> +   constexpr
>> +   default_accessor(default_accessor<_OElementType>) noexcept
>> +   { }
>> +
>> +  constexpr reference
>> +  access(data_handle_type __p, size_t __i) const noexcept
>> +  { return __p[__i]; }
>> +
>> +  constexpr data_handle_type
>> +  offset(data_handle_type __p, size_t __i) const noexcept
>> +  { return __p + __i; }
>> +};
>> +
>>  _GLIBCXX_END_NAMESPACE_VERSION
>>  }
>>  #endif
>> diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/
>> std.cc.in
>> index 9336118f5d9..e692caaa5f9 100644
>> --- a/libstdc++-v3/src/c++23/std.cc.in
>> +++ b/libstdc++-v3/src/c++23/std.cc.in
>> @@ -1850,7 +1850,8 @@ export namespace std
>>using std::layout_left;
>>using std::layout_right;
>>using std::layout_stride;
>> -  // FIXME layout_left_padded, layout_right_padded, default_accessor and
>> mdspan
>> +  using std::default_accessor;
>> +  // FIXME layout_left_padded, layout_right_padded, aligned_accessor and
>> mdspan
>>  }
>>  #endif
>>
>> diff --git
>> a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
>> b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
>> new file mode 100644
>> index 000..c036f8ad10f
>> --- /dev/null
>> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
>> @@ -0,0 +1,99 @@
>> +// { dg-do run { target c++23 } }
>> +#include 
>> +
>> +#include 
>> +
>> +constexpr size_t dyn = std::dynamic_extent;
>> +
>> +template
>> +  constexpr void
>> +  test_accessor_policy()
>> +  {
>> +static_assert(std::copyable);
>> +static_assert(std::is_nothrow_move_constructible_v);
>> +static_assert(std::is_nothrow_move_assignable_v);
>> +static_assert(std::is_nothrow_swappable_v);
>> +  }
>> +
>> +constexpr bool
>> +test_access()
>> +{
>> +  std::default_accessor accessor;
>> +  std::array a{10, 11, 12, 13, 14};
>> +  VERIFY(accessor.access(a.data(), 0) == 10);
>> +  VERIFY(accessor.access(a.data(), 4) == 14);
>> +  return true;
>> +}
>> +
>> +constexpr bool
>> +test_offset()
>> +{
>> +  std::default_accessor accessor;
>> +  std::array a{10, 11, 12, 13, 14};
>> +  VERIFY(accessor.offset(a.data(), 0) == a.data());
>> +  VERIFY(accessor.offset(a.data(), 4) == a.data() + 4);
>> +  return true;
>> +}
>> +
>> +class Base
>> +{ };
>> +
>> +class Derived : public Base
>> +{ };
>> +
>> +constexpr void
>> +test_ctor()
>> +{
>> +  // T -> T
>> +
>> static_assert(std::is_nothrow_constructible_v,
>> +
>>  std::default_accessor>);
>> +  static_assert(std::is_convertible_v,
>> + std::default_accessor>);
>> +
>> +  // T -> const T
>> +  static_assert(std::is_convertible_v,
>> + std::default_accessor> double>>);
>> +  static_assert(std::is_convertible_v,
>> + 

Re: [PATCH 0/1] Adapt unwinder to Linux's SME signal behaviour

2025-06-30 Thread Yury Khrustalev
Hi,

On Thu, Jun 19, 2025 at 02:39:47PM +0100, Yury Khrustalev wrote:
> This patch aligns unwinder with the recent chnages in Linux SME signal
> behaviour.
> 
> Regression checked on AArch64 and no regressions have been found.
> OK for trunk?
> 
> base commit: 20f59301851
> 
> ---
> 
> Richard Sandiford (1):
>   aarch64: Adapt unwinder to linux's SME signal behaviour
> 
>  gcc/doc/sourcebuild.texi  |  3 +
>  .../g++.target/aarch64/sme/sme_throw_1.C  | 55 +++
>  .../g++.target/aarch64/sme/sme_throw_2.C  |  4 +
>  gcc/testsuite/lib/target-supports.exp | 23 +
>  libgcc/config/aarch64/linux-unwind.h  | 95 ++-
>  5 files changed, 179 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.target/aarch64/sme/sme_throw_1.C
>  create mode 100644 gcc/testsuite/g++.target/aarch64/sme/sme_throw_2.C
> 
> -- 
> 2.39.5
> 


A polite ping :)

Thanks,
Yury



[PATCH] libphobos: Fully enable Darwin/i386 support

2025-06-30 Thread Rainer Orth
I recently noticed that libphobos isn't enable by default on 32-bit
Darwin with the target triples determined by config.guess.  E.g. on a
Darwin 15 system the target triple is something like
i386-apple-darwin15.6.0 while configure.tgt only matches
i?86-*-darwin1[2-7].

This patch also allows such minor and micro versions.

Tested on i386-apple-darwin15.6.0.

I'd commit this as obvious, but there's more: on older Darwin versions
(9, 10, and 11), configure.tgt only sets LIBDRUNTIME_ONLY.  However,
toplevel configure.ac doesn't take this into account when deciding
whether to enable libphobos or not.  I wonder if it should, though.  I
guess it could: on my Darwin 11 system, test results (with explicit
--enable-libphobos) aren't too bad:

=== gdc tests ===


Running target unix
FAIL: gdc.dg/gdc300.d   (test for excess errors)
WARNING: gdc.test/compilable/ctfe_math.d   (test for excess errors) program 
timed out.
UNRESOLVED: gdc.test/runnable/stress.d   compilation failed to produce 
executable
UNRESOLVED: gdc.test/runnable/stress.d -shared-libphobos   compilation failed 
to produce executable
UNRESOLVED: gdc.test/runnable/test12197.d   compilation failed to produce 
executable
UNRESOLVED: gdc.test/runnable/test12197.d -shared-libphobos   compilation 
failed to produce executable
UNRESOLVED: gdc.test/runnable/wc.d   compilation failed to produce executable
UNRESOLVED: gdc.test/runnable/wc.d -shared-libphobos   compilation failed to 
produce executable
UNRESOLVED: gdc.test/runnable/wc2.d   compilation failed to produce executable
UNRESOLVED: gdc.test/runnable/wc2.d -shared-libphobos   compilation failed to 
produce executable
UNRESOLVED: gdc.test/runnable/wc3.d   compilation failed to produce executable
UNRESOLVED: gdc.test/runnable/wc3.d -shared-libphobos   compilation failed to 
produce executable
UNRESOLVED: gdc.test/runnable_cxx/cpp_stdlib.d   compilation failed to produce 
executable
UNRESOLVED: gdc.test/runnable_cxx/cpp_stdlib.d -shared-libphobos   compilation 
failed to produce executable
UNRESOLVED: gdc.test/runnable_cxx/cppa.d   compilation failed to produce 
executable
UNRESOLVED: gdc.test/runnable_cxx/cppa.d -g   compilation failed to produce 
executable
UNRESOLVED: gdc.test/runnable_cxx/cppa.d -g -shared-libphobos   compilation 
failed to produce executable
UNRESOLVED: gdc.test/runnable_cxx/cppa.d -shared-libphobos   compilation failed 
to produce executable

=== gdc Summary for unix ===

# of expected passes12849
# of unexpected failures1
# of unresolved testcases   16
# of unsupported tests  611

Running target unix/-m64
FAIL: gdc.dg/gdc300.d   (test for excess errors)
UNRESOLVED: gdc.test/runnable/stress.d   compilation failed to produce 
executable
UNRESOLVED: gdc.test/runnable/stress.d -shared-libphobos   compilation failed 
to produce executable
UNRESOLVED: gdc.test/runnable/test12197.d   compilation failed to produce 
executable
UNRESOLVED: gdc.test/runnable/test12197.d -shared-libphobos   compilation 
failed to produce executable
UNRESOLVED: gdc.test/runnable/wc.d   compilation failed to produce executable
UNRESOLVED: gdc.test/runnable/wc.d -shared-libphobos   compilation failed to 
produce executable
UNRESOLVED: gdc.test/runnable/wc2.d   compilation failed to produce executable
UNRESOLVED: gdc.test/runnable/wc2.d -shared-libphobos   compilation failed to 
produce executable
UNRESOLVED: gdc.test/runnable/wc3.d   compilation failed to produce executable
UNRESOLVED: gdc.test/runnable/wc3.d -shared-libphobos   compilation failed to 
produce executable

=== gdc Summary for unix/-m64 ===

# of expected passes12859
# of unexpected failures1
# of unresolved testcases   10
# of unsupported tests  610

=== gdc Summary ===

# of expected passes25708
# of unexpected failures2
# of unresolved testcases   26
# of unsupported tests  1221
/private/var/gcc/regression/master/10.7-gcc-32/build/gcc/gdc  version 16.0.0 
20250626 (experimental) [master 5d613f473126772c47180d895b5ca438329534e2] (GCC) 

=== libphobos tests ===


Running target unix
FAIL: libphobos.druntime/shared/core/internal/gc/impl/conservative/gc.d (test 
for excess errors)
FAIL: libphobos.druntime/shared/core/thread/fiber/base.d execution test
FAIL: libphobos.druntime/shared/core/time.d execution test
FAIL: libphobos.druntime/shared/rt/monitor_.d execution test
FAIL: libphobos.druntime/static/core/internal/gc/impl/conservative/gc.d (test 
for excess errors)
FAIL: libphobos.shared/host.c -ldl -pthread execution test
FAIL: libphobos.shared/load_linkdep.d -shared-libphobos -ldl execution test

=== libphobos Summary for unix ===

# of expected passes504
# of unexpected failures7
# of unsupported tests  1

Running target unix/-m64
FAIL: libphobos.druntime/shared/core/thread/fiber/base.d execution test
FAIL: libphobos.druntime/shared/

Re: [PATCH 1/3]middle-end: support vec_cbranch_any and vec_cbranch_all [PR118974]

2025-06-30 Thread Richard Biener
On Mon, 9 Jun 2025, Tamar Christina wrote:

> This patch introduces two new vector cbranch optabs vec_cbranch_any and
> vec_cbranch_all.
> 
> To explain why we need two new optabs let me explain the current cbranch and 
> its
> limitations and what I'm trying to optimize. So sorry for the long email, but 
> I
> hope it explains why I think we want new optabs.
> 
> Today cbranch can be used for both vector and scalar modes.  In both these
> cases it's intended to compare boolean values, either scalar or vector.
> 
> The optab documentation does not however state that it can only handle
> comparisons against 0.  So many targets have added code for the vector variant
> that tries to deal with the case where we branch based on two non-zero
> registers.
> 
> However this code can't ever be reached because the cbranch expansion only 
> deals
> with comparisons against 0 for vectors.  This is because for vectors the rest 
> of
> the compiler has no way to generate a non-zero comparison. e.g. the vectorizer
> will always generate a zero comparison, and the C/C++ front-ends won't allow
> vectors to be used in a cbranch as it expects a boolean value.  ISAs like SVE
> work around this by requiring you to use an SVE PTEST intrinsics which results
> in a single scalar boolean value that represents the flag values.
> 
> e.g. if (svptest_any (..))
> 
> The natural question is why do we not at expand time then rewrite the 
> comparison
> to a non-zero comparison if the target supports it.
> 
> The reason is we can't safely do so.  For an ANY comparison (e.g. != b) this 
> is
> trivial, but for an ALL comparison (e.g. == b) we would have to flip both 
> branch
> and invert the value being compared.  i.e. we have to make it a != b 
> comparison.
> 
> But in emit_cmp_and_jump_insns we can't flip the branches anymore because they
> have already been lowered into a fall through branch (PC) and a label, ready 
> for
> use in an if_then_else RTL expression.
> 
> Additionally as mentioned before, cbranches expect the values to be masks, not
> values.  This kinda works out if you XOR the values, but for FP vectors you'd
> need to know what equality means for the FP format.  i.e. it's possible for
> IEEE 754 values but It's not immediately obvious if this is true for all
> formats.
> 
> Now why does any of this matter?  Well there are two optimizations we want to 
> be
> able to do.
> 
> 1. Adv. SIMD does not support a vector !=, as in there's no instruction for 
> it.
>For both Integer and FP vectors we perform the comparisons as EQ and then
>invert the resulting mask.  Ideally we'd like to replace this with just a 
> XOR
>and the appropriate branch.
> 
> 2. When on an SVE enabled system we would like to use an SVE compare + branch
>for the Adv. SIMD sequence which could happen due to cost modelling.  
> However
>we can only do so based on if we know that the values being compared 
> against
>are the boolean masks.  This means we can't really use combine to do this
>because combine would have to match the entire sequence including the
>vector comparisons because at RTL we've lost the information that
>VECTOR_BOOLEAN_P would have given us.  This sequence would be too long for
>combine to match due to it having to match the compare + branch sequence
>being generated as well.  It also becomes a bit messy to match ANY and ALL
>sequences.
> 
> To handle these two cases I propose the new optabs vec_cbranch_any and
> vec_cbranch_all that expect the operands to be values, not masks, and the
> comparison operation is the comparison being performed.  The current cbranch
> optab can't be used here because we need to be able to see both comparison
> operators (for the boolean branch and the data compare branch).
> 
> The initial != 0 or == 0 is folded away into the name as _any and _all 
> allowing
> the target to easily do as it wishes.
> 
> I have intentionally chosen to require cbranch_optab to still be the main one.
> i.e. you can't have vec_cbranch_any/vec_cbranch_all without cbranch because
> these two are an expand time only construct.  I've also chosen them to be this
> such that there's no change needed to any other passes in the middle-end.
> 
> With these two optabs it's trivial to implement the two optimization I 
> described
> above.  A target expansion hook is also possible but optabs felt more natural
> for the situation.
> 
> I.e. with them we can now generate
> 
> .L2:
> ldr q31, [x1, x2]
> add v29.4s, v29.4s, v25.4s
> add v28.4s, v28.4s, v26.4s
> add v31.4s, v31.4s, v30.4s
> str q31, [x1, x2]
> add x1, x1, 16
> cmp x1, 2560
> beq .L1
> .L6:
> ldr q30, [x3, x1]
> cmpeq   p15.s, p7/z, z30.s, z27.s
> b.none  .L2
> 
> and easily prove it correct.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu,
> arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
> -m32, -m64

Re: [PATCH v6 1/3][Middle-end] Provide more contexts for -Warray-bounds, -Wstringop-*warning messages due to code movements from compiler transformation (Part 1) [PR109071, PR85788, PR88771, PR106762,

2025-06-30 Thread Richard Biener
On Tue, Jun 10, 2025 at 5:28 PM Qing Zhao  wrote:
>
>
>
> > On Jun 10, 2025, at 09:37, Richard Biener  
> > wrote:
> >
> > On Mon, Jun 9, 2025 at 8:06 PM Qing Zhao  wrote:
> >>
> >>
> >>
> >>> On Jun 6, 2025, at 03:31, Richard Biener  
> >>> wrote:
> >>>
> >>> On Fri, May 30, 2025 at 5:13 PM Qing Zhao  wrote:
> 
>  Hi, Richard,
> 
>  Really appreciate for your suggestions.
> 
> > On May 30, 2025, at 05:22, Richard Biener  
> > wrote:
> >
> > On Fri, May 23, 2025 at 10:49 PM Qing Zhao  wrote:
> >>
> >> Hi, Richard,
> >>
> >> Thanks a lot for your comments and questions.
> >> Please see my answers embedded below:
> >>
> >>> On May 19, 2025, at 06:44, Richard Biener 
> >>>  wrote:
> >>>
> >>> On Fri, May 16, 2025 at 3:34 PM Qing Zhao  
> >>> wrote:
> 
>  Control this with a new option -fdiagnostics-details.
> 
>  $ cat t.c
>  extern void warn(void);
>  static inline void assign(int val, int *regs, int *index)
>  {
>  if (*index >= 4)
>  warn();
>  *regs = val;
>  }
>  struct nums {int vals[4];};
> 
>  void sparx5_set (int *ptr, struct nums *sg, int index)
>  {
>  int *val = &sg->vals[index];
> 
>  assign(0,ptr, &index);
>  assign(*val, ptr, &index);
>  }
> 
>  $ gcc -Wall -O2  -c -o t.o t.c
>  t.c: In function ‘sparx5_set’:
>  t.c:12:23: warning: array subscript 4 is above array bounds of 
>  ‘int[4]’ [-Warray-bounds=]
>  12 |   int *val = &sg->vals[index];
>    |   ^~~
>  t.c:8:18: note: while referencing ‘vals’
>  8 | struct nums {int vals[4];};
>    |  ^~~~
> 
>  In the above, Although the warning is correct in theory, the warning 
>  message
>  itself is confusing to the end-user since there is information that 
>  cannot
>  be connected to the source code directly.
> 
>  It will be a nice improvement to add more information in the warning 
>  message
>  to report where such index value come from.
> 
>  In order to achieve this, we add a new data structure "move_history" 
>  to record
>  1. the "condition" that triggers the code movement;
>  2. whether the code movement is on the true path of the "condition";
>  3. the "compiler transformation" that triggers the code movement.
> 
>  Whenever there is a code movement along control flow graph due to 
>  some
>  specific transformations, such as jump threading, path isolation, 
>  tree
>  sinking, etc., a move_history structure is created and attached to 
>  the
>  moved gimple statement.
> 
>  During array out-of-bound checking or -Wstringop-* warning checking, 
>  the
>  "move_history" that was attached to the gimple statement is used to 
>  form
>  a sequence of diagnostic events that are added to the corresponding 
>  rich
>  location to be used to report the warning message.
> 
>  This behavior is controled by the new option -fdiagnostics-details
>  which is off by default.
> 
>  With this change, by adding -fdiagnostics-details,
>  the warning message for the above testing case is now:
> 
>  $ gcc -Wall -O2 -fdiagnostics-details -c -o t.o t.c
>  t.c: In function ‘sparx5_set’:
>  t.c:12:23: warning: array subscript 4 is above array bounds of 
>  ‘int[4]’ [-Warray-bounds=]
>  12 |   int *val = &sg->vals[index];
>    |   ^~~
>  ‘sparx5_set’: events 1-2
>  4 |   if (*index >= 4)
>    |  ^
>    |  |
>    |  (1) when the condition is evaluated to true
>  ..
>  12 |   int *val = &sg->vals[index];
>    |   ~~~
>    |   |
>    |   (2) out of array bounds here
>  t.c:8:18: note: while referencing ‘vals’
>  8 | struct nums {int vals[4];};
>    |  ^~~~
> 
>  The change was divided into 3 parts:
> 
>  Part 1: Add new data structure move_history, record move_history 
>  during
>  transformation;
>  Part 2: In warning analysis, Use the new move_history to form a rich
>  location with a sequence of events, to report more context info
>  of the warnings.
>  Part 3: Add debugging mechanism for move_history.
> >>>
> >>> Thanks for working on this.  I'm pasting my review notes on [1/3] 
> >>> below.
> >>>
> >>>
> >>> ove histori

Re: [PATCH 1/2] allow contraction to synthetic single-element vector FMA

2025-06-30 Thread Richard Biener
On Fri, Jun 27, 2025 at 3:45 PM Alexander Monakov  wrote:
>
>
> On Fri, 27 Jun 2025, Richard Biener wrote:
>
> > > I am testing partial fixes for these issues.
> >
> > Can you check again after r16-1731-g08bdb6b4a32f1f?
>
> Certainly.  There's no more fmaddsub-related testsuite failures, and only
> three tests need adjustment on x86.
>
> * gcc.target/i386/pr116979.c
>
> Here we check that FMA is used for complex multiplication. This is a case
> where use of FMA is detrimental for accuracy, but I guess we can choose
> to preserve the status quo. I can look into teaching
> expand_complex_multiplication to emit FMAs.

Yeah, I guess that's within -ffp-contract=on constraints.  When you say it's
detrimental for accuracy, is that a general statement for complex multiply
lowering?  If so we possibly do not want FMAs?

> gcc.target/i386/vect-pr82426.c
>
> Here we check that 2x2 matrix multiplication ends up using a specific mix
> of plain mul/adds and FMAs, and SLP is having difficulties. Generally
> we are doing poorer job compared to LLVM here, either with or without
> early FMAs. Do you want a separate bugreport for this?

Yeah, it seems to be a lack of operand swizzling support for ternary
commutative ops and for swapping ops of calls.  So yes, please open
a separate bugreport for this.  I'll see what I can do there.

> gcc.target/i386/intrinsics_opt-1.c
>
> Here we check that SSE addss and mulss intrinsics are combined into an
> FMA. Clearly a case where unrestricted contraction needs to be enabled
> explicitly via -ffp-contract=fast or such (but also, I'd say it is a
> questionable transform considering the source had intrinsics).

Yep, I'd expect there are some cases where we would need to add
-ffp-contract=fast
when we switch the default.

Thanks,
Richard.

> --- 8< ---
>
> From acf83683b03653e3317a30a549cecd3bde49a325 Mon Sep 17 00:00:00 2001
> From: Alexander Monakov 
> Date: Mon, 12 May 2025 23:23:42 +0300
> Subject: [PATCH] c-family: switch away from -ffp-contract=fast
>
> Unrestricted FMA contraction, combined with optimizations that create
> copies of expressions, is causing hard-to-debug issues such as PR106902.
> Since we implement conformant contraction now, switch C and C++ from
> -ffp-contract=fast to either =off (under -std=c[++]NN like before, also
> for C++ now), or =on (under -std=gnu[++]NN).  Keep -ffp-contract=fast
> when -funsafe-math-optimizations (or -ffast-math, -Ofast) is active.
>
> In other words,
>
> - -ffast-math: no change, unrestricted contraction like before;
> - standards compliant mode for C: no change, no contraction;
> - ditto, for C++: align with C (no contraction);
> - otherwise, switch C and C++ from -ffp-contract=fast to =on.
>
> gcc/c-family/ChangeLog:
>
> * c-opts.cc (c_common_post_options): Adjust handling of
> flag_fp_contract_mode.
>
> gcc/ChangeLog:
>
> * doc/invoke.texi (-ffp-contract): Describe new defaults.
> (-funsafe-math-optimizations): Add -ffp-contract=fast.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/i386/pr116979.c: Add -ffp-contract=fast to flags.
> * gcc.target/i386/vect-pr82426.c: Ditto.
> * gcc.target/i386/intrinsics_opt-1.c: Ditto.
> ---
>  gcc/c-family/c-opts.cc   | 11 ++-
>  gcc/doc/invoke.texi  | 10 ++
>  gcc/testsuite/gcc.target/i386/intrinsics_opt-1.c |  2 +-
>  gcc/testsuite/gcc.target/i386/pr116979.c |  2 +-
>  gcc/testsuite/gcc.target/i386/vect-pr82426.c |  2 +-
>  5 files changed, 11 insertions(+), 16 deletions(-)
>
> diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
> index 3ee9444cbe..40aba4dcc1 100644
> --- a/gcc/c-family/c-opts.cc
> +++ b/gcc/c-family/c-opts.cc
> @@ -877,15 +877,8 @@ c_common_post_options (const char **pfilename)
>  flag_excess_precision = (flag_iso ? EXCESS_PRECISION_STANDARD
>  : EXCESS_PRECISION_FAST);
>
> -  /* ISO C restricts floating-point expression contraction to within
> - source-language expressions (-ffp-contract=on, currently an alias
> - for -ffp-contract=off).  */
> -  if (flag_iso
> -  && !c_dialect_cxx ()
> -  && (OPTION_SET_P (flag_fp_contract_mode)
> - == (enum fp_contract_mode) 0)
> -  && flag_unsafe_math_optimizations == 0)
> -flag_fp_contract_mode = FP_CONTRACT_OFF;
> +  if (!flag_unsafe_math_optimizations && !OPTION_SET_P 
> (flag_fp_contract_mode))
> +flag_fp_contract_mode = flag_iso ? FP_CONTRACT_OFF : FP_CONTRACT_ON;
>
>/* C language modes before C99 enable -fpermissive by default, but
>   only if -pedantic-errors is not specified.  Also treat
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index b83818337c..b03d2f16be 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -13111,16 +13111,17 @@ Disabled by default.
>  @opindex ffp-contract
>  @item -ffp-contract=@var{style}
>  @option{-ffp-contract=off} disables floating-point expression contraction.

Re: AFDO/FDO profile comparator

2025-06-30 Thread Kugan Vivekanandarajah
Hi Honza,

On Sun, Jun 29, 2025 at 10:45 PM Jan Hubicka  wrote:
>
> >
> >
> > > On 24 Jun 2025, at 7:43 pm, Jan Hubicka  wrote:
> > >
> > > External email: Use caution opening links or attachments
> > >
> > >
> > > Hi,
> > > this pass removes early-inlining from afdo pass since all inlining
> > > should now happen from early inliner.  I tedted this on spec and there
> > > are 3 inlines happening here which are blocked at early-inline time by
> > > hitting large function growth limit.  We probably want to bypass that
> > > limit, I will look into that incrementaly.
> >
> > Thanks for doing this. Is the inlining difference here is due to annotation 
> > that happens in auto-profile pass in the earlier implementation?
> >
> > One unrelated question about scaling profiles. We seem to scale-up AFDO  
> > with and_count_scale and scale down local_profile in some other cases. 
> > Should we instead scale up AFDO profile to local_profile scale. Lot of the 
> > inlining and other parameters seem to work well with that.
>
> Hi,
> I implemented simple afdo/fdo profile comparator.  I think we will need to 
> figure out
> what to print and what to look for.  It currently records the afdo, fdo count 
> pairs
> and then try to scale afdo counts to fdo counts printng differences.

I tried your patch on the current master and when I try running as you
mentioned, it looks like PGO counters are not read. I am seeing
something like (fdo is always zero):

update_stmt.part.0/2212 bb 0 (cold) afdo 3400152 (guessed) scaled 0
(guessed) fdo 0 (precise) diff 0, +0.00%
update_stmt.part.0/2212 bb 4 (cold) afdo 3400152 (auto FDO) scaled 0
(guessed) fdo 0 (precise) diff 0, +0.00%

Also, the patch didn't apply cleanly to the current master. Is the
patch complete?

Thanks,
Kugan

>
> It prints info as follows:
>
> brute/32 bb 60 (cold) afdo 0 (auto FDO) scaled 0 (guessed) fdo 4847 (precise) 
> diff -4847, -100.00%
>  preds
>  succs 59 169
> brute/32 bb 61 (hot) afdo 629997 (auto FDO) scaled 24978219 (guessed) fdo 
> 9332718 (precise) diff 15645501, +167.64%
>  preds
>  succs 59 62
> brute/32 bb 62 (hot) afdo 2753633 (auto FDO) scaled 109176468 (guessed) fdo 
> 37330872 (precise) diff 71845596, +192.46%
>  preds
>  succs 61 68 69 63
> brute/32 bb 63 (hot) afdo 2031304 (auto FDO) scaled 80537456 (guessed) fdo 
> 27998154 (precise) diff 52539302, +187.65%
>  preds
>  succs 62 64
> brute/32 bb 64 (very hot) afdo 2661301 (auto FDO) scaled 105515674 (guessed) 
> fdo 111992616 (precise) diff -6476942, -5.78%
>  preds
>  succs 63 67 68 65
>
> I.e. function name, bb index, hotness according to afdo (I added very hot 
> variant as those we want to look at first), afdo count,
> attempt to scale it correctly, fdo count and difference.
>
> So I think very hot with very large negative diff are first to look at.
>
> jh@shroud:~/cpu2017/benchspec/CPU/548.exchange2_r/build/build_peak_autofdo-cmp-m64.>
>  grep "(very hot).*, -9[0-9]\\." *.profile | sort -t")" -n -k3
> digits_2/30 bb 248 (very hot) afdo 1106295 (auto FDO) scaled 43862556 
> (guessed) fdo 2180591954 (precise) diff -2136729398, -97.99%
> digits_2/30 bb 276 (very hot) afdo 7848783 (auto FDO) scaled 311189765 
> (guessed) fdo 13764381875 (precise) diff -13453192110, -97.74%
> digits_2/30 bb 308 (very hot) afdo 8952263 (auto FDO) scaled 354940711 
> (guessed) fdo 10821023213 (precise) diff -10466082502, -96.72%
> digits_2/30 bb 340 (very hot) afdo 8148862 (auto FDO) scaled 323087343 
> (guessed) fdo 7398657585 (precise) diff -7075570242, -95.63%
> digits_2/30 bb 4 (very hot) afdo 9774243 (auto FDO) scaled 387530701 
> (guessed) fdo 4039694145 (precise) diff -3652163444, -90.41%
> hidden_triplets/8 bb 380 (very hot) afdo 153532 (guessed) scaled 6087261 
> (guessed) fdo 162401310 (precise) diff -156314049, -96.25%
> hidden_triplets/8 bb 381 (very hot) afdo 136644 (guessed) scaled 5417682 
> (guessed) fdo 146161179 (precise) diff -140743497, -96.29%
> hidden_triplets/8 bb 383 (very hot) afdo 136644 (guessed) scaled 5417682 
> (guessed) fdo 146161179 (precise) diff -140743497, -96.29%
> hidden_triplets/8 bb 387 (very hot) afdo 53337 (guessed) scaled 2114714 
> (guessed) fdo 162209420 (precise) diff -160094706, -98.70%
> hidden_triplets/8 bb 388 (very hot) afdo 47470 (guessed) scaled 1882098 
> (guessed) fdo 145988478 (precise) diff -144106380, -98.71%
> hidden_triplets/8 bb 390 (very hot) afdo 47470 (guessed) scaled 1882098 
> (guessed) fdo 145988478 (precise) diff -144106380, -98.71%
> new_solver/9 bb 139 (very hot) afdo 365547 (guessed) scaled 14493264 
> (guessed) fdo 399160962 (precise) diff -384667698, -96.37%
> new_solver/9 bb 140 (very hot) afdo 345441 (guessed) scaled 13696098 
> (guessed) fdo 361455947 (precise) diff -347759849, -96.21%
> new_solver/9 bb 142 (very hot) afdo 326442 (guessed) scaled 12942823 
> (guessed) fdo 352025127 (precise) diff -339082304, -96.32%
> new_solver/9 bb 160 (very hot) afdo 365547 (guessed) scaled 14493264 
> (guessed) fdo 397240050 (precise) diff -3827467

Re: [PATCH 1/1] libstdc++: Implement default_accessor from mdspan.

2025-06-30 Thread Tomasz Kaminski
On Mon, Jun 30, 2025 at 9:25 AM Luc Grosheintz 
wrote:

> libstdc++-v3/ChangeLog:
>
> * include/std/mdspan (default_accessor): New class.
> * src/c++23/std.cc.in: Register default_accessor.
> * testsuite/23_containers/mdspan/accessors/default.cc: New test.
> * testsuite/23_containers/mdspan/accessors/default_neg.cc: New
> test.
>
> Signed-off-by: Luc Grosheintz 
> ---
>
> Version of v5 with all local changes included.
>
LGTM, tested locally and now running a full test suite.
Once it will get approval from Jonathan, I will handle merging it.


>
>  libstdc++-v3/include/std/mdspan   | 31 ++
>  libstdc++-v3/src/c++23/std.cc.in  |  3 +-
>  .../23_containers/mdspan/accessors/default.cc | 99 +++
>  .../mdspan/accessors/default_neg.cc   | 23 +
>  4 files changed, 155 insertions(+), 1 deletion(-)
>  create mode 100644
> libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
>  create mode 100644
> libstdc++-v3/testsuite/23_containers/mdspan/accessors/default_neg.cc
>
> diff --git a/libstdc++-v3/include/std/mdspan
> b/libstdc++-v3/include/std/mdspan
> index 6dc2441f80b..c72a64094b7 100644
> --- a/libstdc++-v3/include/std/mdspan
> +++ b/libstdc++-v3/include/std/mdspan
> @@ -1004,6 +1004,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>[[no_unique_address]] _S_strides_t _M_strides;
>  };
>
> +  template
> +struct default_accessor
> +{
> +  static_assert(!is_array_v<_ElementType>,
> +   "ElementType must not be an array type");
> +  static_assert(!is_abstract_v<_ElementType>,
> +   "ElementType must not be an abstract class type");
> +
> +  using offset_policy = default_accessor;
> +  using element_type = _ElementType;
> +  using reference = element_type&;
> +  using data_handle_type = element_type*;
> +
> +  constexpr
> +  default_accessor() noexcept = default;
> +
> +  template
> +   requires is_convertible_v<_OElementType(*)[], element_type(*)[]>
> +   constexpr
> +   default_accessor(default_accessor<_OElementType>) noexcept
> +   { }
> +
> +  constexpr reference
> +  access(data_handle_type __p, size_t __i) const noexcept
> +  { return __p[__i]; }
> +
> +  constexpr data_handle_type
> +  offset(data_handle_type __p, size_t __i) const noexcept
> +  { return __p + __i; }
> +};
> +
>  _GLIBCXX_END_NAMESPACE_VERSION
>  }
>  #endif
> diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/
> std.cc.in
> index 9336118f5d9..e692caaa5f9 100644
> --- a/libstdc++-v3/src/c++23/std.cc.in
> +++ b/libstdc++-v3/src/c++23/std.cc.in
> @@ -1850,7 +1850,8 @@ export namespace std
>using std::layout_left;
>using std::layout_right;
>using std::layout_stride;
> -  // FIXME layout_left_padded, layout_right_padded, default_accessor and
> mdspan
> +  using std::default_accessor;
> +  // FIXME layout_left_padded, layout_right_padded, aligned_accessor and
> mdspan
>  }
>  #endif
>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
> b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
> new file mode 100644
> index 000..c036f8ad10f
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
> @@ -0,0 +1,99 @@
> +// { dg-do run { target c++23 } }
> +#include 
> +
> +#include 
> +
> +constexpr size_t dyn = std::dynamic_extent;
> +
> +template
> +  constexpr void
> +  test_accessor_policy()
> +  {
> +static_assert(std::copyable);
> +static_assert(std::is_nothrow_move_constructible_v);
> +static_assert(std::is_nothrow_move_assignable_v);
> +static_assert(std::is_nothrow_swappable_v);
> +  }
> +
> +constexpr bool
> +test_access()
> +{
> +  std::default_accessor accessor;
> +  std::array a{10, 11, 12, 13, 14};
> +  VERIFY(accessor.access(a.data(), 0) == 10);
> +  VERIFY(accessor.access(a.data(), 4) == 14);
> +  return true;
> +}
> +
> +constexpr bool
> +test_offset()
> +{
> +  std::default_accessor accessor;
> +  std::array a{10, 11, 12, 13, 14};
> +  VERIFY(accessor.offset(a.data(), 0) == a.data());
> +  VERIFY(accessor.offset(a.data(), 4) == a.data() + 4);
> +  return true;
> +}
> +
> +class Base
> +{ };
> +
> +class Derived : public Base
> +{ };
> +
> +constexpr void
> +test_ctor()
> +{
> +  // T -> T
> +
> static_assert(std::is_nothrow_constructible_v,
> +
>  std::default_accessor>);
> +  static_assert(std::is_convertible_v,
> + std::default_accessor>);
> +
> +  // T -> const T
> +  static_assert(std::is_convertible_v,
> + std::default_accessor double>>);
> +  static_assert(std::is_convertible_v,
> + std::default_accessor Derived>>);
> +
> +  // const T -> T
> +  static_assert(!std::is_constructible_v,
> +std::default_accessor double>>);
> +  static_assert(!std::is_constructible_v,

Re: [PATCH][RFC] phiopt: Optimize A < 0 ? ARG1 OP 2^n-1 : ARG1

2025-06-30 Thread Richard Biener
On Fri, 27 Jun 2025, Jeff Law wrote:

> 
> 
> On 6/27/25 12:30 PM, Andrew Pinski wrote:
> > 
> > 
> > On Fri, Jun 27, 2025, 11:06 AM Raphael Moreira Zinsly
> > mailto:rzin...@ventanamicro.com>> wrote:
> > 
> > Hi all,
> > 
> > For targets that have expensive shifts this may not get a better
> > sequence right now, specially for AVR and MSP430 according to
> > our tests.
> > Before I start looking for a fix on those targets I want to know
> > if someone has any advise or other concerns with this transformation.
> > 
> > 
> > There is lshift_cheap_p to see if left shit is cheap but there is not one
> > for right shift.
> > Now doing `-(a<0)` is cheap but the secondary shift is the expensive in
> > those cases. But maybe there is a decent way of selecting the a? CST0:CST1
> > right before expand might be a good idea.
> I think we want to turn it into straightline code as early as possible *if* we
> can do so without regressing other targets and meet the gimple cost criteria.
> The latter is more complex in this case because we're dealing with conditional
> branches, so just counting expression evaluations isn't necessarily sufficient
> here.

Well, there's eliding a branch and there's using shifts intead of cmov.
On GIMPLE you can have a COND_EXPR as a stmt RHS, so you can if-convert
separately from deciding on whether to use cmov or not.  The fact is
that recovering a cmov from the suggested shift operations is hard and
this definitely is a very target dependent decision.

For GIMPLE it's also cost metrics for say early inlining where a larger
stmt sequence is bad.  A branch (gcond) is currently costed 1 plus
the cost of the conditional operator (a < here).  Clearly the shift
sequence is more expensive for inlining.

If we want to special case sign-bit operations it might be worth
considering a (set of) builtin that allows target specific optimal
expansion.  Alternatively this seems to be something for a pre-expand
transform that needs to use target costs to decide whether it's worth.
There are definitely a lot of embedded targets that prefer jumps over
cmov.

Richard.

> 
> There's a whole mess of cases where we can take advantage of splatting the
> sign bit across a GPR.  Selecting across constants is a start, but not the end
> of the line.  Consider a < 0 ? b : 0;  That's just
> 
> t = a >> BITS_PER_WORD-1
> res = t & b;
> 
> 
> jeff
> 
> 
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Re: [RFC PATCH v2 3/3] Add -ftarget-clones-table option support

2025-06-30 Thread Alfie Richards

On 29/06/2025 19:57, Yangyu Chen wrote:

This patch adds support for target_clones table option. The
target_clones table option allows users to specify multiple versions
of a function and select the version at runtime based on the specified
table.

The target clone table is a JSON object where function names serve as
keys, and their values are nested objects. Each nested object maps
architecture names to lists of target clone attributes. This structure
allows specifying function clones for different architectures. Below is
an example:

```
{
   "foo": {
 "x86_64": ["avx2", "avx512f"],
 "riscv64": ["arch=+v", "arch=+zba,+zbb", ...],
 ... // more architectures
   },
   // more functions
}
```

A example of the table is as follows on RISC-V:

C source code "ror32.c":

```
void ror32(unsigned int *a, unsigned int b, unsigned long size) {
   for (unsigned long i = 0; i < size; i++) {
 a[i] = a[i] >> b | (a[i] << (32 - b));
   }
}
```

Table "ror32.target_clones":

```
{
   "ror32": {
 "riscv64": ["arch=+zvbb,+zbb", "arch=+zbb"]
   }
}
```

Then use: gcc -O3 -ftarget-clones-table=ror32.target_clones -S ror32.c
to compile the source code. This will generate 3 versions and its IFUNC
resolver for the ror32 function which is "arch=+zvbb,+zbb" and
"arch=+zbb" and the default version.

Signed-off-by: Yangyu Chen 

gcc/ChangeLog:

* Makefile.in: Add -DTARGET_NAME to CFLAGS-multiple_target.o.
* common.opt: Add target clone table option.
* multiple_target.cc (expand_target_clones): Add support for
target_clones table option.
(init_clone_map): Ditto.
(ipa_target_clone): Ditto.
---
  gcc/Makefile.in|   1 +
  gcc/common.opt |   7 +++
  gcc/multiple_target.cc | 124 -
  3 files changed, 129 insertions(+), 3 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 9535804f7fb..9bf633367e2 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2682,6 +2682,7 @@ s-bversion: BASE-VER
$(STAMP) s-bversion
  
  CFLAGS-toplev.o += -DTARGET_NAME=\"$(target_noncanonical)\"

+CFLAGS-multiple_target.o += -DTARGET_NAME=\"$(target_noncanonical)\"
  CFLAGS-tree-diagnostic-client-data-hooks.o += 
-DTARGET_NAME=\"$(target_noncanonical)\"
  CFLAGS-optinfo-emit-json.o += -DTARGET_NAME=\"$(target_noncanonical)\" 
$(ZLIBINC)
  CFLAGS-analyzer/engine.o += $(ZLIBINC)
diff --git a/gcc/common.opt b/gcc/common.opt
index a76a6920b54..45d49a92b5f 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2692,6 +2692,13 @@ fprofile-reorder-functions
  Common Var(flag_profile_reorder_functions) Optimization
  Enable function reordering that improves code placement.
  
+ftarget-clones-table=

+Common Joined RejectNegative Var(target_clones_table)
+Enable target clones attributes specified in the JSON file.
+
+Variable
+const char *target_clones_table = NULL
+
  fpatchable-function-entry=
  Common Var(flag_patchable_function_entry) Joined Optimization
  Insert NOP instructions at each function entry.
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index d25277c0a93..b5e52d5b91f 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -21,6 +21,10 @@ along with GCC; see the file COPYING3.  If not see
  .  */
  
  #include "config.h"

+#include 
+#define INCLUDE_MAP
+#define INCLUDE_STRING
+#define INCLUDE_SSTREAM
  #include "system.h"
  #include "coretypes.h"
  #include "backend.h"
@@ -38,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
  #include "gimple-walk.h"
  #include "tree-inline.h"
  #include "intl.h"
+#include "json-parsing.h"
  
  /* Walker callback that replaces all FUNCTION_DECL of a function that's

 going to be versioned.  */
@@ -311,7 +316,8 @@ create_target_clone (cgraph_node *node, bool definition, 
char *name,
 create the appropriate clone for each valid target attribute.  */
  
  static bool

-expand_target_clones (struct cgraph_node *node, bool definition)
+expand_target_clones (struct cgraph_node *node, bool definition,
+ std::map  &clone_map)
  {
int i;
/* Parsing target attributes separated by TARGET_CLONES_ATTR_SEPARATOR.  */
@@ -319,7 +325,24 @@ expand_target_clones (struct cgraph_node *node, bool 
definition)
   DECL_ATTRIBUTES (node->decl));
/* No targets specified.  */
if (!attr_target)
-return false;
+{


This seems to only apply the file specified versions if there is no 
attribute in the source code. I think this could be confusing to users.


My preference would be to merge the source code attr versions and the 
JSON file versions, but if you would rather not do that then I think we 
should at least issue a warning acknowledging the conflict.



+  /* Skip functions that are declared but not defined.  */
+  if (DECL_INITIAL (node->decl) != NULL_TREE)
+   {
+ auto it = clone_map.find (IDENTIFIER_POINTER (
+  

Re: [RFC PATCH v2 0/3] Add -ftarget-clones-table option support

2025-06-30 Thread Alfie Richards

Hi Yangyu,

The design of this looks really good to me. Thanks for your work on it.

I really appreciate how you made the JSON structure work for all targets.

Out of curiosity, have you thought about what happens in the case of an 
invalid target version string?


There will be some conflicts to iron out between this and the FMV 
refactor series I have working through review. But I am happy to manage 
that when my patch series lands.


Kind regards,
Alfie

On 29/06/2025 19:55, Yangyu Chen wrote:

This patch series introduces support for the target_clones table
option in GCC. This option enables users to specify target_clones
attributes in a separate file, allowing GCC to generate multiple
versions of the function with different ISA extensions based on the
specified table. This is achieved using the -ftarget-clones-table
option.

The primary objective of this patch series is to provide a
user-friendly way to specify target_clones attributes without
modifying the source code. This approach enhances the source code's
cleanliness, facilitates easier maintenance, and ensures portability
across different architectures and compiler versions.

A example usage is shown below:

Say we have a function `foo` in C source code `foo.c`.

Then we have a target clones table file `target_clones.json`:

```json
{
   "foo": {
 "x86_64": ["avx2", "avx512f"],
 "riscv64": ["arch=+v", "arch=+zba,+zbb", ...],
 ... // more architectures
   },
   // more functions
}
```

Then use: `gcc -O3 -ftarget-clones-table=target_clones.json -S foo.c`
to compile the source code. This will generate multiple versions of
the `foo` function with the specified target clones attributes for
each architecture.

I understand that this patch lacks comprehensive documentation and
test cases, as I am still in the process of writing them.
However, I would appreciate feedback on the implementation before
adding them. If the implementation is deemed acceptable, I
will proceed with writing the documentation and test cases.

Changes in v2:
- Use the name of "-ftarget-clones-table" instead of "-ftarget-profile"
- Use JSON formatted table instead of a text file
- Each architectures like x86_64, aarch64, riscv64, etc. Can specify
   multiple target clones attributes in a single JSON table, which
   makes it more flexible and easier to use.

v1: 
https://patchwork.sourceware.org/project/gcc/cover/tencent_7e345ef1390b9a68a738cee15ec510864...@qq.com/


Yangyu Chen (3):
   Fortran: Do not make_decl_rtl in trans_function_start
   json: add iterate method to object class
   Add -ftarget-clones-table option support

  gcc/Makefile.in   |   1 +
  gcc/common.opt|   7 +++
  gcc/fortran/trans-decl.cc |   3 -
  gcc/json.h|   5 ++
  gcc/multiple_target.cc| 124 +-
  5 files changed, 134 insertions(+), 6 deletions(-)





Re: [PATCH v4 2/6] dwarf: create annotation DIEs for btf tags

2025-06-30 Thread Richard Biener
On Tue, Jun 10, 2025 at 11:41 PM David Faust  wrote:
>
> The btf_decl_tag and btf_type_tag attributes provide a means to annotate
> declarations and types respectively with arbitrary user provided
> strings.  These strings are recorded in debug information for
> post-compilation uses, and despite the name they are meant to be
> recorded in DWARF as well as BTF.  New DWARF extensions
> DW_TAG_GNU_annotation and DW_AT_GNU_annotation are used to represent
> these user annotations in DWARF.
>
> This patch introduces the new DWARF extension DIE and attribute, and
> generates them as necessary to represent user annotations from
> btf_decl_tag and btf_type_tag.
>
> The format of the new DIE is as follows:
>
> DW_TAG_GNU_annotation
> DW_AT_name: "btf_decl_tag" or "btf_type_tag"
> DW_AT_const_value: 
> DW_AT_GNU_annotation: 
>
> DW_AT_GNU_annotation is a new attribute extension used to refer to these
> new annotation DIEs.  If non-null in any given declaration or type DIE,
> it is a reference to a DW_TAG_GNU_annotation DIE holding an annotation
> for that declaration or type.  In addition, the DW_TAG_GNU_annotation
> DIEs may also have a non-null DW_AT_GNU_annotation, referring to another
> annotation DIE.  This allows chains of annotation DIEs to be formed,
> such as in the case where a single declaration has multiple instances of
> btf_decl_tag with different string annotations.

Mostly looks good to me, I'd like to see a 2nd ack on the design.

Also see below for an issue I still have with this.

> gcc/
> * dwarf2out.cc (struct annotation_node, struct annotation_node_hasher)
> (btf_tag_htab): New ancillary structures and hash table.
> (annotation_node_hasher::hash, annotation_node_hasher::equal): New.
> (hash_btf_tag, gen_btf_tag_dies, gen_btf_type_tag_dies)
> (maybe_gen_btf_type_tag_dies, gen_btf_decl_tag_dies): New functions.
> (modified_type_die): Handle btf_type_tag attribute.
> (gen_array_type_die): Call maybe_gen_btf_type_tags for the type.
> (gen_formal_parameter_die): Call gen_btf_decl_tags for the parameter.
> (gen_decl_die): Call gen_btf_decl_tags for the decl.
> (gen_tagged_type_die): Call maybe_gen_btf_type_tag_dies for the type.
> (dwarf2out_early_finish): Empty btf_tag_htab hash table.
> (dwarf2out_cc_finalize): Delete btf_tag_htab hash table.
>
> include/
> * dwarf2.def (DW_TAG_GNU_annotation): New DWARF extension.
> (DW_AT_GNU_annotation): Likewise.
>
> gcc/testsuite/
> * gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-1.c: New test.
> * gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-2.c: New test.
> * gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-3.c: New test.
> * gcc.dg/debug/dwarf2/dwarf-btf-type-tag-1.c: New test.
> * gcc.dg/debug/dwarf2/dwarf-btf-type-tag-2.c: New test.
> * gcc.dg/debug/dwarf2/dwarf-btf-type-tag-3.c: New test.
> * gcc.dg/debug/dwarf2/dwarf-btf-type-tag-4.c: New test.
> * gcc.dg/debug/dwarf2/dwarf-btf-type-tag-5.c: New test.
> * gcc.dg/debug/dwarf2/dwarf-btf-type-tag-6.c: New test.
> * gcc.dg/debug/dwarf2/dwarf-btf-type-tag-7.c: New test.
> ---
>  gcc/dwarf2out.cc  | 308 +-
>  .../debug/dwarf2/dwarf-btf-decl-tag-1.c   |  11 +
>  .../debug/dwarf2/dwarf-btf-decl-tag-2.c   |  25 ++
>  .../debug/dwarf2/dwarf-btf-decl-tag-3.c   |  21 ++
>  .../debug/dwarf2/dwarf-btf-type-tag-1.c   |  10 +
>  .../debug/dwarf2/dwarf-btf-type-tag-2.c   |  31 ++
>  .../debug/dwarf2/dwarf-btf-type-tag-3.c   |  15 +
>  .../debug/dwarf2/dwarf-btf-type-tag-4.c   |  34 ++
>  .../debug/dwarf2/dwarf-btf-type-tag-5.c   |  10 +
>  .../debug/dwarf2/dwarf-btf-type-tag-6.c   |  27 ++
>  .../debug/dwarf2/dwarf-btf-type-tag-7.c   |  19 ++
>  include/dwarf2.def|   4 +
>  12 files changed, 511 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-3.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-type-tag-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-type-tag-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-type-tag-3.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-type-tag-4.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-type-tag-5.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-type-tag-6.c
>  create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-type-tag-7.c
>
> diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
> index d1a55dbcbcb..5b8ed47044f 100644
> --- a/gcc/dwarf2out.cc
> +++ b/gcc/dwarf2out.cc
> @@ -3696,6 +3696,33 @@ static bool frame_pointer_fb_offset_valid;
>
>  stat

Re: [Fortran, Patch, PR120843, v2] Fix reject valid, because of inconformable coranks

2025-06-30 Thread Andre Vehreschild
Hi all,

here now the version of the patch that seems to be more complete. 

Regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline and later backport to
gcc-15?

Regards,
Andre

On Fri, 27 Jun 2025 15:44:20 +0200
Andre Vehreschild  wrote:

> I take this patch back. It seems to be incomplete.
> 
> - Andre
> 
> On Fri, 27 Jun 2025 14:45:36 +0200
> Andre Vehreschild  wrote:
> 
> > Hi all,
> > 
> > this patch fixes a reject valid when the coranks of two operands do not
> > match and no coindex is given. I.e. when only an implicit this_image co-ref
> > is used.
> > 
> > Regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline?
> > 
> > Regards,
> > Andre  
> 
> 


-- 
Andre Vehreschild * Email: vehre ad gmx dot de 
From 427ab489cefe47b801a29e0642d2eedc20474053 Mon Sep 17 00:00:00 2001
From: Andre Vehreschild 
Date: Fri, 27 Jun 2025 14:39:13 +0200
Subject: [PATCH] Fortran: Fix non-conformable corank on this_image ref
 [PR120843]

	PR fortran/120843

gcc/fortran/ChangeLog:

	* resolve.cc (resolve_operator): Report inconsistent coranks
	only when not referencing this_image.
	(gfc_op_rank_conformable): Treat coranks as inconformable only
	when a coindex other then implicit this_image is used.

gcc/testsuite/ChangeLog:

	* gfortran.dg/coarray/coindexed_6.f90: New test.
---
 gcc/fortran/resolve.cc  |  7 ---
 .../gfortran.dg/coarray/coindexed_6.f90 | 17 +
 2 files changed, 21 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/coarray/coindexed_6.f90

diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 58f7aee29c3..50a6fe7fc52 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -4828,7 +4828,8 @@ resolve_operator (gfc_expr *e)
 	  if (e->shape == NULL)
 	e->shape = gfc_copy_shape (op2->shape, op2->corank);
 	}
-  else
+  else if ((op1->ref && !gfc_ref_this_image (op1->ref))
+	   || (op2->ref && !gfc_ref_this_image (op2->ref)))
 	{
 	  gfc_error ("Inconsistent coranks for operator at %L and %L",
 		 &op1->where, &op2->where);
@@ -6070,8 +6071,8 @@ gfc_op_rank_conformable (gfc_expr *op1, gfc_expr *op2)
 gfc_expression_rank (op2);
 
   return (op1->rank == 0 || op2->rank == 0 || op1->rank == op2->rank)
-	 && (op1->corank == 0 || op2->corank == 0
-	 || op1->corank == op2->corank);
+	 && (op1->corank == 0 || op2->corank == 0 || op1->corank == op2->corank
+	 || (!gfc_is_coindexed (op1) && !gfc_is_coindexed (op2)));
 }
 
 /* Resolve a variable expression.  */
diff --git a/gcc/testsuite/gfortran.dg/coarray/coindexed_6.f90 b/gcc/testsuite/gfortran.dg/coarray/coindexed_6.f90
new file mode 100644
index 000..8f5dcabb859
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray/coindexed_6.f90
@@ -0,0 +1,17 @@
+!{ dg-do compile }
+
+! Check PR120843 is fixed
+
+program p
+  implicit none
+
+  integer, allocatable :: arr(:,:) [:,:]
+  integer :: c[*]
+
+  c = 7
+
+  allocate(arr(4,3)[2,*], source=6)
+
+  if (arr(2,2)* c /= 42) stop 1
+
+end program p
-- 
2.50.0



[PATCH v3] AArch64 SIMD: convert mvn+shrn into mvni+subhn

2025-06-30 Thread Remi Machet
Hi,

Attached is the updated patch for the aarch64 conversion of some 
mvn+shrn patterns into a mvni+subhn. Hopefully attachment fixes the tab 
issues, the cover letter was updated to better explain what the patch 
does, code was changed to use emit_move_insn, and testcase was cleaned 
up per Richard and Alex's suggestions.

Sorry for the delay in fixing all suggestions but I was traveling for 
the past 2 weeks.

Remi
From 102b7358be9d030f9f518c2accd329d14fe545a3 Mon Sep 17 00:00:00 2001
From: Remi Machet 
Date: Fri, 13 Jun 2025 18:44:53 +
Subject: [PATCH v3] AArch64 SIMD: convert mvn+shrn into mvni+subhn

Add an optimization to aarch64 SIMD converting mvn+shrn into mvni+subhn when
possible, which allows for better optimization when the code is inside a loop
by using a constant.

The conversion is based on the fact that for an unsigned integer:
  -x = ~x + 1 => ~x = -1 - x
thus '(u8)(~x >> imm)' is equivalent to '(u8)(((u16)-1 - x) >> imm)'.

For the following function:
uint8x8_t neg_narrow_v8hi(uint16x8_t a) {
  uint16x8_t b = vmvnq_u16(a);
  return vshrn_n_u16(b, 8);
}

Without this patch the assembly look like:
not v0.16b, v0.16b
shrnv0.8b, v0.8h, 8

After the patch it becomes:
mvniv31.4s, 0
subhn   v0.8b, v31.8h, v0.8h

Bootstrapped and regtested on aarch64-linux-gnu.

Signed-off-by: Remi Machet 

gcc/ChangeLog:

* config/aarch64/aarch64-simd.md (*shrn_to_subhn_): Add pattern
converting mvn+shrn into mvni+subhn.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/simd/shrn2subhn.c: New test.
---
 gcc/config/aarch64/aarch64-simd.md| 30 
 .../gcc.target/aarch64/simd/shrn2subhn.c  | 36 +++
 2 files changed, 66 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c

diff --git a/gcc/config/aarch64/aarch64-simd.md 
b/gcc/config/aarch64/aarch64-simd.md
index 6e30dc48934..29796f7cf1b 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -5028,6 +5028,36 @@
   DONE;
 })
 
+;; convert (truncate)(~x >> imm) into (truncate)(((u16)-1 - x) >> imm)
+;; because it will result in the 'not' being replaced with a constant load
+;; which allows for better loop optimization.
+;; We limit this to truncations that take the upper half and shift it to the
+;; lower half as we use subhn (patterns that would have generated an shrn
+;; otherwise).
+;; On some implementations the use of subhn also result in better throughput.
+(define_insn_and_split "*shrn_to_subhn_"
+  [(set (match_operand: 0 "register_operand" "=&w")
+   (truncate:
+ (lshiftrt:VQN
+   (not:VQN (match_operand:VQN 1 "register_operand" "w"))
+   (match_operand:VQN 2 "aarch64_simd_shift_imm_vec_exact_top"]
+  "TARGET_SIMD"
+  "#"
+  "&& true"
+  [(const_int 0)]
+{
+  rtx tmp;
+  if (can_create_pseudo_p ())
+tmp = gen_reg_rtx (mode);
+  else
+tmp = gen_rtx_REG (mode, REGNO (operands[0]));
+  emit_move_insn (tmp, CONSTM1_RTX (mode));
+  emit_insn (gen_aarch64_subhn_insn (operands[0], tmp,
+  operands[1], operands[2]));
+  DONE;
+})
+
+
 ;; pmul.
 
 (define_insn "aarch64_pmul"
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c 
b/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c
new file mode 100644
index 000..f90ea134f09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c
@@ -0,0 +1,36 @@
+/* This test case checks that replacing a not+shift by a sub -1 works. */
+/* { dg-do compile } */
+/* { dg-additional-options "-O1" } */
+/* { dg-final { scan-assembler-times "\\tsubhn\\t" 6 } } */
+
+#include
+
+uint8x8_t neg_narrow_v8hi(uint16x8_t a) {
+  uint16x8_t b = vmvnq_u16(a);
+  return vshrn_n_u16(b, 8);
+}
+
+uint8x8_t neg_narrow_vsubhn_v8hi(uint16x8_t a) {
+  uint16x8_t ones = vdupq_n_u16(0x);
+  return vsubhn_u16(ones, a);
+}
+
+uint16x4_t neg_narrow_v4si(uint32x4_t a) {
+  uint32x4_t b = vmvnq_u32(a);
+  return vshrn_n_u32(b, 16);
+}
+
+uint16x4_t neg_narrow_vsubhn_v4si(uint32x4_t a) {
+  uint32x4_t ones = vdupq_n_u32(0x);
+  return vsubhn_u32(ones, a);
+}
+
+uint32x2_t neg_narrow_v2di(uint64x2_t a) {
+  uint64x2_t b = ~a;
+  return vshrn_n_u64(b, 32);
+}
+
+uint32x2_t neg_narrow_vsubhn_v2di(uint64x2_t a) {
+  uint64x2_t ones = vdupq_n_u64(0x);
+  return vsubhn_u64(ones, a);
+}
-- 
2.34.1



Re: [PATCH v7 0/3] extend "counted_by" attribute to pointer fields of structures

2025-06-30 Thread Qing Zhao
Hi,  Richard or Jakub,

Could you please approve the Middle-end part of this patch set?  (Patch #2)

(The C FE part of the patch, Patch #1 and #3 have been approved by Joseph 
already;
 The Middle-end part of the patch has been reviewed by Sid and Richard, I have 
included
  all the changes based on their comments in this version.)

Thanks a lot.

Qing

> On Jun 24, 2025, at 15:29, Qing Zhao  wrote:
> 
> This is the 7th version of the patch set to extend "counted_by" attribute
> to pointer fields of structures.
> 
> The C FE parts (patch #1 and #3) of the 5th version have been approved
> by Joseph already (with a minor typo fix, which is included in this new 
> version);
> 
> The middle end part (patch #2) of the 6th version was reviewed by Sid and 
> Richard,
> Sid raised several format issues in testing cases, and Richard raised one 
> issue
> in tree-object-size.cc. 
> 
> In this 7th version, I fixed all the format issues in testing cases and also 
> the one
> issue in tree-object-size.cc raised by Richard. 
> 
> The whole patch set has been bootstrapped and regression tested on both 
> aarch64 and x86.
> 
> Okay for trunk?
> 
> Thanks a lot.
> 
> Qing



Re: [Patch, Fortran, Coarray, PR88076, v1] 0/6 Add a shared memory multi process coarray library.

2025-06-30 Thread Steve Kargl
Andre,

I've never built gcc for aarch64-freebsd.  I was going to
suggest doing the full bootstrap, but that seems to be too
slow.  On amd64, I use

../gcc/configure --prefix=$WDIR \
   --enable-languages=c,c++,fortran,lto \
   --enable-bootstrap \
   --disable-nls \
   --disable-libssp \
   --disable-multilib \
   --without-libintl

I looked at the FreeBSD ports collection and how it builds
gcc16.  I did not see missing --enable-* or --disable-*.
If you have the ports collection installed in the vm, you
can do 

cd /usr/ports/lang/gcc16-devel
make config |& tee logfile

to see if the port is doing anything to mitigate the issue.
Note, you might need 'make configure'.  This likely a slow
process as it downloads the source code and computes a md5
and then uncompresses.

(more below)

On Mon, Jun 30, 2025 at 03:40:33PM +0200, Andre Vehreschild wrote:
> 
> how to you get a recent gcc compile on aarch64-freebsd-14.3 ? I am seeing
> several issues in core libraries of gcc that are far away from where I touched
> the compiler.
> 
> I am configuring with:
> 
> configure --disable-multilib\
>--enable-stage1-languages=c,fortran,c++\
>--enable-checking=yes \
>--enable-offload-defaulted \
>--prefix="${INSTALLPATH}" \
>CFLAGS="-g -O0 -DENABLE_ASSERT_CHECKING" CXXFLAGS="-g 
> -O0"\
>STAGE1_CFLAGS="-g -O0 -DENABLE_ASSERT_CHECKING" 
> STAGE1_CXXFLAGS="-g -O0"
> 
> Yes, I am doing only stage1. I run this fully virtualized and it is slow. I
> don't want to wait three days for a full bootstrap.
> 
> One of the errors I get is:
> 
> /libgcc/unwind-dw2-fde-dip.c:69:10: error: 'ElfW' redefined [-Werror]
>69 | # define ElfW __ElfN
>   |  ^~~~
> In file included from /usr/include/machine/elf.h:45,
>  from /usr/include/elf.h:37,
>  from /gcc/gcc.test/libgcc/unwind-dw2-fde-dip.c:36:
> /usr/include/sys/elf_generic.h:59:9: note: this is the location of the 
> previous
> definition 
> 59 | #define ElfW(x) __ElfN(x)
>  | ^~~~
> 
> Have you ever seen this before and know a way around it?
> 

I've not seen this error.  elf_generic.h. has the comment

/* Define ElfW for compatibility with Linux, prefer __ElfN() in FreeBSD code */
#define ElfW(x) __ElfN(x)

perhaps, just deleteing the line will allow you to proceed.

-- 
Steve


Re: [PATCH] libphobos: Fully enable Darwin/i386 support

2025-06-30 Thread Iain Sandoe
Hi Rainer,

> On 30 Jun 2025, at 12:58, Rainer Orth  wrote:
> 
> I recently noticed that libphobos isn't enable by default on 32-bit
> Darwin with the target triples determined by config.guess.  E.g. on a
> Darwin 15 system the target triple is something like
> i386-apple-darwin15.6.0 while configure.tgt only matches
> i?86-*-darwin1[2-7].
> 
> This patch also allows such minor and micro versions.
> 
> Tested on i386-apple-darwin15.6.0.
> 
> I'd commit this as obvious, but there's more: on older Darwin versions
> (9, 10, and 11), configure.tgt only sets LIBDRUNTIME_ONLY.

For Darwin9 the xcode linker is not new enough to work (it needs at least
the Darwin10 linker).  IIRC Darwin10 has some missing libc functionality
that the wider libphobos (at least used to) uses.  I’d imagine some of the
fails you see on Darwin11 could be in a similar category.

>  However,
> toplevel configure.ac doesn't take this into account when deciding
> whether to enable libphobos or not.  I wonder if it should, though.`

I *think* that’s right - we want to enable libphobos but only the minimal
druntime?

>  I
> guess it could: on my Darwin 11 system, test results (with explicit
> --enable-libphobos) aren't too bad:


> 
> 
> Thoughts?

Certainly, the configure.tgt fix is OK - that’s a slip-up.  It’s also OK
to enable libphobos for Darwin11 if that’s going to get reasonable testing,
but I was not planning on trying to fix outstanding issues there.

I would avoid Darwin10 for now, and Darwin <= 9 is a non-starter
without some additional configury to detect a usable linker version.

thanks
Iain


> 
>   Rainer
> 
> -- 
> -
> Rainer Orth, Center for Biotechnology, Bielefeld University
> 
> 
> 2025-06-30  Rainer Orth  
> 
>   libphobos:
>   * configure.tgt : Also consider minor
>   versions supported.
> 
> # HG changeset patch
> # Parent  6faf58fc5f919a561f8bb1df3fc2f1cfd3d67e5e
> libphobos: Fully enable Darwin/i386 support
> 
> diff --git a/libphobos/configure.tgt b/libphobos/configure.tgt
> --- a/libphobos/configure.tgt
> +++ b/libphobos/configure.tgt
> @@ -64,7 +64,7 @@ case "${target}" in
>   *-*-darwin9* | *-*-darwin1[01]*)
>   LIBDRUNTIME_ONLY=yes
>   ;;
> -  x86_64-*-darwin1[2-9]* | x86_64-*-darwin2* | i?86-*-darwin1[2-7])
> +  x86_64-*-darwin1[2-9]* | x86_64-*-darwin2* | i?86-*-darwin1[2-7]*)
>   LIBPHOBOS_SUPPORTED=yes
>   ;;
>   x86_64-*-freebsd* | i?86-*-freebsd*)



Re: [PATCH v6 1/3][Middle-end] Provide more contexts for -Warray-bounds, -Wstringop-*warning messages due to code movements from compiler transformation (Part 1) [PR109071,PR85788,PR88771,PR106762,PR1

2025-06-30 Thread Qing Zhao



> On Jun 27, 2025, at 15:24, Kees Cook  wrote:
> 
> On Fri, Jun 27, 2025 at 01:38:51PM +, Qing Zhao wrote:
>> The good news is:  With the above simple heuristic and a simple back tracing 
>> of  the CFG, all the 
>> current testing cases for the following PRs passed without any issue:  
>> 
>> PR109071
>> PR88771
>> PR85788
>> PR108770
>> PR106762
>> PR115274
>> PR117179
>> 
>> I will continue working on this to add more testing cases and also more 
>> warnings per the following discussion:
>> https://gcc.gnu.org/pipermail/gcc-patches/2025-May/684126.html
>> https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686323.html
>> https://gcc.gnu.org/pipermail/gcc-patches/2025-June/685852.html
>> https://gcc.gnu.org/pipermail/gcc-patches/2025-June/685854.html
>> 
>> Let me know if you have any comments or suggestions.
> 
> Thanks great!
> 
> Here are the patches I got landed in Linux that were uncovered using the
> earlier -fdiagnostics-details implementation:
> 
> https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?qt=grep&q=diagnostics-details
> 
> Reverting these patches show the warnings again for me. If you want to
> test them against the new implementation, this should work:
> 
> ### Set up build...
> 
> $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> $ cd linux
> $ git revert --no-edit 8a39f1c870e9d6fbac5638f3a42a6a6363829c49
> $ git revert --no-edit 4a6f18f28627e121bd1f74b5fcc9f945d6dbeb1e
> $ git revert --no-edit 239d87327dcd361b0098038995f8908f3296864f
> $ git revert --no-edit ac6f0825e582f2216a582c9edf0cee7bfe347ba6
> $ CPUS=$(getconf _NPROCESSORS_ONLN)
> $ FLAGS="-Warray-bounds -fdiagnostic-show-context=1"
> $ make -j$CPUS KCFLAGS="$FLAGS" allmodconfig
> 
> # These three targets are stable, the 4th one is harder to hit, so
> # I've left it off (kernel/padata.o):
> 
> $ make -j$CPUS KCFLAGS="$FLAGS" fs/overlayfs/util.o
> $ make -j$CPUS KCFLAGS="$FLAGS" drivers/net/ethernet/mellanox/mlx4/alloc.o
> $ make -j$CPUS KCFLAGS="$FLAGS" drivers/pinctrl/mediatek/pinctrl-airoha.o

Thanks, I will try this with the new implementation on my side first.
> 
> 
> If you prefer, I can also do this once the new implementation is posted. :)

If there is any issue during my testing, I will let you know at that time.

Thanks a lot.

Qing
> 
> -Kees
> 
> -- 
> Kees Cook



[Fortran, Patch, PR120846, v1] Fix ICE when a function is called more than once in a coarray expression.

2025-06-30 Thread Andre Vehreschild
Hi all,

attached patch fixes an ICE when in an expression with a coindex a function was
used more than once. E.g. coarray(mod( something ), mod( something else ))[i]
ICE'd because a component for aliasing the second mod() could not be created.

Regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline and gcc-15 later on?

Regards,
Andre
-- 
Andre Vehreschild * Email: vehre ad gmx dot de 
From e4d4dd9768f7797e30542ec99b16093a663c65f3 Mon Sep 17 00:00:00 2001
From: Andre Vehreschild 
Date: Fri, 27 Jun 2025 15:31:21 +0200
Subject: [PATCH] Fortran: Ensure arguments in coarray call get unique
 components in add_data [PR120847]

	PR fortran/120847

gcc/fortran/ChangeLog:

	* coarray.cc (check_add_new_comp_handle_array): Make the count
	of components static to be able to create more than one.  Create
	an array component only for array expressions.

gcc/testsuite/ChangeLog:

	* gfortran.dg/coarray/coindexed_7.f90: New test.
---
 gcc/fortran/coarray.cc|  4 ++--
 .../gfortran.dg/coarray/coindexed_7.f90   | 24 +++
 2 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90

diff --git a/gcc/fortran/coarray.cc b/gcc/fortran/coarray.cc
index 2f067f855e5..6914697c78b 100644
--- a/gcc/fortran/coarray.cc
+++ b/gcc/fortran/coarray.cc
@@ -503,7 +503,7 @@ check_add_new_comp_handle_array (gfc_expr *e, gfc_symbol *type,
  gfc_symbol *add_data)
 {
   gfc_component *comp;
-  int cnt = -1;
+  static int cnt = -1;
   gfc_symtree *caller_image;
   gfc_code *pre_code = caf_accessor_prepend;
   bool static_array_or_scalar = true;
@@ -566,7 +566,7 @@ check_add_new_comp_handle_array (gfc_expr *e, gfc_symbol *type,
   else
 {
   comp->initializer = gfc_copy_expr (e);
-  if (e_attr.dimension)
+  if (e_attr.dimension && e->rank)
 	{
 	  comp->attr.dimension = 1;
 	  comp->as = get_arrayspec_from_expr (e);
diff --git a/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90 b/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90
new file mode 100644
index 000..066397024f4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90
@@ -0,0 +1,24 @@
+!{ dg-do compile }
+
+! Check PR120847 is fixed.
+
+program p
+  implicit none
+
+  type T
+integer, allocatable :: i(:, :) [:]
+  end type T
+
+  type(T) :: o
+  integer, allocatable :: c[:]
+  integer :: i
+
+  c = 7
+
+  allocate(o%i(4, 5)[*], source=6)
+
+  do i = 1, 4
+c = o%i(mod(i, 2), mod(i, 3))[1]
+  end do
+
+end program p
-- 
2.50.0



Re: [Patch, Fortran, Coarray, PR88076, v1] 0/6 Add a shared memory multi process coarray library.

2025-06-30 Thread Andre Vehreschild
Hi Steve,

how to you get a recent gcc compile on aarch64-freebsd-14.3 ? I am seeing
several issues in core libraries of gcc that are far away from where I touched
the compiler.

I am configuring with:

configure --disable-multilib\
 --enable-stage1-languages=c,fortran,c++\
 --enable-checking=yes \
 --enable-offload-defaulted \
 --prefix="${INSTALLPATH}" \
 CFLAGS="-g -O0 -DENABLE_ASSERT_CHECKING" CXXFLAGS="-g 
-O0"\
 STAGE1_CFLAGS="-g -O0 -DENABLE_ASSERT_CHECKING" 
STAGE1_CXXFLAGS="-g -O0"

Yes, I am doing only stage1. I run this fully virtualized and it is slow. I
don't want to wait three days for a full bootstrap.

One of the errors I get is:

/libgcc/unwind-dw2-fde-dip.c:69:10: error: 'ElfW' redefined [-Werror]
   69 | # define ElfW __ElfN
  |  ^~~~
In file included from /usr/include/machine/elf.h:45,
 from /usr/include/elf.h:37,
 from /gcc/gcc.test/libgcc/unwind-dw2-fde-dip.c:36:
/usr/include/sys/elf_generic.h:59:9: note: this is the location of the previous
definition 
59 | #define ElfW(x) __ElfN(x)
 | ^~~~

Have you ever seen this before and know a way around it?

Regards,
Andre

On Sun, 29 Jun 2025 22:02:38 -0700
Steve Kargl  wrote:

> On Sun, Jun 29, 2025 at 06:54:53PM -0700, Steve Kargl wrote:
> > On Sun, Jun 29, 2025 at 03:30:21PM -0700, Steve Kargl wrote:  
> > > On Sun, Jun 29, 2025 at 11:07:31AM -0700, Steve Kargl wrote:  
> > > > On Sun, Jun 29, 2025 at 10:35:39AM -0700, Steve Kargl wrote:  
> > > > > 
> > > > > === gfortran Summary ===
> > > > > 
> > > > > # of expected passes73149
> > > > > # of unexpected failures522  
> > >   
> 
> After forcefully adding '#include ', '#include ',
> and 'extern char **environ' where needed.  I now see
> 
> === gfortran Summary ===
> 
> # of expected passes73561
> # of unexpected failures110
> # of expected failures  343
> # of unresolved testcases   78
> # of unsupported tests  94
> 
> for 'gmake check-fortran', and if I use RUNTESTFLAGS='dg.exp=\*unsign\*'
> to test the unsigned issue reported earlier, I see
> 
> === gfortran Summary ===
> 
> # of expected passes434
> # of unsupported tests  6
> /home/kargl/gcc/obj/gcc/gfortran  version 16.0.0 20250629 (experimental)
> (GCC) 
> 
> I suspect we'll need to have
> 
> #include "config.h"
> 
> #indef HAVE_UNISTD_H
> #include 
> #endif
> 
> and similar for other headers files.  I further suspect that this
> are going to be rough on CYWIN/MINGW.
> 
> 


-- 
Andre Vehreschild * Email: vehre ad gmx dot de 


[COMMITTED 33/40] ada: Remove uses of E_Void for subtype declarations

2025-06-30 Thread Marc Poulhiès
From: Ronan Desplanques 

This patch slightly reorganizes Analyze_Subtype_Declaration so that the
proper Ekind of the new subtype's entity is set before anything else is
done with it. A new local subprogram is introduced in the process.

gcc/ada/ChangeLog:

* sem_ch3.adb (Analyze_Subtype_Declaration): Remove uses of E_Void.
(Copy_Parent_Attributes): New procedure.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_ch3.adb | 43 ++-
 1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 425d624f031..b39a3514031 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -5737,6 +5737,25 @@ package body Sem_Ch3 is
   Id : constant Entity_Id := Defining_Identifier (N);
   T  : Entity_Id;
 
+  procedure Copy_Parent_Attributes;
+  --  Copy fields that don't depend on the type kind from the subtype
+  --  denoted by the subtype mark.
+
+  
+  -- Copy_Parent_Attributes --
+  
+
+  procedure Copy_Parent_Attributes is
+  begin
+ Set_Etype (Id, Base_Type (T));
+ Set_Is_Volatile (Id, Is_Volatile (T));
+ Set_Treat_As_Volatile (Id, Treat_As_Volatile (T));
+ Set_Is_Generic_Type (Id, Is_Generic_Type (Base_Type (T)));
+ Set_Convention (Id, Convention (T));
+  end Copy_Parent_Attributes;
+
+   --  Start of processing for Analyze_Subtype_Declaration
+
begin
   Generate_Definition (Id);
   Set_Is_Pure (Id, Is_Pure (Current_Scope));
@@ -5803,13 +5822,6 @@ package body Sem_Ch3 is
  T := Full_View (T);
   end if;
 
-  --  Inherit common attributes
-
-  Set_Is_Volatile   (Id, Is_Volatile   (T));
-  Set_Treat_As_Volatile (Id, Treat_As_Volatile (T));
-  Set_Is_Generic_Type   (Id, Is_Generic_Type   (Base_Type (T)));
-  Set_Convention(Id, Convention(T));
-
   --  If ancestor has predicates then so does the subtype, and in addition
   --  we must delay the freeze to properly arrange predicate inheritance.
 
@@ -5849,16 +5861,16 @@ package body Sem_Ch3 is
   --  semantic attributes must be established here.
 
   if Nkind (Subtype_Indication (N)) /= N_Subtype_Indication then
- Set_Etype (Id, Base_Type (T));
-
  case Ekind (T) is
 when Array_Kind =>
Mutate_Ekind  (Id, E_Array_Subtype);
+   Copy_Parent_Attributes;
Copy_Array_Subtype_Attributes (Id, T);
Set_Packed_Array_Impl_Type(Id, Packed_Array_Impl_Type (T));
 
 when Decimal_Fixed_Point_Kind =>
Mutate_Ekind (Id, E_Decimal_Fixed_Point_Subtype);
+   Copy_Parent_Attributes;
Set_Digits_Value (Id, Digits_Value   (T));
Set_Delta_Value  (Id, Delta_Value(T));
Set_Scale_Value  (Id, Scale_Value(T));
@@ -5871,6 +5883,7 @@ package body Sem_Ch3 is
 
 when Enumeration_Kind =>
Mutate_Ekind (Id, E_Enumeration_Subtype);
+   Copy_Parent_Attributes;
Set_First_Literal(Id, First_Literal (Base_Type (T)));
Set_Scalar_Range (Id, Scalar_Range   (T));
Set_Is_Character_Type(Id, Is_Character_Type  (T));
@@ -5880,6 +5893,7 @@ package body Sem_Ch3 is
 
 when Ordinary_Fixed_Point_Kind =>
Mutate_Ekind  (Id, E_Ordinary_Fixed_Point_Subtype);
+   Copy_Parent_Attributes;
Set_Scalar_Range (Id, Scalar_Range   (T));
Set_Small_Value  (Id, Small_Value(T));
Set_Delta_Value  (Id, Delta_Value(T));
@@ -5889,6 +5903,7 @@ package body Sem_Ch3 is
 
 when Float_Kind =>
Mutate_Ekind (Id, E_Floating_Point_Subtype);
+   Copy_Parent_Attributes;
Set_Scalar_Range (Id, Scalar_Range   (T));
Set_Digits_Value (Id, Digits_Value   (T));
Set_Is_Constrained   (Id, Is_Constrained (T));
@@ -5898,6 +5913,7 @@ package body Sem_Ch3 is
 
 when Signed_Integer_Kind =>
Mutate_Ekind (Id, E_Signed_Integer_Subtype);
+   Copy_Parent_Attributes;
Set_Scalar_Range (Id, Scalar_Range   (T));
Set_Is_Constrained   (Id, Is_Constrained (T));
Set_Is_Known_Valid   (Id, Is_Known_Valid (T));
@@ -5905,6 +5921,7 @@ package body Sem_Ch3 is
 
 when Modular_Integer_Kind =>
Mutate_Ekind (Id, E_Modular_Integer_Subtype);
+   Copy_Parent_Attributes;
Set_Scalar_Range (Id, Scalar_Range   (T));

[COMMITTED 36/40] ada: Reuse Snames classification of reserved words

2025-06-30 Thread Marc Poulhiès
From: Ronan Desplanques 

Before this patch, Check_Future_Keyword had hardcoded lists of what
reserved words were introduced in what versions of the Ada language
specification. This patch makes it use the classification in Snames
instead.

gcc/ada/ChangeLog:

* par-util.adb (Check_Future_Keyword): Use Snames subtypes. Extend
comment.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/par-util.adb | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/gcc/ada/par-util.adb b/gcc/ada/par-util.adb
index 53b57e4c1bf..78a76b3b1f1 100644
--- a/gcc/ada/par-util.adb
+++ b/gcc/ada/par-util.adb
@@ -176,14 +176,17 @@ package body Util is
procedure Check_Future_Keyword is
begin
   --  Ada 2005 (AI-284): Compiling in Ada 95 mode we warn that INTERFACE,
-  --  OVERRIDING, and SYNCHRONIZED are new reserved words.
+  --  OVERRIDING, and SYNCHRONIZED are new reserved words. We make an
+  --  exception if INTERFACE is used in the context of the GNAT-specific
+  --  pragma Interface, since we accept that pragma regardless of the Ada
+  --  version.
 
   if Ada_Version = Ada_95
 and then Warn_On_Ada_2005_Compatibility
   then
- if Token_Name in Name_Overriding | Name_Synchronized
-   or else (Token_Name = Name_Interface
- and then Prev_Token /= Tok_Pragma)
+ if Token_Name in Ada_2005_Reserved_Words
+   and then not (Token_Name = Name_Interface
+ and then Prev_Token = Tok_Pragma)
  then
 Error_Msg_N ("& is a reserved word in Ada 2005?y?", Token_Node);
  end if;
@@ -194,13 +197,13 @@ package body Util is
   if Ada_Version in Ada_95 .. Ada_2005
 and then Warn_On_Ada_2012_Compatibility
   then
- if Token_Name = Name_Some then
+ if Token_Name in Ada_2012_Reserved_Words then
 Error_Msg_N ("& is a reserved word in Ada 2012?y?", Token_Node);
  end if;
   end if;
 
   if Ada_Version < Ada_With_All_Extensions then
- if Token_Name = Name_Finally then
+ if Token_Name in GNAT_Extensions_Reserved_Words then
 Error_Msg_N
   ("& is a reserved word with all extensions enabled?",
Token_Node);
-- 
2.43.0



[COMMITTED 27/40] ada: Ignore unchecked type conversions while getting enclosing object

2025-06-30 Thread Marc Poulhiès
From: Piotr Trojanek 

This patch both makes GNAT emit warnings on unused assignments where previously
they were suppressed for obscure reasons and synchronizes routine
Get_Enclosing_Object with a similar routine in GNATprove (which differs in
handling of explicit dereferences).

gcc/ada/ChangeLog:

* sem_util.adb (Get_Enclosing_Object): Traverse unchecked type
conversions since they from the compiler and should be transparent for
semantic reasoning.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_util.adb | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 3c2a776ce36..127728ab601 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -10314,7 +10314,9 @@ package body Sem_Util is
 =>
return Get_Enclosing_Object (Prefix (N));
 
-when N_Type_Conversion =>
+when N_Type_Conversion
+   | N_Unchecked_Type_Conversion
+=>
return Get_Enclosing_Object (Expression (N));
 
 when others =>
-- 
2.43.0



[COMMITTED 10/40] ada: Add entity chain debug printing subprograms

2025-06-30 Thread Marc Poulhiès
From: Ronan Desplanques 

This patchs adds two pn-like subprograms that print entity chains.

gcc/ada/ChangeLog:

* treepr.ads (Print_Entity_Chain, pec, rpec): New subprograms.
* treepr.adb (Print_Entity_Chain, pec, rpec): Likewise.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/treepr.adb | 58 ++
 gcc/ada/treepr.ads | 14 +++
 2 files changed, 72 insertions(+)

diff --git a/gcc/ada/treepr.adb b/gcc/ada/treepr.adb
index 0f723ed25b2..d58f3ceb36f 100644
--- a/gcc/ada/treepr.adb
+++ b/gcc/ada/treepr.adb
@@ -412,6 +412,34 @@ package body Treepr is
 
procedure pe (N : Union_Id) renames pn;
 
+   -
+   -- pec --
+   -
+
+   procedure pec (From : Entity_Id) is
+   begin
+  Push_Output;
+  Set_Standard_Output;
+
+  Print_Entity_Chain (From);
+
+  Pop_Output;
+   end pec;
+
+   --
+   -- rpec --
+   --
+
+   procedure rpec (From : Entity_Id) is
+   begin
+  Push_Output;
+  Set_Standard_Output;
+
+  Print_Entity_Chain (From, Rev => True);
+
+  Pop_Output;
+   end rpec;
+

-- pl --

@@ -589,6 +617,36 @@ package body Treepr is
   end if;
end Print_End_Span;
 
+   
+   -- Print_Entity_Chain --
+   
+
+   procedure Print_Entity_Chain (From : Entity_Id; Rev : Boolean := False) is
+  Ent : Entity_Id := From;
+   begin
+  Printing_Descendants := False;
+  Phase := Printing;
+
+  loop
+ declare
+Next_Ent : constant Entity_Id :=
+  (if Rev then Prev_Entity (Ent) else Next_Entity (Ent));
+
+Prefix_Char : constant Character :=
+  (if Present (Next_Ent) then '|' else ' ');
+ begin
+Print_Node (Ent, "", Prefix_Char);
+
+exit when No (Next_Ent);
+
+Ent := Next_Ent;
+
+Print_Char ('|');
+Print_Eol;
+ end;
+  end loop;
+   end Print_Entity_Chain;
+
---
-- Print_Entity_Info --
---
diff --git a/gcc/ada/treepr.ads b/gcc/ada/treepr.ads
index f8a17fbfd79..43e518711e6 100644
--- a/gcc/ada/treepr.ads
+++ b/gcc/ada/treepr.ads
@@ -60,6 +60,12 @@ package Treepr is
--  Prints the subtree consisting of the given element list and all its
--  referenced descendants.
 
+   procedure Print_Entity_Chain (From : Entity_Id; Rev : Boolean := False);
+   --  Prints the entity chain From is on, starting from From. In other words,
+   --  prints From and then recursively follow the Next_Entity field. If Rev is
+   --  True, prints the chain backwards, i.e. follow the Last_Entity field
+   --  instead of Next_Entity.
+
--  The following debugging procedures are intended to be called from gdb.
--  Note that in several cases there are synonyms which represent historical
--  development, and we keep them because some people are used to them!
@@ -103,4 +109,12 @@ package Treepr is
--  on the left and add a minus sign. This just saves some typing in the
--  debugger.
 
+   procedure pec (From : Entity_Id);
+   pragma Export (Ada, pec);
+   --  Print From and the entities that follow it on its entity chain
+
+   procedure rpec (From : Entity_Id);
+   pragma Export (Ada, rpec);
+   --  Like pec, but walk the entity chain backwards. The 'r' stands for
+   --  "reverse".
 end Treepr;
-- 
2.43.0



[COMMITTED 15/40] ada: include header to declare isalpha in adaint

2025-06-30 Thread Marc Poulhiès
From: Alexandre Oliva 

A vxworks-specific part of adaint.c calls isalpha without including
ctype.h.  gcc-14 rejects calls of undeclared functions.  Include the
required header file when compiling for vxworks.

gcc/ada/ChangeLog:

* adaint.c [__vxworks]: Include ctype.h.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/adaint.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 63130e0f2bc..2f5bbf31f79 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -61,6 +61,7 @@
 #define POSIX
 #include "vxWorks.h"
 #include 
+#include  /* for isalpha */
 
 #if defined (__mips_vxworks)
 #include "cacheLib.h"
-- 
2.43.0



Re: [PATCH] c++: Fix up cp_build_array_ref COND_EXPR handling [PR120471]

2025-06-30 Thread Jason Merrill

On 6/29/25 2:19 PM, Jason Merrill wrote:

On 6/28/25 3:08 AM, Jakub Jelinek wrote:

On Fri, Jun 27, 2025 at 06:49:12PM -0400, Jason Merrill wrote:

On 6/27/25 5:58 PM, Jakub Jelinek wrote:

The following testcase is miscompiled since the introduction of UBSan,
cp_build_array_ref COND_EXPR handling replaces
(cond ? a : b)[idx] with cond ? a[idx] : b[idx], but if there are
SAVE_EXPRs inside of idx, they will be evaluated just in one of the
branches and the other uses uninitialized temporaries.
Fixed by using cp_save_expr and if needed, evaluating it before the
condition; for constant indexes this shouldn't change anything, and for
larger expressions in idx I think the patch should result in smaller
generated code, no need to duplicate all the evaluation in each of the
branches.


Evaluating idx before op0 seems to violate
https://eel.is/c++draft/expr#cond-1

"The first expression is sequenced before the second or third expression
([intro.execution])."


Oops, yes.  That one could be still handled by turning the condition
into SAVE_EXPR , SAVE_EXPR , SAVE_EXPR .
But for C++17 there is also
"In a subscript expression E1[E2], E1 is sequenced before E2."
and I'm not sure how can that be handled.

So, kill the optimization unless idx is INTEGER_CST (am not sure
TREE_SIDE_EFFECTS is sufficient because it could be e.g. reading from 
some
VAR_DECL), 


!TREE_SIDE_EFFECTS && tree_invariant_p?


Or perhaps introduce a predicate that checks whether it's safe to use an 
expression in both branches of a COND_EXPR, i.e. if there are no 
SAVE_EXPR/TARGET_EXPR/BIND_EXPR?



and perhaps try to recover the optimization in GIMPLE?
Though, I think we don't gimplify ARRAY_REF into ARRAY_REF if the first
operand is not an array and don't create ARRAY_REFs for what has been
written as *(arr + idx).  On the other side, ARRAY_REF is beneficial
primary for the simple cases, so maybe if op1 and op2 are ADDR_EXPRs
of non-volatile VAR_DECLs or COMPONENT_REFs with VAR_DECL bases so
constant or constant offset from frame, E1 is sequenced before E2 won't
be really observable and we could use the 3 SAVE_EXPRs.

I think it has been added for
https://gcc.gnu.org/pipermail/gcc-patches/2001-April/thread.html#48160
but I'm sure GIMPLE in between FE and expansion changed things 
sufficiently

that it won't ICE anymore.


And my comment in that thread was that pushing the indexing down into 
the COND_EXPR is probably undesirable once we start doing "significant 
optimization on trees" so maybe we should just drop it?


I see that simply removing the COND_EXPR case from cp_build_array_ref 
brings back the ICE from that thread, so more work is needed.


I guess your suggestion of only pushing the indexing down for simple 
indexes makes sense, otherwise do the *(a ? &b : &c)[d] transformation.


For release branches, would unshare_expr (idx) for the second arm be 
enough?


Ah, no, that doesn't help with SAVE_EXPR.

Jason



RE: [PATCH V3] x86: Enable separate shrink wrapping

2025-06-30 Thread Cui, Lili
I investigated the small case in  
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120881.

Pass_final will print "call mount" after "NOTE_INSN_PROLOGUE_END", since 
shrink_wrap separate doesn’t put it at the beginning of the function, the 
printing position is changed.


Thanks,
Lili.

From: H.J. Lu 
Sent: Monday, June 30, 2025 7:03 PM
To: Uros Bizjak 
Cc: Cui, Lili ; gcc-patches@gcc.gnu.org; Liu, Hongtao 
; richard.guent...@gmail.com; Michael Matz 
Subject: Re: [PATCH V3] x86: Enable separate shrink wrapping

On Tue, Jun 17, 2025 at 10:33 PM Uros Bizjak 
mailto:ubiz...@gmail.com>> wrote:
>
> On Tue, Jun 17, 2025 at 4:03 PM Cui, Lili 
> mailto:lili@intel.com>> wrote:
> >
> > From: Lili Cui mailto:lili@intel.com>>
> >
> > Hi Uros,
> >
> > This is patch v3, the main changes are as follows.
> >
> > 1. Added a pro_epilogue_adjust_stack_add_nocc in i386.md to add memory 
> > clobber for lea/mov.
> > 2. Adjusted some formatting issues.
> > 3. Added scan-rtl-dumps for ia32 in shrink_wrap_separate.C.
> >
> > Collected spec2017 performance on ZNVER5, EMR and ICELAKE. No performance 
> > regression was observed.
> > For O2 multi-copy :
> > 511.povray_r improved by 2.8% on ZNVER5.
> > 511.povray_r improved by 4.2% on EMR
> >
> > Bootstrapped & regtested on x86-64-pc-linux-gnu.
> > Use this patch to build the latest Linux kernel and boot successfully.
> >
> > Thanks,
> > Lili.
> >
> >
> > This commit implements the target macros (TARGET_SHRINK_WRAP_*) that
> > enable separate shrink wrapping for function prologues/epilogues in
> > x86.
> >
> > When performing separate shrink wrapping, we choose to use mov instead
> > of push/pop, because using push/pop is more complicated to handle rsp
> > adjustment and may lose performance, so here we choose to use mov, which
> > has a small impact on code size, but guarantees performance.
> >
> > Using mov means we need to use sub/add to maintain the stack frame. In
> > some special cases, we need to use lea to prevent affecting EFlags.
> >
> > Avoid inserting sub between test-je-jle to change EFlags, lea should be
> > used here.
> >
> > foo:
> > xorl%eax, %eax
> > testl   %edi, %edi
> > je  .L11
> > sub $16, %rsp  --> leaq-16(%rsp), %rsp
> > movq%r13, 8(%rsp)
> > movl$1, %r13d
> > jle .L4
> >
> > Tested against SPEC CPU 2017, this change always has a net-positive
> > effect on the dynamic instruction count.  See the following table for
> > the breakdown on how this reduces the number of dynamic instructions
> > per workload on a like-for-like (with/without this commit):
> >
> > instruction count   basewith commit (commit-base)/commit
> > 502.gcc_r   98666845943 96891561634 -1.80%
> > 526.blender_r   6.21226E+11 6.12992E+11 -1.33%
> > 520.omnetpp_r   1.1241E+11  1.11093E+11 -1.17%
> > 500.perlbench_r 1271558717  1263268350  -0.65%
> > 523.xalancbmk_r 2.20103E+11 2.18836E+11 -0.58%
> > 531.deepsjeng_r 2.73591E+11 2.72114E+11 -0.54%
> > 500.perlbench_r 64195557393 63881512409 -0.49%
> > 541.leela_r 2.99097E+11 2.98245E+11 -0.29%
> > 548.exchange2_r 1.27976E+11 1.27784E+11 -0.15%
> > 527.cam4_r  88981458425 7334679 -0.11%
> > 554.roms_r  2.60072E+11 2.59809E+11 -0.10%
> >
> > Collected spec2017 performance on ZNVER5, EMR and ICELAKE. No performance 
> > regression was observed.
> >
> > For O2 multi-copy :
> > 511.povray_r improved by 2.8% on ZNVER5.
> > 511.povray_r improved by 4% on EMR
> > 511.povray_r improved by 3.3 % ~ 4.6% on ICELAKE.
> >
> > gcc/ChangeLog:
> >
> > * config/i386/i386-protos.h (ix86_get_separate_components):
> > New function.
> > (ix86_components_for_bb): Likewise.
> > (ix86_disqualify_components): Likewise.
> > (ix86_emit_prologue_components): Likewise.
> > (ix86_emit_epilogue_components): Likewise.
> > (ix86_set_handled_components): Likewise.
> > * config/i386/i386.cc (save_regs_using_push_pop):
> > Split from ix86_compute_frame_layout.
> > (ix86_compute_frame_layout):
> > Use save_regs_using_push_pop.
> > (pro_epilogue_adjust_stack):
> > Use gen_pro_epilogue_adjust_stack_add_nocc.
> > (ix86_expand_prologue): Add some assertions and adjust
> > the stack frame at the beginning of the prolog for shrink
> > wrapping separate.
> > (ix86_emit_save_regs_using_mov):
> > Skip registers that are wrapped separately.
> > (ix86_emit_restore_regs_using_mov): Likewise.
> > (ix86_expand_epilogue): Add some assertions and set
> > restore_regs_via_mov to true for shrink wrapping separate.
> > (ix86_get_separate_components): New function.
> > (ix86_components_for_bb): Likewise.
> > (ix8

[COMMITTED 02/40] ada: Fix internal error on expression function called for default expression

2025-06-30 Thread Marc Poulhiès
From: Eric Botcazou 

This happens for the default expression of a controlled component when an
aggregate is used for the record type, because of a freeze node generated
for the expression within an artificial block that is needed to implement
the cleanup actions attached to the assignment of the component.

This is fixed by extending the special treatment applied to freeze nodes
by Insert_Actions, in the case of loops generated for aggregates, to the
case of blocks generated for aggregates.

gcc/ada/ChangeLog:

* exp_util.adb (Insert_Actions): Extend special treatment applied
to freeze nodes to the case of blocks generated for aggregates.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_util.adb | 26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 45eb808a8d2..3f6646b050c 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -8200,20 +8200,24 @@ package body Exp_Util is
elsif Nkind (Parent (P)) in N_Variant | N_Record_Definition then
   null;
 
-   --  Do not insert freeze nodes within the loop generated for
-   --  an aggregate, because they may be elaborated too late for
-   --  subsequent use in the back end: within a package spec the
-   --  loop is part of the elaboration procedure and is only
-   --  elaborated during the second pass.
+   --  Do not insert freeze nodes within a block or loop generated
+   --  for an aggregate, because they may be elaborated too late
+   --  for subsequent use in the back end: within a package spec,
+   --  the block or loop is part of the elaboration procedure and
+   --  is only elaborated during the second pass.
 
-   --  If the loop comes from source, or the entity is local to the
-   --  loop itself it must remain within.
+   --  If the block or loop comes from source, or the entity is
+   --  local to the block or loop itself, it must remain within.
 
-   elsif Nkind (Parent (P)) = N_Loop_Statement
- and then not Comes_From_Source (Parent (P))
+   elsif ((Nkind (Parent (P)) = N_Handled_Sequence_Of_Statements
+and then
+  Nkind (Parent (Parent (P))) = N_Block_Statement
+and then not Comes_From_Source (Parent (Parent (P
+  or else (Nkind (Parent (P)) = N_Loop_Statement
+and then not Comes_From_Source (Parent (P
  and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
- and then
-   Scope (Entity (First (Ins_Actions))) /= Current_Scope
+ and then not
+   Within_Scope (Entity (First (Ins_Actions)), Current_Scope)
then
   null;
 
-- 
2.43.0



[COMMITTED 07/40] ada: Document sanitizers for Ada

2025-06-30 Thread Marc Poulhiès
From: Jose Ruiz 

gcc/ada/ChangeLog:

* doc/gnat_ugn/gnat_and_program_execution.rst: Add the
documentation about using sanitizers with Ada code.
* gnat_ugn.texi: Regenerate.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst | 3 ++-
 gcc/ada/gnat_ugn.texi   | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst 
b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
index ab49e12e794..0184bd4aaf8 100644
--- a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
+++ b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
@@ -4200,7 +4200,8 @@ It can detect the following types of problems:
   Ada’s ``Index_Check`` detects buffer overflows caused by out-of-bounds array
   access. If run-time checks are disabled, the sanitizer can still detect such
   overflows at execution time the same way as it signalled the previous wrong
-  memory overlay.
+  memory overlay. Note that if both the Ada run-time checks and the sanitizer
+  are enabled, the Ada run-time exception takes precedence.
 
 .. code-block:: ada
 
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 170384b505f..2bad9b858b8 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -22971,7 +22971,8 @@ Buffer overflow
 Ada’s @code{Index_Check} detects buffer overflows caused by out-of-bounds array
 access. If run-time checks are disabled, the sanitizer can still detect such
 overflows at execution time the same way as it signalled the previous wrong
-memory overlay.
+memory overlay. Note that if both the Ada run-time checks and the sanitizer
+are enabled, the Ada run-time exception takes precedence.
 
 @quotation
 
-- 
2.43.0



[COMMITTED 12/40] ada: Remove redundant condition in test of System.Val_Real.Integer_To_Real

2025-06-30 Thread Marc Poulhiès
From: Eric Botcazou 

The second condition of the conjunction is redundant with the first.

gcc/ada/ChangeLog:

* libgnat/s-valrea.adb (Integer_to_Real): Rename to...
(Integer_To_Real): ...this.  Remove the second condition of the
conjunction in the test for the zero value.
(Scan_Real): Adjust to above renaming.
(Value_Real): Likewise.
* libgnat/s-valuer.ads (Scan_Raw_Real): Add note about Val.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/libgnat/s-valrea.adb | 14 +++---
 gcc/ada/libgnat/s-valuer.ads |  3 ++-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/gcc/ada/libgnat/s-valrea.adb b/gcc/ada/libgnat/s-valrea.adb
index aff694dd721..6dd8aa5da96 100644
--- a/gcc/ada/libgnat/s-valrea.adb
+++ b/gcc/ada/libgnat/s-valrea.adb
@@ -90,7 +90,7 @@ package body System.Val_Real is
 when others => raise Program_Error);
--  Return the exponent of a power of 2
 
-   function Integer_to_Real
+   function Integer_To_Real
  (Str   : String;
   Val   : Impl.Value_Array;
   Base  : Unsigned;
@@ -105,10 +105,10 @@ package body System.Val_Real is
--  Return Num'Scaling (5.0**Exp, -S) as a double number where Exp > Maxexp
 
-
-   -- Integer_to_Real --
+   -- Integer_To_Real --
-
 
-   function Integer_to_Real
+   function Integer_To_Real
  (Str   : String;
   Val   : Impl.Value_Array;
   Base  : Unsigned;
@@ -213,7 +213,7 @@ package body System.Val_Real is
 
   --  Compute the final value by applying the scaling, if any
 
-  if (Val (1) = 0 and then Val (2) = 0) or else S = 0 then
+  if Val (1) = 0 or else S = 0 then
  R_Val := Double_Real.To_Single (D_Val);
 
   else
@@ -313,7 +313,7 @@ package body System.Val_Real is
 
exception
   when Constraint_Error => Bad_Value (Str);
-   end Integer_to_Real;
+   end Integer_To_Real;
 
---
-- Large_Powfive --
@@ -456,7 +456,7 @@ package body System.Val_Real is
begin
   Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Base, Scale, Extra, Minus);
 
-  return Integer_to_Real (Str, Val, Base, Scale, Minus);
+  return Integer_To_Real (Str, Val, Base, Scale, Minus);
end Scan_Real;
 

@@ -473,7 +473,7 @@ package body System.Val_Real is
begin
   Val := Impl.Value_Raw_Real (Str, Base, Scale, Extra, Minus);
 
-  return Integer_to_Real (Str, Val, Base, Scale, Minus);
+  return Integer_To_Real (Str, Val, Base, Scale, Minus);
end Value_Real;
 
 end System.Val_Real;
diff --git a/gcc/ada/libgnat/s-valuer.ads b/gcc/ada/libgnat/s-valuer.ads
index 9f279982812..bc5a2e0954a 100644
--- a/gcc/ada/libgnat/s-valuer.ads
+++ b/gcc/ada/libgnat/s-valuer.ads
@@ -85,7 +85,8 @@ package System.Value_R is
--
--Sum [Val (N) * (Base ** Scale (N)), N in 1 .. Parts]
--
-   --  when Parts > 1, with the negative sign if Minus is true.
+   --  when Parts > 1, with the negative sign if Minus is true. Note that
+   --  Val (1) cannot be zero unless Val is entirely filled with zero.
--
--  If no valid real is found, then Ptr.all points either to an initial
--  non-blank character, or to Max + 1 if the field is all spaces and the
-- 
2.43.0



[COMMITTED 23/40] ada: Fix detection of ghost objects in unusual procedure calls

2025-06-30 Thread Marc Poulhiès
From: Piotr Trojanek 

When name of a called procedure involves unusual constructs, e.g. type
conversions (like in "Typ (Obj).all"), we must look at the outermost construct
to decide whether the name denotes a ghost entity.

gcc/ada/ChangeLog:

* ghost.adb (Ghost_Entity): Remove; use Get_Enclosing_Ghost_Object
instead; adapt callers.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/ghost.adb | 34 --
 1 file changed, 4 insertions(+), 30 deletions(-)

diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb
index 2c61f3a80ab..ac38f3cc239 100644
--- a/gcc/ada/ghost.adb
+++ b/gcc/ada/ghost.adb
@@ -67,11 +67,6 @@ package body Ghost is
-- Local subprograms --
---
 
-   function Ghost_Entity (Ref : Node_Id) return Entity_Id;
-   pragma Inline (Ghost_Entity);
-   --  Obtain the entity of a Ghost entity from reference Ref. Return Empty if
-   --  no such entity exists.
-
procedure Install_Ghost_Mode (Mode : Ghost_Mode_Type);
pragma Inline (Install_Ghost_Mode);
--  Install Ghost mode Mode as the Ghost mode in effect
@@ -1079,27 +1074,6 @@ package body Ghost is
   end if;
end Check_Ghost_Type;
 
-   --
-   -- Ghost_Entity --
-   --
-
-   function Ghost_Entity (Ref : Node_Id) return Entity_Id is
-  Obj_Ref : constant Node_Id := Ultimate_Prefix (Ref);
-
-   begin
-  --  When the reference denotes a subcomponent, recover the related whole
-  --  object (SPARK RM 6.9(1)).
-
-  if Is_Entity_Name (Obj_Ref) then
- return Entity (Obj_Ref);
-
-  --  Otherwise the reference cannot possibly denote a Ghost entity
-
-  else
- return Empty;
-  end if;
-   end Ghost_Entity;
-

-- Implements_Ghost_Interface --

@@ -1249,7 +1223,7 @@ package body Ghost is
   --  A procedure call is Ghost when it invokes a Ghost procedure
 
   if Nkind (N) = N_Procedure_Call_Statement then
- Id := Ghost_Entity (Name (N));
+ Id := Get_Enclosing_Ghost_Object (Name (N));
 
  return Present (Id) and then Is_Ghost_Entity (Id);
   end if;
@@ -1770,7 +1744,7 @@ package body Ghost is
   --  A procedure call becomes Ghost when the procedure being invoked is
   --  Ghost. Install the Ghost mode of the procedure.
 
-  Id := Ghost_Entity (Name (N));
+  Id := Get_Enclosing_Ghost_Object (Name (N));
 
   if Present (Id) then
  if Is_Checked_Ghost_Entity (Id) then
@@ -2084,7 +2058,7 @@ package body Ghost is
   --  of the target.
 
   if Nkind (N) = N_Assignment_Statement then
- Id := Ghost_Entity (Name (N));
+ Id := Get_Enclosing_Ghost_Object (Name (N));
 
  if Present (Id) then
 Set_Ghost_Mode_From_Entity (Id);
@@ -2123,7 +2097,7 @@ package body Ghost is
   --  procedure being invoked.
 
   elsif Nkind (N) = N_Procedure_Call_Statement then
- Id := Ghost_Entity (Name (N));
+ Id := Get_Enclosing_Ghost_Object (Name (N));
 
  if Present (Id) then
 Set_Ghost_Mode_From_Entity (Id);
-- 
2.43.0



Re: [RFC] [C]New syntax for the argument of counted_by attribute for C language

2025-06-30 Thread Bill Wendling
Despite our best efforts, the Clang Area Team has decided *not* to
accept any of our suggestions to make this feature compatible between
Clang and GCC:

  
https://discourse.llvm.org/t/rfc-bounds-safety-in-c-syntax-compatibility-with-gcc/85885/65

They have also firmly rejected the idea of adding forward declarations
within the attribute and in the parameter list.

This leaves us with little choice if we want to have a possibility of
having this feature be compatible with non-Clang compilers. I
suggested two options below (though it might be prudent to use
'counted_by_func' instead of 'counted_by_expr' for the "function"
form).

They wave away our concerns with "[w]e realize that this solution is
not acceptable to the GCC community, which is unfortunate. However,
the needs of our two communities are a bit different in conflicting
ways in this case, so it seems reasonable that we each look to our own
QoI until a better solution emerges." I have no clue what they mean by
that last part as a "better solution" would be far more difficult to
wedge into a wide-spread existing feature than to start with it.
(Maybe they mean when GCC can support generalized expressions in
attributes at some point?) And the first part is patronizing and
blatantly wrong.

-bw

On Wed, Jun 25, 2025 at 1:37 PM Bill Wendling  wrote:
>
> I posted this on the LLVM Discourse forum[1] and got some traction, so
> I want to get the GCC community's input. (My initial proposal is
> replicated here.)
>
> I had already mentioned this in previous emails in this thread, so
> it's nothing super new, and there have been some suggested
> improvements already. Parts of this reference a meeting that took
> place between the LLVM developers and some non-LLVM developers. The
> meeting mostly explained the issues regarding the "compromise" from
> this thread and how it interacts (poorly) with C++, and vice versa.
>
> There was a lengthy discussion after this proposal.
>
> Please take a look and let me know what you think.
>
> -bw
>
> [1] 
> https://discourse.llvm.org/t/rfc-bounds-safety-in-c-syntax-compatibility-with-gcc/85885/32?u=void
>
> --
>
> I’ve been putting off pushing this proposal, because it is a departure
> from what Apple has done and added a lot of extra syntax for this
> feature, but I think it’s appropriate right now.
>
> The main issue at play is that C and C++ are two very different
> languages. The scoping rules are completely different making name
> resolution not work in one language without jumping through
> non-obvious hoops. This was made clear in @rapidsna’s presentation
> last week. Making matters worse is that GCC (and other) compilers
> perform one pass parsing for C, making forward declarations necessary.
> The forward declarations, while solving many issues, have their own
> issues. Other solutions at play require changes to the base languages,
> which require approval by the standards committee.
>
> Even if the full struct was declared before the expression in the
> attribute was defined, there would still be issues, due to one example
> from @rapidsna’s presentation [as pointed out by Joseph Jelinek]:
>
> typedef int T;
> struct foo {
>   int T;
>   int U;
>   int * __counted_by_expr(int T; (T)+U) buf; // Addition or cast?
> };
>
> Given this, I want to propose using functions / static methods for 
> expressions.
>
> The function takes one and only one argument: a "this" pointer to the
> least enclosing non-anonymous struct.
>
> The call to the function is generated by the compiler, so no argument
> the attribute only needs to indicate the function’s name. This avoids
> the need to add a new __builtin_* or __self element to C.
>
> * The function needs to be declared before use in C. (It can be fully
> defined if no fields within the struct are used.)
> * The function should be static and marked as pure (and maybe always_inline).
> * The function in C++ should be private or protected.
>
> C example:
>
> static size_t calc_counted_by(void *);
> struct foo {
>   /* ... */
>   struct bar {
> int * __counted_by_expr(calc_counted_by) buf;
> int count;
> int scale;
>   };
> };
>
> enum { OFFSET = 42 };
>
> // The function could be marked with the 'pure' attribute.
> static size_t __pure calc_counted_by(void *p) {
>   struct bar *ptr = (struct foo *)p;
>   return ptr->count * ptr->scale - OFFSET;
> }
>
> C++ example:
>
> struct foo {
>   enum { OFFSET = 42 };
>   struct bar {
> int * __counted_by_expr(calc_counted_by) buf;
>   private:
> static size_t __pure calc_counted_by(struct bar *ptr) {
>   return ptr->count * ptr->scale - OFFSET;
> }
>   public:
> int count;
> int scale;
>   };
> };
>
> Pros
>
> 1. This uses the current language without any modifications to scoping
> or requiring feature additions that need to be approved by the
> standards committee. All compilers should be able to implement them
> without major modifications.
> 2. Name look

[COMMITTED 06/40] ada: Document sanitizers for Ada

2025-06-30 Thread Marc Poulhiès
From: Jose Ruiz 

gcc/ada/ChangeLog:

* doc/gnat_ugn/gnat_and_program_execution.rst: Add the
documentation about using sanitizers with Ada code.
* gnat_ugn.texi: Regenerate.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 .../gnat_ugn/gnat_and_program_execution.rst   | 269 +++
 gcc/ada/gnat_ugn.texi | 691 +-
 2 files changed, 787 insertions(+), 173 deletions(-)

diff --git a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst 
b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
index 4ecb3cf2e96..ab49e12e794 100644
--- a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
+++ b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
@@ -23,6 +23,7 @@ This chapter covers several topics:
 * `Performing Dimensionality Analysis in GNAT`_
 * `Stack Related Facilities`_
 * `Memory Management Issues`_
+* `Sanitizers for Ada`_
 
 .. _Running_and_Debugging_Ada_Programs:
 
@@ -4133,3 +4134,271 @@ execution of this erroneous program:
 
   The allocation root #1 of the first example has been split in 2 roots #1
   and #3, thanks to the more precise associated backtrace.
+
+.. _Sanitizers_for_Ada:
+
+Sanitizers for Ada
+==
+
+.. index:: Sanitizers
+
+This section explains how to use sanitizers with Ada code. Sanitizers offer 
code
+instrumentation and run-time libraries that detect certain memory issues and
+undefined behaviors during execution. They provide dynamic analysis 
capabilities
+useful for debugging and testing.
+
+While many sanitizer capabilities overlap with Ada's built-in runtime checks,
+they are particularly valuable for identifying issues that arise from unchecked
+features or low-level operations.
+
+.. _AddressSanitizer:
+
+AddressSanitizer
+
+
+.. index:: AddressSanitizer
+.. index:: ASan
+.. index:: -fsanitize=address
+
+AddressSanitizer (aka ASan) is a memory error detector activated with the
+:switch:`-fsanitize=address` switch. Note that many of the typical memory 
errors,
+such as use after free or buffer overflow, are detected by Ada’s 
``Access_Check``
+and ``Index_Check``.
+
+It can detect the following types of problems:
+
+* Wrong memory overlay
+
+  A memory overlay is a situation in which an object of one type is placed at 
the
+  same memory location as a distinct object of a different type, thus 
overlaying
+  one object over the other in memory. When there is an overflow because the
+  objects do not overlap (like in the following example), the sanitizer can 
signal
+  it.
+
+.. code-block:: ada
+
+   procedure Wrong_Size_Overlay is
+  type Block is array (Natural range <>) of Integer;
+
+  Block4 : aliased Block := (1 .. 4 => 4);
+  Block5 : Block (1 .. 5) with Address => Block4'Address;
+   begin
+  Block5 (Block5'Last) := 5;  --  Outside the object
+   end Wrong_Size_Overlay;
+
+  If the code is built with the :switch:`-fsanitize=address` and :switch:`-g`` 
options,
+  the following error is shown at execution time:
+
+::
+
+...
+SUMMARY: AddressSanitizer: stack-buffer-overflow 
wrong_size_overlay.adb:7 in _ada_wrong_size_overlay
+...
+
+* Buffer overflow
+
+  Ada’s ``Index_Check`` detects buffer overflows caused by out-of-bounds array
+  access. If run-time checks are disabled, the sanitizer can still detect such
+  overflows at execution time the same way as it signalled the previous wrong
+  memory overlay.
+
+.. code-block:: ada
+
+   procedure Buffer_Overrun is
+  Size : constant := 100;
+  Buffer : array (1 .. Size) of Integer := (others => 0);
+  Wrong_Index : Integer := Size + 1 with Export;
+   begin
+  -- Access outside the boundaries
+  Put_Line ("Value: " & Integer'Image (Buffer (Wrong_Index)));
+   end Buffer_Overrun;
+
+* Use after lifetime
+
+  Ada’s ``Accessibility_Check`` helps prevent use-after-return and
+  use-after-scope errors by enforcing lifetime rules. When these checks are
+  bypassed using ``Unchecked_Access``, sanitizers can still detect such
+  violations during execution.
+
+.. code-block:: ada
+
+   with Ada.Text_IO; use Ada.Text_IO;
+
+   procedure Use_After_Return is
+  type Integer_Access is access all Integer;
+  Ptr : Integer_Access;
+
+  procedure Inner;
+
+  procedure Inner is
+ Local : aliased Integer := 42;
+  begin
+ Ptr := Local'Unchecked_Access;
+  end Inner;
+
+   begin
+  Inner;
+  --  Accessing Local after it has gone out of scope
+  Put_Line ("Value: " & Integer'Image (Ptr.all));
+   end Use_After_Return;
+
+  If the code is built with the :switch:`-fsanitize=address` and :switch:`-g`
+  options, the following error is shown at execution time:
+
+::
+
+...
+==1793927==ERROR: AddressSanitizer: stack-use-after-return on address 
0xf6fa1a409060 at pc 0xb20b6cb6cac0 bp

[COMMITTED 05/40] ada: Remove dead branch from Get_Enclosing_Object

2025-06-30 Thread Marc Poulhiès
From: Piotr Trojanek 

The dead branch in routine Get_Enclosing_Object was most likely some
experiment from the early days of GNATprove. This routine is meant
to be called with the LHS of an assignment statement where an implicit
dereference is always rewritten into explicit one, regardless if code
is generated.

gcc/ada/ChangeLog:

* sem_util.adb (Get_Enclosing_Object): Remove dead code.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_util.adb | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index c8e30f3dc7f..a62b7013d70 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -10266,14 +10266,7 @@ package body Sem_Util is
| N_Selected_Component
| N_Slice
 =>
-   --  If not generating code, a dereference may be left implicit.
-   --  In thoses cases, return Empty.
-
-   if Is_Access_Type (Etype (Prefix (N))) then
-  return Empty;
-   else
-  return Get_Enclosing_Object (Prefix (N));
-   end if;
+   return Get_Enclosing_Object (Prefix (N));
 
 when N_Type_Conversion =>
return Get_Enclosing_Object (Expression (N));
-- 
2.43.0



[COMMITTED 08/40] ada: Tweak handling of Parent field in Print_Node

2025-06-30 Thread Marc Poulhiès
From: Ronan Desplanques 

Before this patch, Print_Node failed to honor its Prefix_Char formal
parameter when printing the Parent field. This had no consequences
because Prefix_Char was only used to print members of Nlists, and those
don't have a parent in the tree. But this patch fixes it anyway in
preparation for new debug printing features.

gcc/ada/ChangeLog:

* treepr.adb (Print_Node): Tweak Parent field printing.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/treepr.adb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/treepr.adb b/gcc/ada/treepr.adb
index 16e2bc8ade5..0f723ed25b2 100644
--- a/gcc/ada/treepr.adb
+++ b/gcc/ada/treepr.adb
@@ -1144,8 +1144,8 @@ package body Treepr is
   end if;
 
   if not Is_List_Member (N) then
- Print_Str (Prefix_Str);
- Print_Str (" Parent = ");
+ Print_Str (Prefix);
+ Print_Str ("Parent = ");
  Print_Node_Ref (Parent (N));
  Print_Eol;
   end if;
-- 
2.43.0



[COMMITTED 30/40] ada: Ignore ghost predicate in Ada.Strings.Superbounded

2025-06-30 Thread Marc Poulhiès
From: Claire Dross 

Add an assertion policy to ignore the ghost predicates in
Ada.Strings.Superbounded.

gcc/ada/ChangeLog:

* libgnat/a-strsup.ads: Ignore Ghost_Predicate in the assertion policy.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/libgnat/a-strsup.ads | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/gcc/ada/libgnat/a-strsup.ads b/gcc/ada/libgnat/a-strsup.ads
index 65d13ed2cbe..68098ea8941 100644
--- a/gcc/ada/libgnat/a-strsup.ads
+++ b/gcc/ada/libgnat/a-strsup.ads
@@ -42,10 +42,11 @@
 --  contract cases should not be executed at runtime as well, in order not to
 --  slow down the execution of these functions.
 
-pragma Assertion_Policy (Pre=> Ignore,
- Post   => Ignore,
- Contract_Cases => Ignore,
- Ghost  => Ignore);
+pragma Assertion_Policy (Pre => Ignore,
+ Post=> Ignore,
+ Contract_Cases  => Ignore,
+ Ghost   => Ignore,
+ Ghost_Predicate => Ignore);
 
 with Ada.Strings.Maps; use type Ada.Strings.Maps.Character_Mapping_Function;
 with Ada.Strings.Search;
-- 
2.43.0



[COMMITTED 39/40] ada: Refine use of Has_Exit

2025-06-30 Thread Marc Poulhiès
From: Ronan Desplanques 

The description of the Has_Exit field in Einfo makes it pretty clear
that it can only be meaningful for loop entities. It was however defined
in all entities until this patch, which restricts this field to E_Loop.

gcc/ada/ChangeLog:

* gen_il-gen-gen_entities.adb (Gen_Entities): Tweak Has_Exit.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/gen_il-gen-gen_entities.adb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/ada/gen_il-gen-gen_entities.adb 
b/gcc/ada/gen_il-gen-gen_entities.adb
index 5c895977d40..3c0ded9f72e 100644
--- a/gcc/ada/gen_il-gen-gen_entities.adb
+++ b/gcc/ada/gen_il-gen-gen_entities.adb
@@ -77,7 +77,6 @@ begin -- Gen_IL.Gen.Gen_Entities
 Sm (Has_Delayed_Aspects, Flag),
 Sm (Has_Delayed_Freeze, Flag),
 Sm (Has_Delayed_Rep_Aspects, Flag),
-Sm (Has_Exit, Flag),
 Sm (Has_Forward_Instantiation, Flag),
 Sm (Has_Fully_Qualified_Name, Flag),
 Sm (Has_Gigi_Rep_Item, Flag),
@@ -1226,6 +1225,7 @@ begin -- Gen_IL.Gen.Gen_Entities
--  loop statement.
(Sm (First_Entity, Node_Id),
 Sm (First_Exit_Statement, Node_Id),
+Sm (Has_Exit, Flag),
 Sm (Has_Loop_Entry_Attributes, Flag),
 Sm (Last_Entity, Node_Id),
 Sm (Renamed_Or_Alias, Node_Id),
-- 
2.43.0



Re: [COMMITTED] cobol: Normalize generating and using function_decls.

2025-06-30 Thread Rainer Orth
Hi Robert,

> These changes have been shown to generate more sensible code on both
> x86_64.
>
> On x86_64-pc-linux, a bootstrap build of --enable-languages=c,c++,cobol
> succeeded.

this patch has one change (not listed in ChangeLog) that broke 32-bit
Solaris bootstrap:

diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index f0faaa41577..660b0b4c4c2 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -12359,7 +12359,7 @@ numstr2i( const char input[], radix_t radix ) {
 return output;
   }
   if( erc == -1 ) {
-yywarn("'%s' was accepted as %zu", input, integer);
+yywarn("'%s' was accepted as %ld", input, integer);
   }
   return output;
 }

This causes

/vol/gcc/src/hg/master/local/gcc/cobol/parse.y: In function ‘real_value 
numstr2i(const char*, radix_t)’:
/vol/gcc/src/hg/master/local/gcc/cobol/parse.y:12362:12: error: format ‘%ld’ 
expects argument of type ‘long int’, but argument 3 has type ‘std::size_t’ {aka 
‘unsigned int’} [-Werror=format=]
12362 | yywarn("'%s' was accepted as %ld", input, integer);
  |^~ ~~~
  |   |
  |   std::size_t {aka unsigned 
int}

Returning to %zu obviously fixes this.

Besides, I noticed

diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in
index bec81a6acc0..18eb3b0f1e5 100644
--- a/gcc/cobol/Make-lang.in
+++ b/gcc/cobol/Make-lang.in
@@ -353,6 +353,13 @@ cobol.srcman:
 
 cobol.mostlyclean:
 
+gcobol.clean:
+# This is intended for non-general use.  It is a last-ditch effort to flush
+# out all oject files and executable code for gcobol and libgcobol, causing 
+# a complete rebuild of all executable code.
+   rm -fr gcobol cobol1 cobol/*\
+   ../*/libgcobol/*
+

This is at least incomplete: in multilib builds, there are more
instances of libgcobol in //libgcobol.

Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


Re: [PATCH] c++, v2: Fix up cp_build_array_ref COND_EXPR handling [PR120471]

2025-06-30 Thread Jason Merrill

On 6/30/25 1:06 PM, Jakub Jelinek wrote:

On Mon, Jun 30, 2025 at 05:14:06PM +0200, Jakub Jelinek wrote:

1) for idx being INTEGER_CST (case for which I believe the change has been
added) it keeps doing what it did
2) if both op1 and op2 are arrays with invariant address or pointers to
something with invariant address, it uses
SAVE_EXPR , SAVE_EXPR  SAVE_EXPR 
as COND_EXPR condition and otherwise what it did
3) otherwise punt

Now, perhaps a predicate (but how to call it) whether idx doesn't
contain any SAVE_EXPRs/TARGET_EXPRs/BIND_EXPRs and isn't really large
expression (but how to measure it; perhaps also no CALL_EXPRs, and the
question if it should allow say multiplication/division/modulo, those might
need larger code as well) could be used instead of the INTEGER_CST check,
either immediately or incrementally.
But guess I should first try to reproduce the ICE you've mentioned.


So, the thing with the ICE is that the parsing gives us a COND_EXPR
of ARRAY_TYPE with ARRAY_TYPE operands.  So, when we punt (either always
by removing the COND_EXPR cp_build_array_ref optimization altogether or
conditionally), we risk the bogus COND_EXPR with ARRAY_TYPE remains in the
IL.
Now, with the v2 patch I've posted, neither
extern int a1[];
extern int a2[];
void foo(int p)
{
   int x = (p ? a1 : a2)[1];
}
nor
void bar(int p, int q)
{
   int x = (p ? a1 : a2)[q];
}
actually ICE, because in the first case idx is INTEGER_CST and in the
second case a1 and a2 are invariant address arrays.
But e.g.
extern int a1[], a2[], a3[], a4[];

int
foo (int p)
{
   return (p ? a1 : a2)[1];
}

int
bar (int p, int q)
{
   return (p ? a1 : a2)[q];
}

int
baz (int p, int q)
{
   return (p ? q ? a1 : a2 : q ? a3 : a4)[1];
}

int
qux (int p, int q, int r)
{
   return (p ? q ? a1 : a2 : q ? a3 : a4)[r];
}

already ICEs with my patch in baz and qux, because the gimplifier can't
handle ARRAY_TYPE COND_EXPRs with unknown bounds for obvious reasons.

So, what about the following patch then (or its variant with some
predicate of not large expression without
SAVE_EXPR/TARGET_EXPR/BIND_EXPR/CALL_EXPR/STATEMENT_EXPR/LABEL_EXPR))?


Might go with my earlier !TREE_SIDE_EFFECTS && tree_invariant_p suggestion?


2025-06-30  Jakub Jelinek  

PR c++/120471
* typeck.cc (cp_build_array_ref) : If idx is not
INTEGER_CST, don't optimize the case (but cp_default_conversion on
array early if it has ARRAY_TYPE) or use
SAVE_EXPR , SAVE_EXPR , SAVE_EXPR  as new op0 depending
on flag_strong_eval_order and whether op1 and op2 are arrays with
invariant address or tree invariant pointers.  Formatting fixes.

* g++.dg/ubsan/pr120471.C: New test.
* g++.dg/parse/pr120471.C: New test.

--- gcc/cp/typeck.cc.jj 2025-06-30 12:19:16.398242029 +0200
+++ gcc/cp/typeck.cc2025-06-30 18:59:51.289774002 +0200
@@ -4001,13 +4001,91 @@ cp_build_array_ref (location_t loc, tree
}
  
  case COND_EXPR:

-  ret = build_conditional_expr
-  (loc, TREE_OPERAND (array, 0),
-  cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
-  complain),
-  cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx,
-  complain),
-  complain);
+  tree op0, op1, op2;
+  op0 = TREE_OPERAND (array, 0);
+  op1 = TREE_OPERAND (array, 1);
+  op2 = TREE_OPERAND (array, 1);
+  if (TREE_CODE (idx) != INTEGER_CST)
+   {
+ /* If idx could possibly have some SAVE_EXPRs, turning
+(op0 ? op1 : op2)[idx] into
+op0 ? op1[idx] : op2[idx] can lead into temporaries
+initialized in one conditional path and uninitialized
+uses of them in the other path.
+And if idx is a really large expression, evaluating it
+twice is also not optimal.
+On the other side, op0 must be sequenced before evaluation
+of op1 and op2 and for C++17 op0, op1 and op2 must be
+sequenced before idx.
+If idx is INTEGER_CST, we can just do the optimization
+without any SAVE_EXPRs, if op1 and op2 are both ARRAY_TYPE
+VAR_DECLs or COMPONENT_REFs thereof (so their address
+is constant or relative to frame), optimize into
+(SAVE_EXPR , SAVE_EXPR , SAVE_EXPR )
+? op1[SAVE_EXPR ] : op2[SAVE_EXPR ]
+Otherwise avoid this optimization.  */
+ if (flag_strong_eval_order == 2)
+   {
+ if (TREE_CODE (TREE_TYPE (op1)) == ARRAY_TYPE)
+   {
+ tree xop1 = op1;
+ while (TREE_CODE (xop1) == COMPONENT_REF)
+   xop1 = TREE_OPERAND (xop1, 0);
+ STRIP_ANY_LOCATION_WRAPPER (xop1);
+ if (!decl_address_invariant_p (xop1))


Maybe split most of the tree_invariant_p_1 ADDR_EXPR case into an 
address_invariant_p predicate?



+ 

Re: [PATCH] [RISC-V] Correct CFA notes for stack-clash protection [PR120714]

2025-06-30 Thread Jeff Law




On 6/27/25 12:48 AM, Alexey Merzlyakov wrote:

Fixes incorrect SP-addresses used in CFA notes for the stack probes
unrelative to the frame's top. It applied to the RISC-V targets code
generation when the stack-clash protection is enabled.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_allocate_and_probe_stack_space):
  Fix SP-addresses in REG_CFA_DEF_CFA notes for stack-clash case.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/pr120714.c: New test.
Raphael and I sync'd on these issues this morning.  Raphael has 
indicated Alexey's patch is better as it handles residuals correctly. 
So I've pushed this patch.


Thanks Alexey!

jeff



[COMMITTED 32/40] ada: Remove useless Set_Scope calls

2025-06-30 Thread Marc Poulhiès
From: Ronan Desplanques 

This patch remove calls to Set_Scope that have no effect because of
subsequent calls to Append_Entity, which calls Set_Scope itself.

gcc/ada/ChangeLog:

* cstand.adb (Make_Aliased_Component, Make_Formal, New_Operator,
Create_Standard): Remove useless calls.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/cstand.adb | 4 
 1 file changed, 4 deletions(-)

diff --git a/gcc/ada/cstand.adb b/gcc/ada/cstand.adb
index 1dc06986e74..79e7083f62b 100644
--- a/gcc/ada/cstand.adb
+++ b/gcc/ada/cstand.adb
@@ -1076,7 +1076,6 @@ package body CStand is
 Set_Never_Set_In_Source(A_Char, True);
 Set_Is_True_Constant   (A_Char, True);
 Set_Etype  (A_Char, Standard_Character);
-Set_Scope  (A_Char, Standard_Entity (S_ASCII));
 Set_Is_Immediately_Visible (A_Char, False);
 Set_Is_Public  (A_Char, True);
 Set_Is_Known_Valid (A_Char, True);
@@ -1732,7 +1731,6 @@ package body CStand is
begin
   Mutate_Ekind  (Id, E_Component);
   Set_Etype (Id, Typ);
-  Set_Scope (Id, Rec);
   Reinit_Component_Location (Id);
   Set_Original_Record_Component (Id, Id);
   Set_Is_Aliased(Id);
@@ -1750,7 +1748,6 @@ package body CStand is
begin
   Mutate_Ekind  (Formal, E_In_Parameter);
   Set_Mechanism (Formal, Default_Mechanism);
-  Set_Scope (Formal, Standard_Standard);
   Set_Etype (Formal, Typ);
 
   return Formal;
@@ -1780,7 +1777,6 @@ package body CStand is
   Set_Is_Pure(Ident_Node, True);
   Mutate_Ekind   (Ident_Node, E_Operator);
   Set_Etype  (Ident_Node, Typ);
-  Set_Scope  (Ident_Node, Standard_Standard);
   Set_Homonym(Ident_Node, Get_Name_Entity_Id (Op));
   Set_Convention (Ident_Node, Convention_Intrinsic);
 
-- 
2.43.0



[COMMITTED 20/40] ada: 'Size'Class and interface types documentation

2025-06-30 Thread Marc Poulhiès
From: Steve Baird 

Update GNAT RM documentation of the Size'Class aspect.

gcc/ada/ChangeLog:

* doc/gnat_rm/gnat_language_extensions.rst: Update documentation for
mutably tagged types and the Size'Class aspect.
* gnat_rm.texi: Regenerate.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 .../doc/gnat_rm/gnat_language_extensions.rst  | 183 +---
 gcc/ada/gnat_rm.texi  | 198 +++---
 2 files changed, 229 insertions(+), 152 deletions(-)

diff --git a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst 
b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst
index 0a08a83a5a2..bdc4e675488 100644
--- a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst
+++ b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst
@@ -1350,113 +1350,150 @@ case statement with composite selector type".
 Mutably Tagged Types with Size'Class Aspect
 ---
 
-The ``Size'Class`` aspect can be applied to a tagged type to specify a size
-constraint for the type and its descendants. When this aspect is specified
-on a tagged type, the class-wide type of that type is considered to be a
-"mutably tagged" type - meaning that objects of the class-wide type can have
-their tag changed by assignment from objects with a different tag.
+For a specific tagged nonformal type T that satisfies some conditions
+described later in this section, the universal-integer-valued type-related
+representation aspect ``Size'Class`` may be specified; any such specified
+aspect value shall be static.
+
+Specifying this aspect imposes an upper bound on the sizes of all specific
+descendants of T (including T itself). T'Class (but not T) is then said to be
+a "mutably tagged" type - meaning that T'Class is a definite subtype and that
+the tag of a variable of type T'Class may be modified by assignment in some
+cases described later in this section. An inherited ``Size'Class`` aspect
+value may be overridden, but not with a larger value.
+
+If the ``Size'Class`` aspect is specified for a type T, then every specific
+descendant of T (including T itself)
+
+* shall have a Size that does not exceed the specified value; and
+
+* shall have a (possibly inherited) ``Size'Class`` aspect that does not exceed
+  the specifed value; and
+
+* shall be undiscriminated; and
+
+* shall have no composite subcomponent whose subtype is subject to a nonstatic
+  constraint; and
+
+* shall not have a tagged partial view other than a private extension; and
+
+* shall not be a descendant of an interface type; and
+
+* shall not have a statically deeper accessibility level than that of T.
+
+If the ``Size'Class`` aspect is not specified for a type T (either explicitly
+or by inheritance), then it shall not be specified for any descendant of T.
 
 Example:
 
 .. code-block:: ada
 
-type Base is tagged null record
-with Size'Class => 16 * 8;  -- Size in bits (128 bits, or 16 bytes)
+type Root_Type is tagged null record with Size'Class => 16 * 8;
 
-type Derived_Type is new Base with record
-   Data_Field : Integer;
+type Derived_Type is new Root_Type with record
+   Stuff : Some_Type;
 end record;  -- ERROR if Derived_Type exceeds 16 bytes
 
-Class-wide types with a specified ``Size'Class`` can be used as the type of
-array components, record components, and stand-alone objects.
+Because any subtype of a mutably tagged type is definite, it can be used as a
+component subtype for enclosing array or record types, as the subtype of a
+default-initialized stand-alone object, or as the subtype of an uninitialized
+allocator, as in this example:
 
 .. code-block:: ada
 
-Inst : Base'Class;
-type Array_of_Base is array (Positive range <>) of Base'Class;
+Obj : Root_Type'Class;
+type Array_of_Roots is array (Positive range <>) of Root_Type'Class;
 
-If the ``Size'Class`` aspect is specified for a type ``T``, then every
-specific descendant of ``T`` [redundant: (including ``T``)]
+Default initialization of an object of such a definite subtype proceeds as
+for the corresponding specific type, except that Program_Error is raised if
+the specific type is abstract. In particular, the initial tag of the object
+is that of the corresponding specific type.
 
-- shall have a Size that does not exceed the specified value; and
+There is a general design principle that if a type has a tagged partial view,
+then the type's ``Size'Class`` aspect (or lack thereof) should be determinable
+by looking only at the partial view. That provides the motivation for the
+rules of the next two paragraphs.
 
-- shall be undiscriminated; and
+If a type has a tagged partial view, then a ``Size'Class`` aspect specification
+may be provided only at the point of the partial view declaration (in other
+words, no such aspect specification may be provided when the full view of
+the type is declared). All of the above rules (in particular, the rule that
+an overriding ``Size'Clas

[COMMITTED 14/40] ada: Record type Put_Image procedures omitting discriminant values

2025-06-30 Thread Marc Poulhiès
From: Steve Baird 

If a type T has a partial view with a known_discriminant_part and no
user-specified Put_Image aspect specification, then the output generated
by  T'Put_Image would incorrectly omit the discriminant values.

gcc/ada/ChangeLog:

* exp_put_image.adb (Build_Record_Put_Image_Procedure): If
Discriminant_Specifications takes us from the full view of a type
to an (intentionally) unanalyzed subtree, then instead find
discriminant entities by calling Discriminant_Specifications on
the partial view of the type.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_put_image.adb | 55 +--
 1 file changed, 41 insertions(+), 14 deletions(-)

diff --git a/gcc/ada/exp_put_image.adb b/gcc/ada/exp_put_image.adb
index ae5fa40fa38..40b2a65b821 100644
--- a/gcc/ada/exp_put_image.adb
+++ b/gcc/ada/exp_put_image.adb
@@ -695,17 +695,15 @@ package body Exp_Put_Image is
Put_Image_Base_Type
  (Get_Corresponding_Mutably_Tagged_Type_If_Present (Etype (C)));
   begin
- if Ekind (C) /= E_Void then
-Append_To (Clist,
-  Make_Attribute_Reference (Loc,
-Prefix => New_Occurrence_Of (Component_Typ, Loc),
-Attribute_Name => Name_Put_Image,
-Expressions=> New_List (
-  Make_Identifier (Loc, Name_S),
-  Make_Selected_Component (Loc,
-Prefix=> Make_Identifier (Loc, Name_V),
-Selector_Name => New_Occurrence_Of (C, Loc);
- end if;
+ Append_To (Clist,
+   Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (Component_Typ, Loc),
+ Attribute_Name => Name_Put_Image,
+ Expressions=> New_List (
+   Make_Identifier (Loc, Name_S),
+   Make_Selected_Component (Loc,
+ Prefix=> Make_Identifier (Loc, Name_V),
+ Selector_Name => New_Occurrence_Of (C, Loc);
   end Append_Component_Attr;
 
   ---
@@ -944,9 +942,38 @@ package body Exp_Put_Image is
 
  --  Generate Put_Images for the discriminants of the type
 
- Append_List_To (Stms,
-   Make_Component_Attributes
- (Discriminant_Specifications (Type_Decl)));
+ declare
+Discrim_Specs : List_Id := Discriminant_Specifications (Type_Decl);
+Partial_View  : Entity_Id;
+ begin
+if Present (First (Discrim_Specs))
+  and then Ekind (Defining_Identifier (First (Discrim_Specs))) =
+   E_Void
+then
+   --  If the known discriminant part is repeated for the
+   --  completion of a private type declaration, then the
+   --  second copy is (by design) not analyzed. So we'd better
+   --  use the first copy instead.
+
+   Partial_View := Incomplete_Or_Partial_View
+ (Defining_Identifier (Type_Decl));
+
+   pragma Assert (Ekind (Partial_View) in
+  E_Private_Type
+| E_Limited_Private_Type
+| E_Record_Type_With_Private);
+
+   Discrim_Specs :=
+ Discriminant_Specifications (Parent (Partial_View));
+
+   pragma Assert (Present (First (Discrim_Specs)));
+   pragma Assert
+ (Ekind (Defining_Identifier (First (Discrim_Specs))) /=
+  E_Void);
+end if;
+
+Append_List_To (Stms, Make_Component_Attributes (Discrim_Specs));
+ end;
 
  Rdef := Type_Definition (Type_Decl);
 
-- 
2.43.0



[COMMITTED 35/40] ada: Remove obsolete comment

2025-06-30 Thread Marc Poulhiès
From: Ronan Desplanques 

This patch removes a comment that was left over when an exception
declaration was removed.

gcc/ada/ChangeLog:

* sem_ch5.adb (Analyze_Loop_Statement): Remove obsolete comment.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_ch5.adb | 4 
 1 file changed, 4 deletions(-)

diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 0c2cb2cb91d..12b04fd8e88 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -3561,10 +3561,6 @@ package body Sem_Ch5 is

 
procedure Analyze_Loop_Statement (N : Node_Id) is
-
-  --  The following exception is raised by routine Prepare_Loop_Statement
-  --  to avoid further analysis of a transformed loop.
-
   procedure Prepare_Loop_Statement
 (Iter: Node_Id;
  Stop_Processing : out Boolean);
-- 
2.43.0



Re: [PATCH][RFC] phiopt: Optimize A < 0 ? ARG1 OP 2^n-1 : ARG1

2025-06-30 Thread Jeff Law




On 6/30/25 2:18 AM, Richard Biener wrote:

On Sat, 28 Jun 2025, Jeff Law wrote:




On 6/27/25 12:20 PM, Andrew Pinski wrote:







I have been trying to most of the phiopt to over to use match and simplify
(via match.pd patterns). Is there an issue why this can't be a match pattern
instead? It seems like a good fit too.
It should simplify the code added even.

I can certainly see the appeal in not having to write recognition code by
hand.  But I didn't think match.pd handled if-then-else conditionals sanely.
I guess if something is handing us the ternary form reasonably consistently,
then that's a huge step forward.

If we set aside the match.pd vs phiopt question the other question in this
space is cost model and canonical form.

Which of these would be considered the least costly in the gimple model:

x = c < 0 ? -1 : 16384


cost 1


or

t = c >> 63;
x = t | 16384;


cost 2


or

if (c < 0) then goto bb1 else goto bb2

bb1:

bb2:
x = phi (-1 (b1), 16384 (bb2))


cost 2


The first form at least gives targets without a reasonable shifter (h8, sh,
and a few others) a fighting chance to lower to efficient target code during
the gimple->rtl expansion phase.  The second option makes it harder to support
the oddballs, but makes the common case easy as we don't really have to do
anything.  The last form is undesirable IMHO.


IMO we need to select a "canonical" variant that is easy to transform
into one of the others which rules out the >>| form.

That works for me.

So I think the overall direction is:

1. Try to do the translation in match.pd
2. Target the conditional move form
3. Adjust expanders and/or target bits as necessary to avoid regressions


Right?



Jeff



[COMMITTED 19/40] ada: Fix detection of ghost objects in assignment statements

2025-06-30 Thread Marc Poulhiès
From: Piotr Trojanek 

Remove duplicated and inconsistent code for detecting ghost objects on the
left-hand side of assignment statements. Fix detection in the presence of
attribute references (e.g. "X'Access.all"), function calls (e.g. "F.all"),
qualified expressions (e.g. "T'(new Integer'(0)).all") and unchecked type
conversions (which come from expansion).

gcc/ada/ChangeLog:

* ghost.adb
(Whole_Object_Ref): Remove; use Get_Enclosing_Ghost_Object instead.
(Is_Ghost_Assignment): Handle more than object identifiers.
(Mark_And_Set_Ghost_Assignment): Likewise.
* sem_util.adb (Get_Enclosing_Ghost_Object): Detect more expressions
as ghost references; rename to better match the intended meaning.
* sem_util.ads (Get_Enclosing_Ghost_Object): Rename; adjust comment.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/ghost.adb| 62 +++-
 gcc/ada/sem_util.adb | 29 ++---
 gcc/ada/sem_util.ads |  5 ++--
 3 files changed, 38 insertions(+), 58 deletions(-)

diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb
index 314a13deba8..2c61f3a80ab 100644
--- a/gcc/ada/ghost.adb
+++ b/gcc/ada/ghost.adb
@@ -67,12 +67,6 @@ package body Ghost is
-- Local subprograms --
---
 
-   function Whole_Object_Ref (Ref : Node_Id) return Node_Id;
-   --  For a name that denotes an object, returns a name that denotes the whole
-   --  object, declared by an object declaration, formal parameter declaration,
-   --  etc. For example, for P.X.Comp (J), if P is a package X is a record
-   --  object, this returns P.X.
-
function Ghost_Entity (Ref : Node_Id) return Entity_Id;
pragma Inline (Ghost_Entity);
--  Obtain the entity of a Ghost entity from reference Ref. Return Empty if
@@ -787,7 +781,7 @@ package body Ghost is
   Formal : Entity_Id;
   Is_Default : Boolean := False)
is
-  Actual_Obj : constant Entity_Id := Get_Enclosing_Deep_Object (Actual);
+  Actual_Obj : constant Entity_Id := Get_Enclosing_Ghost_Object (Actual);
begin
   if not Is_Ghost_Entity (Formal) then
  return;
@@ -1197,7 +1191,7 @@ package body Ghost is
   --  entity.
 
   if Nkind (N) = N_Assignment_Statement then
- Id := Ghost_Entity (Name (N));
+ Id := Get_Enclosing_Ghost_Object (Name (N));
 
  return Present (Id) and then Is_Ghost_Entity (Id);
   end if;
@@ -1492,29 +1486,23 @@ package body Ghost is
 end if;
 
 declare
-   Whole : constant Node_Id := Whole_Object_Ref (Lhs);
-   Id: Entity_Id;
+   Id : constant Entity_Id := Get_Enclosing_Ghost_Object (Lhs);
 begin
-   if Is_Entity_Name (Whole) then
-  Id := Entity (Whole);
+   if Present (Id) then
+  --  Left-hand side denotes a Checked ghost entity, so install
+  --  the region.
 
-  if Present (Id) then
- --  Left-hand side denotes a Checked ghost entity, so
- --  install the region.
+  if Is_Checked_Ghost_Entity (Id) then
+ Install_Ghost_Region (Check, N);
 
- if Is_Checked_Ghost_Entity (Id) then
-Install_Ghost_Region (Check, N);
+  --  Left-hand side denotes an Ignored ghost entity, so
+  --  install the region, and mark the assignment statement as
+  --  an ignored ghost assignment, so it will be removed later.
 
- --  Left-hand side denotes an Ignored ghost entity, so
- --  install the region, and mark the assignment statement
- --  as an ignored ghost assignment, so it will be removed
- --  later.
-
- elsif Is_Ignored_Ghost_Entity (Id) then
-Install_Ghost_Region (Ignore, N);
-Set_Is_Ignored_Ghost_Node (N);
-Record_Ignored_Ghost_Node (N);
- end if;
+  elsif Is_Ignored_Ghost_Entity (Id) then
+ Install_Ghost_Region (Ignore, N);
+ Set_Is_Ignored_Ghost_Node (N);
+ Record_Ignored_Ghost_Node (N);
   end if;
end if;
 end;
@@ -2157,24 +2145,4 @@ package body Ghost is
   end if;
end Set_Is_Ghost_Entity;
 
-   --
-   -- Whole_Object_Ref --
-   --
-
-   function Whole_Object_Ref (Ref : Node_Id) return Node_Id is
-   begin
-  if Nkind (Ref) in N_Indexed_Component | N_Slice
-or else (Nkind (Ref) = N_Selected_Component
-   and then Is_Object_Reference (Prefix (Ref)))
-  then
- if Is_Access_Type (Etype (Prefix (Ref))) then
-return Ref;
- else
-   

[COMMITTED 28/40] ada: Sort subprogram declaration in alphabetic order

2025-06-30 Thread Marc Poulhiès
From: Piotr Trojanek 

Code cleanup; semantics is unaffected.

gcc/ada/ChangeLog:

* sem_util.ads (Get_Enclosing_Object, Get_Enum_Lit_From_Pos,
Is_Universal_Numeric_Type): Reorder declarations.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_util.ads | 42 +-
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 6e458664864..e9c12636b04 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -1139,15 +1139,28 @@ package Sem_Util is
--  identifier provided as the external name. Letters in the name are
--  according to the setting of Opt.External_Name_Default_Casing.
 
-   function Get_Enclosing_Object (N : Node_Id) return Entity_Id;
-   --  If expression N references a part of an object, return this object.
-   --  Otherwise return Empty. Expression N should have been resolved already.
-
function Get_Enclosing_Ghost_Entity (N : Node_Id) return Entity_Id;
--  If expression N references a name of either an object or of a
--  subprogram, then return its outermost entity that determines
--  whether this name denotes a ghost object.
 
+   function Get_Enclosing_Object (N : Node_Id) return Entity_Id;
+   --  If expression N references a part of an object, return this object.
+   --  Otherwise return Empty. Expression N should have been resolved already.
+
+   function Get_Enum_Lit_From_Pos
+ (T   : Entity_Id;
+  Pos : Uint;
+  Loc : Source_Ptr) return Node_Id;
+   --  This function returns an identifier denoting the E_Enumeration_Literal
+   --  entity for the specified value from the enumeration type or subtype T.
+   --  The second argument is the Pos value. Constraint_Error is raised if
+   --  argument Pos is not in range. The third argument supplies a source
+   --  location for constructed nodes returned by this function. If No_Location
+   --  is supplied as source location, the location of the returned node is
+   --  copied from the original source location for the enumeration literal,
+   --  when available.
+
function Get_Generic_Entity (N : Node_Id) return Entity_Id;
--  Returns the true generic entity in an instantiation. If the name in the
--  instantiation is a renaming, the function returns the renamed generic.
@@ -1213,19 +1226,6 @@ package Sem_Util is
--  When flag Do_Checks is set, this routine will flag duplicate uses of
--  aspects.
 
-   function Get_Enum_Lit_From_Pos
- (T   : Entity_Id;
-  Pos : Uint;
-  Loc : Source_Ptr) return Node_Id;
-   --  This function returns an identifier denoting the E_Enumeration_Literal
-   --  entity for the specified value from the enumeration type or subtype T.
-   --  The second argument is the Pos value. Constraint_Error is raised if
-   --  argument Pos is not in range. The third argument supplies a source
-   --  location for constructed nodes returned by this function. If No_Location
-   --  is supplied as source location, the location of the returned node is
-   --  copied from the original source location for the enumeration literal,
-   --  when available.
-
function Get_Iterable_Type_Primitive
  (Typ : Entity_Id;
   Nam : Name_Id) return Entity_Id;
@@ -2443,15 +2443,15 @@ package Sem_Util is
--  Determine whether an arbitrary entity denotes an instance of function
--  Ada.Unchecked_Conversion.
 
-   function Is_Universal_Numeric_Type (T : Entity_Id) return Boolean;
-   pragma Inline (Is_Universal_Numeric_Type);
-   --  True if T is Universal_Integer or Universal_Real
-
function Is_Unconstrained_Or_Tagged_Item (Item : Entity_Id) return Boolean;
--  Subsidiary to Collect_Subprogram_Inputs_Outputs and the analysis of
--  pragma Depends. Determine whether the type of dependency item Item is
--  tagged, unconstrained array or unconstrained record.
 
+   function Is_Universal_Numeric_Type (T : Entity_Id) return Boolean;
+   pragma Inline (Is_Universal_Numeric_Type);
+   --  True if T is Universal_Integer or Universal_Real
+
function Is_User_Defined_Equality (Id : Entity_Id) return Boolean;
--  Determine whether an entity denotes a user-defined equality
 
-- 
2.43.0



Re: [PATCH 1/1] libstdc++: Implement default_accessor from mdspan.

2025-06-30 Thread Jonathan Wakely
On Mon, 30 Jun 2025 at 11:48, Tomasz Kaminski  wrote:
>
>
>
> On Mon, Jun 30, 2025 at 9:58 AM Tomasz Kaminski  wrote:
>>
>>
>>
>> On Mon, Jun 30, 2025 at 9:25 AM Luc Grosheintz  
>> wrote:
>>>
>>> libstdc++-v3/ChangeLog:
>>>
>>> * include/std/mdspan (default_accessor): New class.
>>> * src/c++23/std.cc.in: Register default_accessor.
>>> * testsuite/23_containers/mdspan/accessors/default.cc: New test.
>>> * testsuite/23_containers/mdspan/accessors/default_neg.cc: New test.
>>>
>>> Signed-off-by: Luc Grosheintz 
>>> ---
>>>
>>> Version of v5 with all local changes included.
>>
>> LGTM, tested locally and now running a full test suite.
>> Once it will get approval from Jonathan, I will handle merging it.
>
> All test passed.

OK for trunk, thank you both.

>>
>>
>>>
>>>
>>>  libstdc++-v3/include/std/mdspan   | 31 ++
>>>  libstdc++-v3/src/c++23/std.cc.in  |  3 +-
>>>  .../23_containers/mdspan/accessors/default.cc | 99 +++
>>>  .../mdspan/accessors/default_neg.cc   | 23 +
>>>  4 files changed, 155 insertions(+), 1 deletion(-)
>>>  create mode 100644 
>>> libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
>>>  create mode 100644 
>>> libstdc++-v3/testsuite/23_containers/mdspan/accessors/default_neg.cc
>>>
>>> diff --git a/libstdc++-v3/include/std/mdspan 
>>> b/libstdc++-v3/include/std/mdspan
>>> index 6dc2441f80b..c72a64094b7 100644
>>> --- a/libstdc++-v3/include/std/mdspan
>>> +++ b/libstdc++-v3/include/std/mdspan
>>> @@ -1004,6 +1004,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>>[[no_unique_address]] _S_strides_t _M_strides;
>>>  };
>>>
>>> +  template
>>> +struct default_accessor
>>> +{
>>> +  static_assert(!is_array_v<_ElementType>,
>>> +   "ElementType must not be an array type");
>>> +  static_assert(!is_abstract_v<_ElementType>,
>>> +   "ElementType must not be an abstract class type");
>>> +
>>> +  using offset_policy = default_accessor;
>>> +  using element_type = _ElementType;
>>> +  using reference = element_type&;
>>> +  using data_handle_type = element_type*;
>>> +
>>> +  constexpr
>>> +  default_accessor() noexcept = default;
>>> +
>>> +  template
>>> +   requires is_convertible_v<_OElementType(*)[], element_type(*)[]>
>>> +   constexpr
>>> +   default_accessor(default_accessor<_OElementType>) noexcept
>>> +   { }
>>> +
>>> +  constexpr reference
>>> +  access(data_handle_type __p, size_t __i) const noexcept
>>> +  { return __p[__i]; }
>>> +
>>> +  constexpr data_handle_type
>>> +  offset(data_handle_type __p, size_t __i) const noexcept
>>> +  { return __p + __i; }
>>> +};
>>> +
>>>  _GLIBCXX_END_NAMESPACE_VERSION
>>>  }
>>>  #endif
>>> diff --git a/libstdc++-v3/src/c++23/std.cc.in 
>>> b/libstdc++-v3/src/c++23/std.cc.in
>>> index 9336118f5d9..e692caaa5f9 100644
>>> --- a/libstdc++-v3/src/c++23/std.cc.in
>>> +++ b/libstdc++-v3/src/c++23/std.cc.in
>>> @@ -1850,7 +1850,8 @@ export namespace std
>>>using std::layout_left;
>>>using std::layout_right;
>>>using std::layout_stride;
>>> -  // FIXME layout_left_padded, layout_right_padded, default_accessor and 
>>> mdspan
>>> +  using std::default_accessor;
>>> +  // FIXME layout_left_padded, layout_right_padded, aligned_accessor and 
>>> mdspan
>>>  }
>>>  #endif
>>>
>>> diff --git 
>>> a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc 
>>> b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
>>> new file mode 100644
>>> index 000..c036f8ad10f
>>> --- /dev/null
>>> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
>>> @@ -0,0 +1,99 @@
>>> +// { dg-do run { target c++23 } }
>>> +#include 
>>> +
>>> +#include 
>>> +
>>> +constexpr size_t dyn = std::dynamic_extent;
>>> +
>>> +template
>>> +  constexpr void
>>> +  test_accessor_policy()
>>> +  {
>>> +static_assert(std::copyable);
>>> +static_assert(std::is_nothrow_move_constructible_v);
>>> +static_assert(std::is_nothrow_move_assignable_v);
>>> +static_assert(std::is_nothrow_swappable_v);
>>> +  }
>>> +
>>> +constexpr bool
>>> +test_access()
>>> +{
>>> +  std::default_accessor accessor;
>>> +  std::array a{10, 11, 12, 13, 14};
>>> +  VERIFY(accessor.access(a.data(), 0) == 10);
>>> +  VERIFY(accessor.access(a.data(), 4) == 14);
>>> +  return true;
>>> +}
>>> +
>>> +constexpr bool
>>> +test_offset()
>>> +{
>>> +  std::default_accessor accessor;
>>> +  std::array a{10, 11, 12, 13, 14};
>>> +  VERIFY(accessor.offset(a.data(), 0) == a.data());
>>> +  VERIFY(accessor.offset(a.data(), 4) == a.data() + 4);
>>> +  return true;
>>> +}
>>> +
>>> +class Base
>>> +{ };
>>> +
>>> +class Derived : public Base
>>> +{ };
>>> +
>>> +constexpr void
>>> +test_ctor()
>>> +{
>>> +  // T -> T
>>> +  
>>> static_assert(std::is_nothrow_constructible_v,
>>> +   
>>> std::default_accessor>);
>>> +  static

[COMMITTED 29/40] ada: Array aggregates of mutably tagged objects

2025-06-30 Thread Marc Poulhiès
From: Javier Miranda 

When an array of mutably tagged class-wide types is initialized
with an array aggregate, the compiler erroneously rejects it
reporting that the type of the aggregate cannot be a
class-wide type. In addition, Program_Error is not raised at
runtime on array type or record type objects when they have
mutably tagged abstract class-wide type components that are
initialized by default.

gcc/ada/ChangeLog:

* sem_aggr.adb (Resolve_Record_Aggregate): Adjust the code to
handle mutably tagged class-wide types since they don't have
discriminants, but all class-wide types are considered to have
unknown discriminants. Initialize mutably tagged class-wide
type components calling their IP subprogram.
* exp_aggr.adb (Gen_Assign): Handle mutably tagged class-wide type
components that have an initializing qualified expression, and
mutably tagged class-wide components default initialization.
(Gen_Loop): Handle mutably tagged class-wide types.
(Gen_Assign): ditto.
(Build_Record_Aggr_Code): Default initialization of mutably tagged
class-wide types is performed by their IP subprogram.
* exp_ch3.adb (Init_Component): Generate code to raise Program_Error
in the IP subprogram of arrays when the type of their components is
a mutably tagged abstract class-wide type.
(Build_Init_Procedure): ditto for the init procedure of record types.
(Build_Init_Statements): Ensure that the type of the expression
initializing a mutably class-wide tagged type component is frozen.
(Requires_Init_Proc): Mutably tagged class-wide types require the
init-proc since it takes care of their default initialization.
* sem_util.adb (Needs_Simple_Initialization): Mutably tagged class-wide
types don't require simple initialization.
* types.ads (PE_Abstract_Type_Component): New reason for Program_Error.
* types.h (PE_Abstract_Type_Component): ditto.
* exp_ch11.adb (Get_RT_Exception_Name): Handle new reason for
Program_Error.
* libgnat/a-except.adb (Rcheck_PE_Abstract_Type_Component): New
subprogram.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_aggr.adb | 244 ++-
 gcc/ada/exp_ch11.adb |   2 +
 gcc/ada/exp_ch3.adb  |  57 +++-
 gcc/ada/libgnat/a-except.adb |  18 +++
 gcc/ada/sem_aggr.adb |  28 +++-
 gcc/ada/sem_util.adb |   5 -
 gcc/ada/types.ads|   4 +-
 gcc/ada/types.h  |   5 +-
 8 files changed, 288 insertions(+), 75 deletions(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index a25d28d2edd..e3734a2d8c9 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -1407,6 +1407,23 @@ package body Exp_Aggr is
N_Iterated_Component_Association
then
   null;
+
+   --  For mutably tagged class-wide type components that have an
+   --  initializing qualified expression, the expression must be
+   --  analyzed and resolved using the type of the qualified
+   --  expression; otherwise spurious errors would be reported
+   --  because components defined in derivations of the root type
+   --  of the mutably tagged class-wide type would not be visible.
+
+   --  Resolve_Aggr_Expr has previously checked that the type of
+   --  the qualified expression is a descendant of the root type
+   --  of the mutably class-wide tagged type.
+
+   elsif Is_Mutably_Tagged_Type (Comp_Typ)
+ and then Nkind (Expr) = N_Qualified_Expression
+   then
+  Analyze_And_Resolve (Expr_Q, Etype (Expr));
+
else
   Analyze_And_Resolve (Expr_Q, Comp_Typ);
end if;
@@ -1440,12 +1457,54 @@ package body Exp_Aggr is
  end if;
 
  if Present (Expr) then
-Initialize_Component
-  (N  => N,
-   Comp   => Indexed_Comp,
-   Comp_Typ   => Comp_Typ,
-   Init_Expr  => Expr,
-   Stmts  => Stmts);
+
+--  For mutably tagged abstract class-wide types, we rely on the
+--  type of the initializing expression to initialize the tag of
+--  each array component.
+
+--  Generate:
+-- expr_type!(Indexed_Comp) := expr;
+-- expr_type!(Indexed_Comp)._tag := expr_type'Tag;
+
+if Is_Mutably_Tagged_Type (Comp_Typ)
+  and then Is_Abstract_Type (Root_Type (Comp_Typ))
+then
+   declare
+  Expr_Type : Entity_Id;
+
+   begin
+  if Nkind (Expr) in N_Has_Etype
+and then Present (Etype (Expr))
+  

[COMMITTED 21/40] ada: Remove redundant `gnatls -l` switch

2025-06-30 Thread Marc Poulhiès
From: Tonu Naks 

gcc/ada/ChangeLog:

* gnatls.adb: remove -l switch

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/gnatls.adb | 39 ---
 1 file changed, 39 deletions(-)

diff --git a/gcc/ada/gnatls.adb b/gcc/ada/gnatls.adb
index 6fa2327e724..5f7e490c1c5 100644
--- a/gcc/ada/gnatls.adb
+++ b/gcc/ada/gnatls.adb
@@ -117,7 +117,6 @@ procedure Gnatls is
 
Also_Predef   : Boolean := False;  --  -a
Dependable: Boolean := False;  --  -d
-   License   : Boolean := False;  --  -l
Very_Verbose_Mode : Boolean := False;  --  -V
--  Command line flags
 
@@ -188,9 +187,6 @@ procedure Gnatls is
procedure Usage;
--  Print usage message
 
-   procedure Output_License_Information;
-   --  Output license statement, and if not found, output reference to COPYING
-
function Image (Restriction : Restriction_Id) return String;
--  Returns the capitalized image of Restriction
 
@@ -881,20 +877,6 @@ procedure Gnatls is
   return Normalize_Pathname (Path);
end Normalize;
 
-   
-   -- Output_License_Information --
-   
-
-   procedure Output_License_Information is
-   begin
-  case Build_Type is
- when others =>
-Write_Str ("Please refer to file COPYING in your distribution"
- & " for license terms.");
-Write_Eol;
-  end case;
-   end Output_License_Information;
-
---
-- Output_Object --
---
@@ -1794,7 +1776,6 @@ procedure Gnatls is
when 'o' => Reset_Print; Print_Object := True;
when 'v' => Verbose_Mode  := True;
when 'd' => Dependable:= True;
-   when 'l' => License   := True;
when 'V' => Very_Verbose_Mode := True;
 
when others => OK := False;
@@ -1948,11 +1929,6 @@ procedure Gnatls is
"depend");
   Write_Eol;
 
-  --  Line for -l
-
-  Write_Str ("  -l output license information");
-  Write_Eol;
-
   --  Line for -v
 
   Write_Str ("  -v verbose output, full path and unit " &
@@ -2048,21 +2024,6 @@ begin
   Next_Arg := Next_Arg + 1;
end loop Scan_Args;
 
-   --  If -l (output license information) is given, it must be the only switch
-
-   if License then
-  if Arg_Count = 2 then
- Output_License_Information;
-
-  else
- Set_Standard_Error;
- Write_Str ("Can't use -l with another switch");
- Write_Eol;
- Try_Help;
- Exit_Program (E_Fatal);
-  end if;
-   end if;
-
--  Handle --RTS switch
 
if RTS_Specified /= null then
-- 
2.43.0



[PATCH] tailc: Handle musttail in case of non-cleaned-up cleanups, especially ASan related [PR120608]

2025-06-30 Thread Jakub Jelinek
Hi!

The following testcases FAIL at -O0 -fsanitize=address.  The problem is
we end up with something like
  _26 = foo (x_24(D)); [must tail call]
  // predicted unlikely by early return (on trees) predictor.
  finally_tmp.3_27 = 0;
  goto ; [INV]
...
   :
  # _6 = PHI <_26(3), _23(D)(4)>
  # finally_tmp.3_8 = PHI 
  .ASAN_MARK (POISON, &c, 4);
  if (finally_tmp.3_8 == 1)
goto ; [INV]
  else
goto ; [INV]
  
   :
:
  finally_tmp.4_31 = 0;
  goto ; [INV]
...
   :
  # finally_tmp.4_9 = PHI 
  .ASAN_MARK (POISON, &b, 4);
  if (finally_tmp.4_9 == 1)
goto ; [INV]
  else
goto ; [INV]
...
   :
  # _7 = PHI <_6(8), _34(9)>
  .ASAN_MARK (POISON, &a, 4);

   :
:
  return _7;
before the sanopt pass.  This is -O0, we don't try to do forward
propagation, jump threading etc.  And what is worse, the sanopt
pass lowers the .ASAN_MARK calls that the tailc/musttail passes
already handle into somewthing that they can't easily pattern match.

The following patch fixes that by
1) moving the musttail pass 2 passes earlier (this is mostly just
   for -O0/-Og, for normal optimization levels musttail calls are
   handled in the tailc pass), i.e. across the sanopt and cleanup_eh
   passes
2) recognizes these finally_tmp SSA_NAME assignments, PHIs using those
   and GIMPLE_CONDs deciding based on those both on the backwards
   walk (when we start from the edges to EXIT) and forwards walk
   (when we find a candidate tail call and process assignments
   after those up to the return statement).  For backwards walk,
   ESUCC argument has been added which is either NULL for the
   noreturn musttail case, or the succ edge through which we've
   reached bb and if it sees GIMPLE_COND with such comparison,
   based on the ESUCC and comparison it will remember which later
   edges to ignore later on and which bb must be walked up to the
   start during tail call discovery (the one with the PHI).
3) the move of musttail pass across cleanup_eh pass resulted in
   g++.dg/opt/pr119613.C regressions but moving cleanup_eh before
   sanopt doesn't work too well, so I've extended
   empty_eh_cleanup to also handle resx which doesn't throw
   externally

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk
and say after a week for 15.2?
I know moving a pass on release branches feels risky, though the
musttail pass is only relevant to functions with musttail calls,
so something quite rare and only at -O0/-Og (unless one e.g.
disables the tailc pass).

2025-06-30  Jakub Jelinek  

PR middle-end/120608
* passes.def (pass_musttail): Move before pass_sanopt.
* tree-tailcall.cc (empty_eh_cleanup): Handle GIMPLE_RESX
which doesn't throw externally through recursion on single
eh edge (if any and cnt still allows that).
(find_tail_calls): Add ESUCC, IGNORED_EDGES and MUST_SEE_BBS
arguments.  Handle GIMPLE_CONDs for non-simplified cleanups with
finally_tmp temporaries both on backward and forward walks, adjust
recursive call.
(tree_optimize_tail_calls_1): Adjust find_tail_calls callers.

* c-c++-common/asan/pr120608-3.c: New test.
* c-c++-common/asan/pr120608-4.c: New test.
* g++.dg/asan/pr120608-3.C: New test.
* g++.dg/asan/pr120608-4.C: New test.

--- gcc/passes.def.jj   2025-06-30 10:59:37.603459981 +0200
+++ gcc/passes.def  2025-06-30 12:22:34.279724203 +0200
@@ -444,9 +444,9 @@ along with GCC; see the file COPYING3.
   NEXT_PASS (pass_lower_switch_O0);
   NEXT_PASS (pass_asan_O0);
   NEXT_PASS (pass_tsan_O0);
+  NEXT_PASS (pass_musttail);
   NEXT_PASS (pass_sanopt);
   NEXT_PASS (pass_cleanup_eh);
-  NEXT_PASS (pass_musttail);
   NEXT_PASS (pass_lower_resx);
   NEXT_PASS (pass_nrv);
   NEXT_PASS (pass_gimple_isel);
--- gcc/tree-tailcall.cc.jj 2025-06-27 23:33:57.981203083 +0200
+++ gcc/tree-tailcall.cc2025-06-30 12:38:40.718429291 +0200
@@ -532,8 +532,16 @@ empty_eh_cleanup (basic_block bb, int *e
  && sanitize_flags_p (SANITIZE_ADDRESS)
  && asan_mark_p (g, ASAN_MARK_POISON))
continue;
-  if (is_gimple_resx (g) && stmt_can_throw_external (cfun, g))
-   return true;
+  if (is_gimple_resx (g))
+   {
+ if (stmt_can_throw_external (cfun, g))
+   return true;
+ if (single_succ_p (bb)
+ && (single_succ_edge (bb)->flags & EDGE_EH)
+ && cnt > 1)
+   return empty_eh_cleanup (single_succ (bb), eh_has_tsan_func_exit,
+cnt - 1);
+   }
   return false;
 }
   if (!single_succ_p (bb))
@@ -548,8 +556,9 @@ empty_eh_cleanup (basic_block bb, int *e
 static live_vars_map *live_vars;
 static vec live_vars_vec;
 
-/* Finds tailcalls falling into basic block BB.  The list of found tailcalls is
-   added to the start of RET.  When ONLY_MUSTTAIL is set only handle musttail.
+/* Finds tailcalls falling into basic block BB when coming from edge ESUCC (or
+   NULL).  The list of found 

Re: [PATCH 1/1] ivopts: Fix scan-assembler-not regexes for aarch64/sve test

2025-06-30 Thread Richard Sandiford
Christopher Bazley  writes:
> The test added by r16-1671-ge7ff8e8d77df74 passed despite using
> regular expressions that would never match real assembly language
> output from the compiler. Because the regular expressions were not
> expected to match, and didn't, this was not noticeable; however,
> it also made that part of the test useless.
>
> The regular expressions have been fixed. Verified that the fixed
> regular expressions do match assembly language output produced by
> the compiler before the changes to ivopts in commit e7ff8e8d77d,
> but do not match assembly language output produced by the compiler
> after the changes to ivopts.
>
> gcc/testsuite/ChangeLog:
>
>   * gcc.target/aarch64/sve/adr_7.c: Fix regular expressions.

LGTM, thanks.  Pushed to trunk.

Richard


[COMMITTED 17/40] ada: Elide copy for calls as values of nonlimited by-reference components

2025-06-30 Thread Marc Poulhiès
From: Eric Botcazou 

...in aggregates.  This prevents a temporary from being created on the
primary stack to hold the result of the function calls before it is copied
to the component of the aggregate in the nonlimited by-reference case.

This requires a small tweak to Check_Function_Writable_Actuals to avoid
giving a spurious error in a specific case.

gcc/ada/ChangeLog:

* exp_aggr.ads (Parent_Is_Regular_Aggregate): New predicate.
* exp_aggr.adb (In_Place_Assign_OK.Safe_Component): Implement more
accurate criterion for function calls.
(Convert_To_Assignments): Use Parent_Is_Regular_Aggregate predicate.
(Expand_Array_Aggregate): Likewise.  Remove obsolete comment.
(Initialize_Component): Do not adjust when the expression is a naked
function call and Back_End_Return_Slot is True.
(Parent_Is_Regular_Aggregate): New predicate.
* exp_ch3.adb (Build_Record_Init_Proc.Build_Assignment): Add test of
Back_End_Return_Slot in conjunction with a function call.
* exp_ch4.adb (Expand_Allocator_Expression): Likewise.  Use the
Is_Container_Aggregate predicate to detect container aggregates.
(Expand_N_Case_Expression): Delay the expansion if the parent is a
regular aggregate and the type should not be copied.
(Expand_N_If_Expression): Likewise.
(New_Assign_Copy): New function.
* exp_ch6.adb (Expand_Ctrl_Function_Call): Bail out when the parent
is a regular aggregate.
* sem_util.adb (Check_Function_Writable_Actuals): Do not take into
account attribute references created by the compiler.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_aggr.adb | 66 ++--
 gcc/ada/exp_aggr.ads |  4 ++
 gcc/ada/exp_ch3.adb  | 10 +++--
 gcc/ada/exp_ch4.adb  | 89 +---
 gcc/ada/exp_ch6.adb  | 18 +++--
 gcc/ada/sem_util.adb |  9 +
 6 files changed, 131 insertions(+), 65 deletions(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 8aad7217935..48478f350bb 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -3865,8 +3865,8 @@ package body Exp_Aggr is
 
   function Safe_Component (Expr : Node_Id) return Boolean;
   --  Verify that an expression cannot depend on the target being assigned
-  --  to. Return true for compile-time known values, stand-alone objects,
-  --  parameters passed by copy, calls to functions that return by copy,
+  --  (which is Target_Object if it is set), return true for compile-time
+  --  known values, stand-alone objects, formal parameters passed by copy,
   --  selected components thereof only if the aggregate's type is an array,
   --  indexed components and slices thereof only if the aggregate's type is
   --  a record, and simple expressions involving only these as operands.
@@ -3877,7 +3877,8 @@ package body Exp_Aggr is
   --  which is excluded by the above condition. Additionally, if the target
   --  is statically known, return true for arbitrarily nested selections,
   --  indexations or slicings, provided that their ultimate prefix is not
-  --  the target itself.
+  --  the target itself, and calls to functions that take only these as
+  --  actual parameters provided that the target is not aliased.
 
   
   -- Safe_Aggregate --
@@ -3982,12 +3983,26 @@ package body Exp_Aggr is
   return Check_Component (Prefix (C), T_OK);
 
when N_Function_Call =>
-  if Nkind (Name (C)) = N_Explicit_Dereference then
- return not Returns_By_Ref (Etype (Name (C)));
-  else
- return not Returns_By_Ref (Entity (Name (C)));
+  if No (Target_Object) or else Is_Aliased (Target_Object) then
+ return False;
   end if;
 
+  if Present (Parameter_Associations (C)) then
+ declare
+Actual : Node_Id;
+ begin
+Actual := First_Actual (C);
+while Present (Actual) loop
+   if not Check_Component (Actual, T_OK) then
+  return False;
+   end if;
+   Next_Actual (Actual);
+end loop;
+ end;
+  end if;
+
+  return True;
+
when N_Indexed_Component | N_Slice =>
   --  In a target record, these operations cannot determine
   --  alone a component so we can recurse whatever the target.
@@ -4179,11 +4194,7 @@ package body Exp_Aggr is
  --  excluding container aggregates as these are transformed into
  --  subprogram calls later.
 
- (Nkind (Parent_Node) = N_Component_A

[COMMITTED 11/40] ada: Fix a couple of typos in the sanitizers for Ada

2025-06-30 Thread Marc Poulhiès
From: Jose Ruiz 

gcc/ada/ChangeLog:

* doc/gnat_ugn/gnat_and_program_execution.rst: Fix a
couple of minor formatting issues.
* gnat_ugn.texi: Regenerate.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst | 6 +++---
 gcc/ada/gnat_ugn.texi   | 7 ++-
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst 
b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
index 0184bd4aaf8..58c00e56f5c 100644
--- a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
+++ b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
@@ -4311,7 +4311,7 @@ UndefinedBehaviorSanitizer
 UndefinedBehaviorSanitizer (aka UBSan) modifies the program at compile-time to
 catch various kinds of undefined behavior during program execution.
 
-Different sanitize options 
(:switch:`-fsanitize=alignment,float-cast-overflow,signed-integer-overflow``)
+Different sanitize options 
(:switch:`-fsanitize=alignment,float-cast-overflow,signed-integer-overflow`)
 detect the following types of problems:
 
 * Wrong alignment
@@ -4397,8 +4397,8 @@ detect the following types of problems:
 Int := Integer (Flt); --  Overflow
  end Float_Cast_Overflow;
 
-   If the code is built with the :switch:`-fsanitize=float-cast-overflow` and
-   :switch:`-g` options, the following error is shown at execution time.
+  If the code is built with the :switch:`-fsanitize=float-cast-overflow` and
+  :switch:`-g` options, the following error is shown at execution time.
 
 ::
 
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 2bad9b858b8..bda453bf1d9 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -23102,7 +23102,7 @@ SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 
allocation(s).
 UndefinedBehaviorSanitizer (aka UBSan) modifies the program at compile-time to
 catch various kinds of undefined behavior during program execution.
 
-Different sanitize options 
(@code{-fsanitize=alignment,float-cast-overflow,signed-integer-overflow`})
+Different sanitize options 
(@code{-fsanitize=alignment,float-cast-overflow,signed-integer-overflow})
 detect the following types of problems:
 
 
@@ -23199,8 +23199,6 @@ In the following code:
 
 @quotation
 
-@quotation
-
 @example
 procedure Float_Cast_Overflow is
Flt : Float := Float'Last with Export;
@@ -23220,7 +23218,6 @@ If the code is built with the 
@code{-fsanitize=float-cast-overflow} and
 float_cast_overflow.adb:5:20: runtime error: 3.40282e+38 is outside the range 
of representable values of type 'integer'
 @end example
 @end quotation
-@end quotation
 @end itemize
 
 @c -- Non-breaking space in running text
@@ -30225,8 +30222,8 @@ to permit their use in free software.
 
 @printindex ge
 
-@anchor{d2}@w{  }
 @anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{   
   }
+@anchor{d2}@w{  }
 
 @c %**end of body
 @bye
-- 
2.43.0



[COMMITTED 26/40] ada: Fix Itype-related predicate check omissions (part 2).

2025-06-30 Thread Marc Poulhiès
From: Steve Baird 

Add to the previous fix for this issue to better handle cases where
GNATProve calls Einfo.Utils.Predicate_Function, passing in an Itype.

gcc/ada/ChangeLog:

* einfo-utils.adb (Predicate_Function): Look through an Itype if
that takes us to another subtype of the same type.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/einfo-utils.adb | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/gcc/ada/einfo-utils.adb b/gcc/ada/einfo-utils.adb
index 60ee509da67..417da6e828b 100644
--- a/gcc/ada/einfo-utils.adb
+++ b/gcc/ada/einfo-utils.adb
@@ -2345,6 +2345,25 @@ package body Einfo.Utils is
begin
   pragma Assert (Is_Type (Id));
 
+  if Nkind (Associated_Node_For_Itype (Id)) = N_Subtype_Declaration then
+ declare
+Associated_Id : constant Entity_Id :=
+  Defining_Identifier (Associated_Node_For_Itype (Id));
+ begin
+--  Avoid Itype/predicate problems by looking through Itypes.
+--  We never introduce new predicates for Itypes, so doing this
+--  will never cause us to incorrectly overlook a predicate.
+--  It is not clear whether the FE needs this fix, but
+--  GNATProve does (note that GNATProve calls Predicate_Function).
+
+if Id /= Associated_Id
+  and then Base_Type (Id) = Base_Type (Associated_Id)
+then
+   return Predicate_Function (Associated_Id);
+end if;
+ end;
+  end if;
+
   --  If type is private and has a completion, predicate may be defined on
   --  the full view.
 
-- 
2.43.0



[COMMITTED 13/40] ada: Fix crash on nested access-to-subprogram types

2025-06-30 Thread Marc Poulhiès
From: Ronan Desplanques 

This patch fixes a crash on some subprograms with anonymous
access-to-subprogram parameters by removing delayed freezing of
subprograms in some cases where it wasn't necessary. The -gnatD output
for itypes is also improved.

gcc/ada/ChangeLog:

* sem_ch6.adb (Check_Delayed_Subprogram, Possible_Freeze): Restrict
cases where freezing is delayed.
* sem_ch6.ads (Check_Delayed_Subprogram): Improve documentation
comment.
* sprint.adb (Write_Itype): Improve output.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_ch6.adb | 13 +++--
 gcc/ada/sem_ch6.ads |  5 ++---
 gcc/ada/sprint.adb  |  4 ++--
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 0ecc6d85221..7bce7fb19a7 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -6425,12 +6425,6 @@ package body Sem_Ch6 is
 
  elsif Has_Delayed_Freeze (T) and then not Is_Frozen (T) then
 Set_Has_Delayed_Freeze (Designator);
-
- elsif Is_Access_Type (T)
-   and then Has_Delayed_Freeze (Designated_Type (T))
-   and then not Is_Frozen (Designated_Type (T))
- then
-Set_Has_Delayed_Freeze (Designator);
  end if;
   end Possible_Freeze;
 
@@ -6457,6 +6451,13 @@ package body Sem_Ch6 is
  Next_Formal (F);
   end loop;
 
+  --  RM 13.14 (15.1/6): the primitive subprograms of a tagged type are
+  --  frozen at the place where the type is frozen.
+
+  if Is_Dispatching_Operation (Designator) then
+ Set_Has_Delayed_Freeze (Designator);
+  end if;
+
   --  Mark functions that return by reference. Note that it cannot be done
   --  for delayed_freeze subprograms because the underlying returned type
   --  may not be known yet (for private types).
diff --git a/gcc/ada/sem_ch6.ads b/gcc/ada/sem_ch6.ads
index 1a78c27abf5..7ebbcaa84ac 100644
--- a/gcc/ada/sem_ch6.ads
+++ b/gcc/ada/sem_ch6.ads
@@ -64,9 +64,8 @@ package Sem_Ch6 is
--  respective counterparts.
 
procedure Check_Delayed_Subprogram (Designator : Entity_Id);
-   --  Designator can be a E_Subprogram_Type, E_Procedure or E_Function. If a
-   --  type in its profile depends on a private type without a full
-   --  declaration, indicate that the subprogram or type is delayed.
+   --  Designator can be a E_Subprogram_Type, E_Procedure or E_Function. Set
+   --  Has_Delayed_Freeze on Designator if its freezing needs to be delayed.
 
procedure Check_Formal_Subprogram_Conformance
  (New_Id  : Entity_Id;
diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb
index 938d2b23910..6b74be14b40 100644
--- a/gcc/ada/sprint.adb
+++ b/gcc/ada/sprint.adb
@@ -4634,7 +4634,7 @@ package body Sprint is
Param : Entity_Id;
 
 begin
-   Param := First_Entity (Typ);
+   Param := First_Formal (Typ);
loop
   Write_Id (Param);
   Write_Str (" : ");
@@ -4646,7 +4646,7 @@ package body Sprint is
   end if;
 
   Write_Id (Etype (Param));
-  Next_Entity (Param);
+  Next_Formal (Param);
   exit when No (Param);
   Write_Str (", ");
end loop;
-- 
2.43.0



[COMMITTED 09/40] ada: Fix typo in comment

2025-06-30 Thread Marc Poulhiès
From: Ronan Desplanques 

gcc/ada/ChangeLog:

* atree.ads (Parent_Or_List_Containing): Fix typo.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/atree.ads | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/ada/atree.ads b/gcc/ada/atree.ads
index 615d040c90a..802db870933 100644
--- a/gcc/ada/atree.ads
+++ b/gcc/ada/atree.ads
@@ -453,7 +453,7 @@ package Atree is
 
function Parent_Or_List_Containing (X : Union_Id) return Union_Id;
--  X must be in Node_Range or in List_Range. If X is in Node_Range and is
-   --  contained in a list, returns that list, otherwise return the parent of
+   --  contained in a list, returns that list, otherwise returns the parent of
--  the list or node represented by X.
 
function Paren_Count (N : Node_Id) return Nat;
-- 
2.43.0



[COMMITTED 22/40] ada: Fix bogus error for pragma No_Component_Reordering on record type

2025-06-30 Thread Marc Poulhiès
From: Eric Botcazou 

This happens when the record type has an incomplete declaration before its
full declaration and is fixed by calling Find_Type appropriately.

gcc/ada/ChangeLog:

* sem_prag.adb (Analyze_Pragma) :
Call Find_Type on the first argument of the pragma.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_prag.adb | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 2fc3698a67b..2717c38cdfd 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -21370,8 +21370,8 @@ package body Sem_Prag is
  --  pragma No_Component_Reordering [([Entity =>] type_LOCAL_NAME)];
 
  when Pragma_No_Component_Reordering => No_Comp_Reordering : declare
-E: Entity_Id;
-E_Id : Node_Id;
+Typ : Entity_Id;
+Type_Id : Node_Id;
 
  begin
 GNAT_Pragma;
@@ -21384,19 +21384,20 @@ package body Sem_Prag is
 else
Check_Optional_Identifier (Arg2, Name_Entity);
Check_Arg_Is_Local_Name (Arg1);
-   E_Id := Get_Pragma_Arg (Arg1);
+   Type_Id := Get_Pragma_Arg (Arg1);
 
-   if Etype (E_Id) = Any_Type then
+   Find_Type (Type_Id);
+   Typ := Entity (Type_Id);
+
+   if Typ = Any_Type then
   return;
end if;
 
-   E := Entity (E_Id);
-
-   if not Is_Record_Type (E) then
+   if not Is_Record_Type (Typ) then
   Error_Pragma_Arg ("pragma% requires record type", Arg1);
end if;
 
-   Set_No_Reordering (Base_Type (E));
+   Set_No_Reordering (Base_Type (Typ));
 end if;
  end No_Comp_Reordering;
 
-- 
2.43.0



[COMMITTED 40/40] ada: Fix Execution_Successful value with exceptions

2025-06-30 Thread Marc Poulhiès
From: Viljar Indus 

Store the Exit_Code value and use that to generate
the Exceution_Successful value in the SARIF report.

gcc/ada/ChangeLog:

* comperr.adb (Compiler_Abort): Pass the exit code in calls to
Output_Messages.
* errout.adb (Output_Messages): Add new parameter for the
Exit_Code and store its value.
* errout.ads (Output_Messages): Likewise.
* erroutc-sarif_emitter.adb (Print_Invocations): Set
Execution_Successful based on the exit code.
* erroutc.ads (Exit_Code): Store the exit code value.
* gnat1drv.adb (Gnat1drv): Pass the exit code in calls to
Output_Messages.
* prepcomp.adb (Parse_Preprocessing_Data_File, Prpare_To_Preprocess):
Likewise.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/comperr.adb   |  2 +-
 gcc/ada/errout.adb|  5 +++--
 gcc/ada/errout.ads|  5 +++--
 gcc/ada/erroutc-sarif_emitter.adb |  3 +--
 gcc/ada/erroutc.ads   |  4 
 gcc/ada/gnat1drv.adb  | 26 +++---
 gcc/ada/prepcomp.adb  |  4 ++--
 7 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/gcc/ada/comperr.adb b/gcc/ada/comperr.adb
index 602b13dd59b..c6285e98620 100644
--- a/gcc/ada/comperr.adb
+++ b/gcc/ada/comperr.adb
@@ -146,7 +146,7 @@ package body Comperr is
 
   if Serious_Errors_Detected /= 0 and then not Debug_Flag_K then
  Errout.Finalize (Last_Call => True);
- Errout.Output_Messages;
+ Errout.Output_Messages (E_Errors);
 
  Set_Standard_Error;
  Write_Str ("compilation abandoned due to previous error");
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index 25d1d52e34b..5ed3aab2d9f 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -44,7 +44,6 @@ with Gnatvsn;use Gnatvsn;
 with Lib;use Lib;
 with Opt;use Opt;
 with Nlists; use Nlists;
-with Osint;  use Osint;
 with Output; use Output;
 with Scans;  use Scans;
 with Sem_Aux;use Sem_Aux;
@@ -2710,7 +2709,7 @@ package body Errout is
-- Output_Messages --
-
 
-   procedure Output_Messages is
+   procedure Output_Messages (Exit_Code : Exit_Code_Type) is
 
   --  Local subprograms
 
@@ -2819,6 +2818,8 @@ package body Errout is
  raise Program_Error;
   end if;
 
+  Erroutc.Exit_Code := Exit_Code;
+
   --  Reset current error source file if the main unit has a pragma
   --  Source_Reference. This ensures outputting the proper name of
   --  the source file in this situation.
diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads
index 98aa4b4c120..40b5155f3f7 100644
--- a/gcc/ada/errout.ads
+++ b/gcc/ada/errout.ads
@@ -32,6 +32,7 @@ with Err_Vars;
 with Erroutc;
 with Errid;use Errid;
 with Namet;use Namet;
+with Osint;use Osint;
 with Table;
 with Types;use Types;
 with Uintp;use Uintp;
@@ -716,9 +717,9 @@ package Errout is
--  and must be set True on the last call (a value of True activates some
--  processing that must only be done after all messages are posted).
 
-   procedure Output_Messages;
+   procedure Output_Messages (Exit_Code : Exit_Code_Type);
--  Output list of messages, including messages giving number of detected
-   --  errors and warnings.
+   --  errors and warnings and store the exit code used.
 
procedure Error_Msg
  (Msg : String; Flag_Location : Source_Ptr);
diff --git a/gcc/ada/erroutc-sarif_emitter.adb 
b/gcc/ada/erroutc-sarif_emitter.adb
index 791becb3965..90f7a7c73a9 100644
--- a/gcc/ada/erroutc-sarif_emitter.adb
+++ b/gcc/ada/erroutc-sarif_emitter.adb
@@ -28,7 +28,6 @@ with GNAT.Lists; use GNAT.Lists;
 with Gnatvsn;use Gnatvsn;
 with Lib;use Lib;
 with Namet;  use Namet;
-with Osint;  use Osint;
 with Output; use Output;
 with Sinput; use Sinput;
 with System.OS_Lib;
@@ -759,7 +758,7 @@ package body Erroutc.SARIF_Emitter is
 
   --  Print executionSuccessful
 
-  Write_Boolean_Attribute (N_EXECUTION_SUCCESSFUL, not Compilation_Errors);
+  Write_Boolean_Attribute (N_EXECUTION_SUCCESSFUL, Exit_Code = E_Success);
 
   End_Block;
   NL_And_Indent;
diff --git a/gcc/ada/erroutc.ads b/gcc/ada/erroutc.ads
index 5ee26797c72..2c44b5b1487 100644
--- a/gcc/ada/erroutc.ads
+++ b/gcc/ada/erroutc.ads
@@ -29,10 +29,14 @@
 with Table;
 with Errsw; use Errsw;
 with Errid; use Errid;
+with Osint; use Osint;
 with Types; use Types;
 
 package Erroutc is
 
+   Exit_Code : Exit_Code_Type := E_Success;
+   --  Exit_Code used at the end of the compilation
+
type Error_Msg_Type is
  (Error,  -- Default value
   Non_Serious_Error,
diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb
index 46f04e484b7..ec57cd23731 100644
--- a/gcc/ada/gnat1drv.adb
+++ b/gcc/ada/gnat1drv.adb
@@ -982,7 +982,7 @@ procedure Gnat1drv is
--  Local variables
 
Back_End_Mod

[COMMITTED 31/40] ada: Fix missing rounding in System.Value_R.Scan_Raw_Real

2025-06-30 Thread Marc Poulhiès
From: Eric Botcazou 

The extra digit returned by the function is supposed to be rounded, either
by Scan_Integral_Digits or by Scan_Decimal_Digits, but that is not the case
when it is the last digit read by Scan_Integral_Digits.

The problem is fixed by rounding it in Scan_Decimal_Digits in this case.

gcc/ada/ChangeLog:

* libgnat/s-valuer.adb (Scan_Decimal_Digits): Also pretend that the
precision limit was just reached if it was already reached.
(Scan_Integral_Digits): Add Extra_Rounded out parameter, set it to
False on entry and to True when Extra is rounded.
(Scan_Raw_Real): New Extra_Rounded local variable.  Pass it in the
calls to Scan_Integral_Digits.  If it is True, pass a dummy extra
digit to Scan_Decimal_Digits.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/libgnat/s-valuer.adb | 47 +++-
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/gcc/ada/libgnat/s-valuer.adb b/gcc/ada/libgnat/s-valuer.adb
index 46f85e11159..faedb884a6a 100644
--- a/gcc/ada/libgnat/s-valuer.adb
+++ b/gcc/ada/libgnat/s-valuer.adb
@@ -84,6 +84,7 @@ package body System.Value_R is
Scale  : out Scale_Array;
N  : out Positive;
Extra  : out Char_As_Digit;
+   Extra_Rounded  : out Boolean;
Base_Violation : in out Boolean);
--  Scan the integral part of a real (i.e. before decimal separator)
--
@@ -93,7 +94,7 @@ package body System.Value_R is
--  For each digit parsed, either Value := Value * Base + Digit or Scale
--  is incremented by 1 if precision limit is reached, in which case the
--  remaining digits are still parsed but ignored, except for the first
-   --  which is stored in Extra.
+   --  which is stored in Extra, rounded if Extra_Rounded is True.
--
--  Base_Violation is set to True if a digit found is not part of the Base
--
@@ -207,18 +208,22 @@ package body System.Value_R is
   --  Number of trailing zeros at a given point
 
begin
-  --  If initial Scale is not 0 then it means that Precision_Limit was
+  --  If initial Scale is not 0, then this means that Precision_Limit was
   --  reached during scanning of the integral part.
 
   if Scale (Data_Index'Last) > 0 then
  Precision_Limit_Reached := True;
+
+ if Round then
+Precision_Limit_Just_Reached := True;
+ end if;
   else
  Extra := 0;
  Precision_Limit_Reached := False;
-  end if;
 
-  if Round then
- Precision_Limit_Just_Reached := False;
+ if Round then
+Precision_Limit_Just_Reached := False;
+ end if;
   end if;
 
   --  Initialize trailing zero counter
@@ -373,6 +378,7 @@ package body System.Value_R is
Scale  : out Scale_Array;
N  : out Positive;
Extra  : out Char_As_Digit;
+   Extra_Rounded  : out Boolean;
Base_Violation : in out Boolean)
is
   pragma Assert (Base in 2 .. 16);
@@ -398,12 +404,13 @@ package body System.Value_R is
   --  Temporary
 
begin
-  --  Initialize N, Value, Scale and Extra
+  --  Initialize N, Value, Scale, Extra and Extra_Rounded
 
   N := 1;
   Value := (others => 0);
   Scale := (others => 0);
   Extra := 0;
+  Extra_Rounded := False;
 
   Precision_Limit_Reached := False;
 
@@ -443,6 +450,7 @@ package body System.Value_R is
 
 if Round and then Precision_Limit_Just_Reached then
Round_Extra (Digit, Base, Value (N), Scale (N), Extra);
+   Extra_Rounded := True;
Precision_Limit_Just_Reached := False;
 end if;
 
@@ -536,6 +544,9 @@ package body System.Value_R is
   --  If True some digits where not in the base. The real is still scanned
   --  till the end even if an error will be raised.
 
+  Extra_Rounded : Boolean;
+  --  True if Extra has been rounded
+
   N : Positive;
   --  Index number of the current part
 
@@ -585,7 +596,7 @@ package body System.Value_R is
 
  Scan_Integral_Digits
(Str, Index, Max, Base, False, Value, Scale, N,
-Char_As_Digit (Extra), Base_Violation);
+Char_As_Digit (Extra), Extra_Rounded, Base_Violation);
 
   --  A dot is allowed only if followed by a digit (RM 3.5(39.8))
 
@@ -599,6 +610,7 @@ package body System.Value_R is
  Value := (others => 0);
  Scale := (others => 0);
  Extra := 0;
+ Extra_Rounded := False;
 
   else
  Bad_Value (Str);
@@ -648,7 +660,7 @@ package body System.Value_R is
 
  Scan_Integral_Digits
(Str, Index, Max, Base, Base_Char /= ASCII.NUL, Value, Scale,
-N, Char_As_Digit (Extra), Base_Violation);
+N, Char_As_Digit (Extra), Extra_Rounded, Base_Violation);
   end if;
 
   --  Do we have a dot?
@@ -673

[COMMITTED 24/40] ada: Tune name and commend document of a ghost utility routine

2025-06-30 Thread Marc Poulhiès
From: Piotr Trojanek 

Detection of ghost entities work similarly for names of objects (in assignment
statements) and for names of subprograms (in subprogram calls). Tune routine
name and its comment to match this similarity.

gcc/ada/ChangeLog:

* sem_util.ads (Get_Enclosing_Ghost_Entity): Rename spec.
* sem_util.adb (Get_Enclosing_Ghost_Object): Rename body; reorder
alphabetically; adapt recursive call.
* ghost.adb: Adapt calls to Get_Enclosing_Ghost_Object.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/ghost.adb| 14 -
 gcc/ada/sem_util.adb | 74 ++--
 gcc/ada/sem_util.ads | 10 +++---
 3 files changed, 48 insertions(+), 50 deletions(-)

diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb
index ac38f3cc239..6f648f2af92 100644
--- a/gcc/ada/ghost.adb
+++ b/gcc/ada/ghost.adb
@@ -776,7 +776,7 @@ package body Ghost is
   Formal : Entity_Id;
   Is_Default : Boolean := False)
is
-  Actual_Obj : constant Entity_Id := Get_Enclosing_Ghost_Object (Actual);
+  Actual_Obj : constant Entity_Id := Get_Enclosing_Ghost_Entity (Actual);
begin
   if not Is_Ghost_Entity (Formal) then
  return;
@@ -1165,7 +1165,7 @@ package body Ghost is
   --  entity.
 
   if Nkind (N) = N_Assignment_Statement then
- Id := Get_Enclosing_Ghost_Object (Name (N));
+ Id := Get_Enclosing_Ghost_Entity (Name (N));
 
  return Present (Id) and then Is_Ghost_Entity (Id);
   end if;
@@ -1223,7 +1223,7 @@ package body Ghost is
   --  A procedure call is Ghost when it invokes a Ghost procedure
 
   if Nkind (N) = N_Procedure_Call_Statement then
- Id := Get_Enclosing_Ghost_Object (Name (N));
+ Id := Get_Enclosing_Ghost_Entity (Name (N));
 
  return Present (Id) and then Is_Ghost_Entity (Id);
   end if;
@@ -1460,7 +1460,7 @@ package body Ghost is
 end if;
 
 declare
-   Id : constant Entity_Id := Get_Enclosing_Ghost_Object (Lhs);
+   Id : constant Entity_Id := Get_Enclosing_Ghost_Entity (Lhs);
 begin
if Present (Id) then
   --  Left-hand side denotes a Checked ghost entity, so install
@@ -1744,7 +1744,7 @@ package body Ghost is
   --  A procedure call becomes Ghost when the procedure being invoked is
   --  Ghost. Install the Ghost mode of the procedure.
 
-  Id := Get_Enclosing_Ghost_Object (Name (N));
+  Id := Get_Enclosing_Ghost_Entity (Name (N));
 
   if Present (Id) then
  if Is_Checked_Ghost_Entity (Id) then
@@ -2058,7 +2058,7 @@ package body Ghost is
   --  of the target.
 
   if Nkind (N) = N_Assignment_Statement then
- Id := Get_Enclosing_Ghost_Object (Name (N));
+ Id := Get_Enclosing_Ghost_Entity (Name (N));
 
  if Present (Id) then
 Set_Ghost_Mode_From_Entity (Id);
@@ -2097,7 +2097,7 @@ package body Ghost is
   --  procedure being invoked.
 
   elsif Nkind (N) = N_Procedure_Call_Statement then
- Id := Get_Enclosing_Ghost_Object (Name (N));
+ Id := Get_Enclosing_Ghost_Entity (Name (N));
 
  if Present (Id) then
 Set_Ghost_Mode_From_Entity (Id);
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index e1b78dce32f..3c2a776ce36 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -10261,6 +10261,43 @@ package body Sem_Util is
   Strval => String_From_Name_Buffer);
end Get_Default_External_Name;
 
+   
+   -- Get_Enclosing_Ghost_Entity --
+   
+
+   function Get_Enclosing_Ghost_Entity (N : Node_Id) return Entity_Id is
+   begin
+  if Is_Entity_Name (N) then
+ return Entity (N);
+  else
+ case Nkind (N) is
+when N_Attribute_Reference
+   | N_Explicit_Dereference
+   | N_Indexed_Component
+   | N_Selected_Component
+   | N_Slice
+=>
+   return Get_Enclosing_Ghost_Entity (Prefix (N));
+
+when N_Function_Call =>
+   return Get_Called_Entity (N);
+
+--  We are interested in the target type, because if it is ghost,
+--  then the object is ghost as well and if it is non-ghost, then
+--  its expression can't be ghost.
+
+when N_Qualified_Expression
+   | N_Type_Conversion
+   | N_Unchecked_Type_Conversion
+=>
+   return Entity (Subtype_Mark (N));
+
+when others =>
+   return Empty;
+ end case;
+  end if;
+   end Get_Enclosing_Ghost_Entity;
+
--
-- Get_Enclosing_Object --
--
@@ -10286,43 +10323,6 @@ package body Sem_Util is
   end if;
end Get_Enclosing_Object;
 
-   
-   -- Get_Enclosing_Ghost_O

Re: [pushed: r16-1830] diagnostics: remove "json" output format

2025-06-30 Thread David Malcolm
On Mon, 2025-06-30 at 15:24 -0400, David Malcolm wrote:
> The "json" output format for diagnostics was deprecated in GCC 15,
> with
> advice to users seeking machine-readable diagnostics from GCC to use
> SARIF instead.
> 
> This patch eliminates it from GCC 16, simplifying the diagnostics
> subsystem somewhat.
> 
> Note that the Ada frontend seems to have its own implementation of
> this
> in errout.adb (Output_JSON_Message), and documented in
> gnat_ugn.texi.  This patch does not touch Ada.
> 
> Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
> Pushed to trunk as r16-1830-g51ce373481e848.

FWIW my testing included the ada frontend.  There don't seem to be any
test coverage for gnat's implementations of json and sarif output, so
if I did break something there, I'm sorry.

Dave

> 
> gcc/ChangeLog:
>   * Makefile.in (OBJS-libcommon): Drop diagnostic-format-
> json.o.
>   * common.opt (fdiagnostics-format=): Drop
>   "json|json-stderr|json-file".
>   (diagnostics_output_format): Drop values "json", "json-
> stderr",
>   and "json-file".
>   * diagnostic-format-json.cc: Delete file.
>   * diagnostic-format.h
>   (diagnostic_output_format_init_json_stderr): Delete.
>   (diagnostic_output_format_init_json_file): Delete.
>   * diagnostic.cc (diagnostic_output_format_init): Delete
> cases for
>   DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR and
>   DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE.
>   * diagnostic.h (DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR):
> Delete.
>   (DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE): Delete.
>   * doc/invoke.texi: Remove references to json output format.
>   * doc/ux.texi: Likewise.
>   * selftest-run-tests.cc (selftest::run_tests): Drop call to
>   deleted selftest::diagnostic_format_json_cc_tests.
>   * selftest.h (selftest::diagnostic_format_json_cc_tests):
> Delete.
> 
> gcc/testsuite/ChangeLog:
>   * c-c++-common/analyzer/out-of-bounds-diagram-1-json.c:
> Deleted test.
>   * c-c++-common/diagnostic-format-json-1.c: Deleted test.
>   * c-c++-common/diagnostic-format-json-2.c: Deleted test.
>   * c-c++-common/diagnostic-format-json-3.c: Deleted test.
>   * c-c++-common/diagnostic-format-json-4.c: Deleted test.
>   * c-c++-common/diagnostic-format-json-5.c: Deleted test.
>   * c-c++-common/diagnostic-format-json-file-1.c: Deleted
> test.
>   * c-c++-common/diagnostic-format-json-stderr-1.c: Deleted
> test.
>   * c-c++-common/pr106133.c: Deleted test.
>   * g++.dg/pr90462.C: Deleted test.
>   * gcc.dg/plugin/diagnostic-test-paths-3.c: Deleted test.
>   * gcc.dg/plugin/plugin.exp (plugin_test_list): Remove
> deleted
>   test.
>   * gfortran.dg/diagnostic-format-json-1.F90: Deleted test.
>   * gfortran.dg/diagnostic-format-json-2.F90: Deleted test.
>   * gfortran.dg/diagnostic-format-json-3.F90: Deleted test.
>   * gfortran.dg/diagnostic-format-json-pr105916.F90: Deleted
> test.
> 
> Signed-off-by: David Malcolm 
> ---
>  gcc/Makefile.in   |   1 -
>  gcc/common.opt    |  11 +-
>  gcc/diagnostic-format-json.cc | 605 
> --
>  gcc/diagnostic-format.h   |   8 -
>  gcc/diagnostic.cc |  11 -
>  gcc/diagnostic.h  |   6 -
>  gcc/doc/invoke.texi   |  23 +-
>  gcc/doc/ux.texi   |   2 +-
>  gcc/selftest-run-tests.cc |   1 -
>  gcc/selftest.h    |   1 -
>  .../analyzer/out-of-bounds-diagram-1-json.c   |  13 -
>  .../c-c++-common/diagnostic-format-json-1.c   |  22 -
>  .../c-c++-common/diagnostic-format-json-2.c   |  26 -
>  .../c-c++-common/diagnostic-format-json-3.c   |  26 -
>  .../c-c++-common/diagnostic-format-json-4.c   |  44 --
>  .../c-c++-common/diagnostic-format-json-5.c   |  38 --
>  .../diagnostic-format-json-file-1.c   |   8 -
>  .../diagnostic-format-json-stderr-1.c |  24 -
>  gcc/testsuite/c-c++-common/pr106133.c |   3 -
>  gcc/testsuite/g++.dg/pr90462.C    |  49 --
>  .../gcc.dg/plugin/diagnostic-test-paths-3.c   |  75 ---
>  gcc/testsuite/gcc.dg/plugin/plugin.exp    |   1 -
>  .../gfortran.dg/diagnostic-format-json-1.F90  |  24 -
>  .../gfortran.dg/diagnostic-format-json-2.F90  |  26 -
>  .../gfortran.dg/diagnostic-format-json-3.F90  |  26 -
>  .../diagnostic-format-json-pr105916.F90   |  14 -
>  26 files changed, 7 insertions(+), 1081 deletions(-)
>  delete mode 100644 gcc/diagnostic-format-json.cc
>  delete mode 100644 gcc/testsuite/c-c++-common/analyzer/out-of-
> bounds-diagram-1-json.c
>  delete mode 100644 gcc/testsuite/c-c++-common/diagnostic-format-
> json-1.c
>  delete mode 100644 gcc/testsuite/c-c++-common/diagnostic-format-
> json-2.c
>  delete mode 100644 gcc/testsuite/c-c++-common/diagnostic-format-
> json-3.c
>  delete mode 100644 gc

Re: [Fortran, Patch, PR120846, v1] Fix ICE when a function is called more than once in a coarray expression.

2025-06-30 Thread Harald Anlauf

Am 30.06.25 um 15:29 schrieb Andre Vehreschild:

Hi all,

attached patch fixes an ICE when in an expression with a coindex a function was
used more than once. E.g. coarray(mod( something ), mod( something else ))[i]
ICE'd because a component for aliasing the second mod() could not be created.

Regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline and gcc-15 later on?

Regards,
Andre


Yes, this is OK for both.

(Be careful about PR numbers, they are correct in the patch;
the subject is off-by-one.)

Thanks for the patch!

Harald




[COMMITTED 16/40] ada: use pointer decay for socket address type compatibility

2025-06-30 Thread Marc Poulhiès
From: Alexandre Oliva 

GCC 14 is stricter about type conversions.  Taking the address of an
array and decaying the array to a pointer to its first element yield
the same address, but the types are no longer considered compatible.
The socket data structures want decayed pointers rather than addresses
of arrays, so drop the '&'s.

gcc/ada/ChangeLog:

* socket.c [__vxworks]
(__gnat_gethostbyname): Drop excess '&'.
(__gnat_gethostbyaddr): Likewise.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/socket.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/gcc/ada/socket.c b/gcc/ada/socket.c
index 77bdde40a24..a22ed993862 100644
--- a/gcc/ada/socket.c
+++ b/gcc/ada/socket.c
@@ -280,10 +280,10 @@ __gnat_gethostbyname (const char *name,
 return -1;
   }
   ret->h_name  = name;
-  ret->h_aliases   = &vxw_h_aliases;
+  ret->h_aliases   = vxw_h_aliases;
   ret->h_addrtype  = AF_INET;
   ret->h_length= 4;
-  ret->h_addr_list = &vxw_h_addr_list;
+  ret->h_addr_list = vxw_h_addr_list;
   return 0;
 }
 
@@ -302,18 +302,18 @@ __gnat_gethostbyaddr (const char *addr, int len, int type,
 return -1;
   }
 
-  if (hostGetByAddr (*(int*)addr, &vxw_h_name) != OK) {
+  if (hostGetByAddr (*(int*)addr, vxw_h_name) != OK) {
 *h_errnop = __gnat_get_h_errno ();
 return -1;
   }
 
   vxw_h_addr   = (long) addr;
 
-  ret->h_name  = &vxw_h_name;
-  ret->h_aliases   = &vxw_h_aliases;
+  ret->h_name  = vxw_h_name;
+  ret->h_aliases   = vxw_h_aliases;
   ret->h_addrtype  = AF_INET;
   ret->h_length= 4;
-  ret->h_addr_list = &vxw_h_addr_list;
+  ret->h_addr_list = vxw_h_addr_list;
   return 0;
 }
 
-- 
2.43.0



[COMMITTED 34/40] ada: Fix bug in -gnatw.o switch (unreferenced out parameters)

2025-06-30 Thread Marc Poulhiès
From: Bob Duff 

Fixes this bug: If -gnatw.o is specified, it is ignored unless
-gnatwm is also specified (either directly, or as part of a
catch-all switch like -gnatwa).

gcc/ada/ChangeLog:

* sem_warn.adb (Warn_On_Useless_Assignments):
Enable Warn_On_Useless_Assignment in the case of
Warn_On_All_Unread_Out_Parameters.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_warn.adb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index 74f9fe304df..32eee3370e2 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -4743,7 +4743,7 @@ package body Sem_Warn is
   Ent : Entity_Id;
 
begin
-  if Warn_On_Modified_Unread
+  if (Warn_On_Modified_Unread or Warn_On_All_Unread_Out_Parameters)
 and then In_Extended_Main_Source_Unit (E)
   then
  Ent := First_Entity (E);
-- 
2.43.0



[COMMITTED 01/40] ada: Adjust comparisons in if-statements according to coding style

2025-06-30 Thread Marc Poulhiès
From: Johannes Kliemann 

The Ada coding style requires the use of short circuit forms in
if-statements. Use this form consistently for all if-statements.

gcc/ada/ChangeLog:

* libgnat/s-valuer.adb: Switch missing if-statements to
short-circuit form.
* libgnat/i-cpoint.adb: Ditto.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/libgnat/i-cpoint.adb | 2 +-
 gcc/ada/libgnat/s-valuer.adb | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/ada/libgnat/i-cpoint.adb b/gcc/ada/libgnat/i-cpoint.adb
index 40a5834edd0..994e639e2f9 100644
--- a/gcc/ada/libgnat/i-cpoint.adb
+++ b/gcc/ada/libgnat/i-cpoint.adb
@@ -148,7 +148,7 @@ package body Interfaces.C.Pointers is
   S : Pointer := Source;
 
begin
-  if Source = null or Target = null then
+  if Source = null or else Target = null then
  raise Dereference_Error;
   end if;
 
diff --git a/gcc/ada/libgnat/s-valuer.adb b/gcc/ada/libgnat/s-valuer.adb
index cc1f778ee4e..46f85e11159 100644
--- a/gcc/ada/libgnat/s-valuer.adb
+++ b/gcc/ada/libgnat/s-valuer.adb
@@ -341,7 +341,7 @@ package body System.Value_R is
 
 --  Underscore is only allowed if followed by a digit
 
-if Digit = Underscore and Index + 1 <= Max then
+if Digit = Underscore and then Index + 1 <= Max then
 
Digit := As_Digit (Str (Index + 1));
if Digit in Valid_Digit then
@@ -496,7 +496,7 @@ package body System.Value_R is
 --  Next character is not a digit. In that case stop scanning
 --  unless the next chracter is an underscore followed by a digit.
 
-if Digit = Underscore and Index + 1 <= Max then
+if Digit = Underscore and then Index + 1 <= Max then
Digit := As_Digit (Str (Index + 1));
if Digit in Valid_Digit then
   Index := Index + 1;
-- 
2.43.0



[COMMITTED 03/40] ada: Fix internal error on Ghost aspect applied to Big_Integers

2025-06-30 Thread Marc Poulhiès
From: Eric Botcazou 

That's a regression introduced by the rewrite of the finalization machinery,
in the form of dangling references to Master_Node entities remaining in the
tree after the removal of the ignored Ghost code.

gcc/ada/ChangeLog:

* exp_ch7.adb (Process_Transient_In_Scope): Bail out if the object
is an ignored ghost entity.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_ch7.adb | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 905094c7e40..1c569b90dd2 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -5275,6 +5275,13 @@ package body Exp_Ch7 is
 Obj_Typ  : Entity_Id;
 
  begin
+--  Ignored Ghost objects do not need any cleanup actions because
+--  they will not appear in the final tree.
+
+if Is_Ignored_Ghost_Entity (Obj_Id) then
+   return;
+end if;
+
 --  If the object needs to be exported to the outer finalizer,
 --  create the declaration of the Master_Node for the object,
 --  which will later be picked up by Build_Finalizer.
-- 
2.43.0



Re: [COMMITED] contrib/mklog.py: Fix writing to a global variable

2025-06-30 Thread Alex Coplan
On 29/06/2025 10:29, Filip Kastl wrote:
> The last patch of mklog.py put top-level code into function 'main()'.
> Because of this, writing to global variable 'root' has to be preceded by
> explicitly declaring 'root' as global.  Otherwise the write only has a
> local effect.
> 
> Without this change, the '-d' cmdline flag would be broken.

Oops.  Sorry for the breakage, and thanks for fixing this up (I don't
use the -d flag, so hadn't noticed).

Alex

> 
> Commited as obvious.
> 
> contrib/ChangeLog:
> 
>   * mklog.py: In 'main()', specify variable 'root' as global.
> 
> Signed-off-by: Filip Kastl 
> ---
>  contrib/mklog.py | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/contrib/mklog.py b/contrib/mklog.py
> index 26d4156b034..b841ef0ae97 100755
> --- a/contrib/mklog.py
> +++ b/contrib/mklog.py
> @@ -389,6 +389,7 @@ def main():
>  if args.input == '-':
>  args.input = None
>  if args.directory:
> +global root
>  root = args.directory
>  
>  data = open(args.input, newline='\n') if args.input else sys.stdin
> -- 
> 2.49.0
> 


Re: [PATCH v4 2/6] dwarf: create annotation DIEs for btf tags

2025-06-30 Thread David Faust



On 6/30/25 06:11, Richard Biener wrote:
>> +static void
>> +gen_btf_decl_tag_dies (tree t, dw_die_ref target, dw_die_ref context_die)
>> +{
>> +  if (t == NULL_TREE || !DECL_P (t) || !target)
>> +return;
>> +
>> +  tree attr = lookup_attribute ("btf_decl_tag", DECL_ATTRIBUTES (t));
>> +  if (attr == NULL_TREE)
>> +return;
>> +
>> +  gen_btf_tag_dies (attr, target, context_die);
>> +
>> +  /* Strip the decl tag attribute once we have created the annotation DIEs
>> + to avoid attempting process it multiple times.  Global variable
>> + declarations may reach this function more than once.  */
>> +  DECL_ATTRIBUTES (t)
>> += remove_attribute ("btf_decl_tag", DECL_ATTRIBUTES (t));
> I do not like modifying trees as part of dwarf2out.  You should be able to
> see whether a DIE already has the respective attribute applied?

Yes, you're right. For decl_tag the case is simple and better handled by
consulting the hash table. Simple fix and this remove_attribute can be
deleted.

Understood re: modifying trees in dwarf2out. I agree it's not ideal.

For this case the remove_attribute can be deleted. For the two below,
one is already immediately restored and the other could be as well so
that there are no lasting changes in the tree at all.

I will explain the reasoning some more below.

> 
>> +}
>> +
>>  /* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging
>> entry that chains the modifiers specified by CV_QUALS in front of the
>> given type.  REVERSE is true if the type is to be interpreted in the
>> @@ -13674,6 +13894,7 @@ modified_type_die (tree type, int cv_quals, bool 
>> reverse,
>>tree item_type = NULL;
>>tree qualified_type;
>>tree name, low, high;
>> +  tree tags;
>>dw_die_ref mod_scope;
>>struct array_descr_info info;
>>/* Only these cv-qualifiers are currently handled.  */
>> @@ -13783,10 +14004,62 @@ modified_type_die (tree type, int cv_quals, bool 
>> reverse,
>>   dquals &= cv_qual_mask;
>>   if ((dquals & ~cv_quals) != TYPE_UNQUALIFIED
>>   || (cv_quals == dquals && DECL_ORIGINAL_TYPE (name) != type))
>> -   /* cv-unqualified version of named type.  Just use
>> -  the unnamed type to which it refers.  */
>> -   return modified_type_die (DECL_ORIGINAL_TYPE (name), cv_quals,
>> - reverse, context_die);
>> +   {
>> + tree dtags = lookup_attribute ("btf_type_tag",
>> +TYPE_ATTRIBUTES (dtype));
>> + if ((tags = lookup_attribute ("btf_type_tag",
>> +   TYPE_ATTRIBUTES (type)))
>> + && !attribute_list_equal (tags, dtags))
>> +   {
>> + /* Use of a typedef with additional btf_type_tags.
>> +Create a new typedef DIE to which we can attach the
>> +additional type_tag DIEs without disturbing other users 
>> of
>> +the underlying typedef.  */
>> + dw_die_ref mod_die = modified_type_die (dtype, cv_quals,
>> + reverse, 
>> context_die);
>> + mod_die = clone_die (mod_die);
>> + add_child_die (comp_unit_die (), mod_die);
>> + if (!lookup_type_die (type))
>> +   equate_type_number_to_die (type, mod_die);
>> +
>> + /* 'tags' is an accumulated list of type_tag attributes
>> +for the typedef'd type on both sides of the typedef.
>> +'dtags' is the set of type_tag attributes only appearing
>> +in the typedef itself.
>> +Find the set of type_tags only on the _use_ of the
>> +typedef, i.e. (tags - dtags).  By construction these
>> +additional type_tags have been chained onto the head of
>> +the attribute list of the original typedef.  */
>> + tree t = tags;
>> + bool altered_chain = false;
>> + while (t)
>> +   {
>> + if (TREE_CHAIN (t) == dtags)
>> +   {
>> + TREE_CHAIN (t) = NULL_TREE;
>> + altered_chain = true;
>> + break;
>> +   }
>> + t = TREE_CHAIN (t);
>> +   }
> And this might be part of that and should thus split out, or be part
> of gen_btf_type_tag_dies itself?  I expected the hashtable to
> cover the DIEs we have for existing chains of tags?
 
OK, this can move into gen_btf_type_tag_dies.

The reason the hash table doesn't help us here is that the uncertainty
is in the attribute list itself.

Specifically, if the type of a variable is a typedef with an additional
type attribute applied, then it is unclear from just the tre

[pushed: r16-1830] diagnostics: remove "json" output format

2025-06-30 Thread David Malcolm
The "json" output format for diagnostics was deprecated in GCC 15, with
advice to users seeking machine-readable diagnostics from GCC to use
SARIF instead.

This patch eliminates it from GCC 16, simplifying the diagnostics
subsystem somewhat.

Note that the Ada frontend seems to have its own implementation of this
in errout.adb (Output_JSON_Message), and documented in
gnat_ugn.texi.  This patch does not touch Ada.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r16-1830-g51ce373481e848.

gcc/ChangeLog:
* Makefile.in (OBJS-libcommon): Drop diagnostic-format-json.o.
* common.opt (fdiagnostics-format=): Drop
"json|json-stderr|json-file".
(diagnostics_output_format): Drop values "json", "json-stderr",
and "json-file".
* diagnostic-format-json.cc: Delete file.
* diagnostic-format.h
(diagnostic_output_format_init_json_stderr): Delete.
(diagnostic_output_format_init_json_file): Delete.
* diagnostic.cc (diagnostic_output_format_init): Delete cases for
DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR and
DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE.
* diagnostic.h (DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR): Delete.
(DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE): Delete.
* doc/invoke.texi: Remove references to json output format.
* doc/ux.texi: Likewise.
* selftest-run-tests.cc (selftest::run_tests): Drop call to
deleted selftest::diagnostic_format_json_cc_tests.
* selftest.h (selftest::diagnostic_format_json_cc_tests): Delete.

gcc/testsuite/ChangeLog:
* c-c++-common/analyzer/out-of-bounds-diagram-1-json.c: Deleted test.
* c-c++-common/diagnostic-format-json-1.c: Deleted test.
* c-c++-common/diagnostic-format-json-2.c: Deleted test.
* c-c++-common/diagnostic-format-json-3.c: Deleted test.
* c-c++-common/diagnostic-format-json-4.c: Deleted test.
* c-c++-common/diagnostic-format-json-5.c: Deleted test.
* c-c++-common/diagnostic-format-json-file-1.c: Deleted test.
* c-c++-common/diagnostic-format-json-stderr-1.c: Deleted test.
* c-c++-common/pr106133.c: Deleted test.
* g++.dg/pr90462.C: Deleted test.
* gcc.dg/plugin/diagnostic-test-paths-3.c: Deleted test.
* gcc.dg/plugin/plugin.exp (plugin_test_list): Remove deleted
test.
* gfortran.dg/diagnostic-format-json-1.F90: Deleted test.
* gfortran.dg/diagnostic-format-json-2.F90: Deleted test.
* gfortran.dg/diagnostic-format-json-3.F90: Deleted test.
* gfortran.dg/diagnostic-format-json-pr105916.F90: Deleted test.

Signed-off-by: David Malcolm 
---
 gcc/Makefile.in   |   1 -
 gcc/common.opt|  11 +-
 gcc/diagnostic-format-json.cc | 605 --
 gcc/diagnostic-format.h   |   8 -
 gcc/diagnostic.cc |  11 -
 gcc/diagnostic.h  |   6 -
 gcc/doc/invoke.texi   |  23 +-
 gcc/doc/ux.texi   |   2 +-
 gcc/selftest-run-tests.cc |   1 -
 gcc/selftest.h|   1 -
 .../analyzer/out-of-bounds-diagram-1-json.c   |  13 -
 .../c-c++-common/diagnostic-format-json-1.c   |  22 -
 .../c-c++-common/diagnostic-format-json-2.c   |  26 -
 .../c-c++-common/diagnostic-format-json-3.c   |  26 -
 .../c-c++-common/diagnostic-format-json-4.c   |  44 --
 .../c-c++-common/diagnostic-format-json-5.c   |  38 --
 .../diagnostic-format-json-file-1.c   |   8 -
 .../diagnostic-format-json-stderr-1.c |  24 -
 gcc/testsuite/c-c++-common/pr106133.c |   3 -
 gcc/testsuite/g++.dg/pr90462.C|  49 --
 .../gcc.dg/plugin/diagnostic-test-paths-3.c   |  75 ---
 gcc/testsuite/gcc.dg/plugin/plugin.exp|   1 -
 .../gfortran.dg/diagnostic-format-json-1.F90  |  24 -
 .../gfortran.dg/diagnostic-format-json-2.F90  |  26 -
 .../gfortran.dg/diagnostic-format-json-3.F90  |  26 -
 .../diagnostic-format-json-pr105916.F90   |  14 -
 26 files changed, 7 insertions(+), 1081 deletions(-)
 delete mode 100644 gcc/diagnostic-format-json.cc
 delete mode 100644 
gcc/testsuite/c-c++-common/analyzer/out-of-bounds-diagram-1-json.c
 delete mode 100644 gcc/testsuite/c-c++-common/diagnostic-format-json-1.c
 delete mode 100644 gcc/testsuite/c-c++-common/diagnostic-format-json-2.c
 delete mode 100644 gcc/testsuite/c-c++-common/diagnostic-format-json-3.c
 delete mode 100644 gcc/testsuite/c-c++-common/diagnostic-format-json-4.c
 delete mode 100644 gcc/testsuite/c-c++-common/diagnostic-format-json-5.c
 delete mode 100644 gcc/testsuite/c-c++-common/diagnostic-format-json-file-1.c
 delete mode 100644 gcc/testsuite/c-c++-common/diagnostic-format-json-stderr-1.c
 delete mode 100644 gcc/testsuite/c-c++-common/pr106133.c
 delete mode 100644 gcc/testsuite/g++.dg/pr90462.C

[pushed: r16-1832] diagnostics: use nullptr rather than NULL

2025-06-30 Thread David Malcolm
Modernization; no functional change intended.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r16-1832-g5bcb841f29a861.

gcc/ChangeLog:
* diagnostic-color.cc: Use nullptr rather than NULL.
* diagnostic-format-sarif.cc: Likewise.
* diagnostic-format-text.cc: Likewise.
* diagnostic-macro-unwinding.cc: Likewise.
* diagnostic-path-output.cc: Likewise.
* diagnostic-path.cc: Likewise.
* diagnostic-show-locus.cc: Likewise.
* diagnostic-spec.cc: Likewise.
* diagnostic.cc: Likewise.
* lazy-diagnostic-path.cc: Likewise.
* simple-diagnostic-path.cc: Likewise.
* tree-diagnostic-client-data-hooks.cc: Likewise.

Signed-off-by: David Malcolm 
---
 gcc/diagnostic-color.cc  | 14 +++---
 gcc/diagnostic-format-sarif.cc   | 14 +++---
 gcc/diagnostic-format-text.cc| 14 +++---
 gcc/diagnostic-macro-unwinding.cc|  6 +--
 gcc/diagnostic-path-output.cc|  8 ++--
 gcc/diagnostic-path.cc   |  6 +--
 gcc/diagnostic-show-locus.cc | 28 ++--
 gcc/diagnostic-spec.cc   |  4 +-
 gcc/diagnostic.cc| 54 
 gcc/lazy-diagnostic-path.cc  |  2 +-
 gcc/simple-diagnostic-path.cc|  2 +-
 gcc/tree-diagnostic-client-data-hooks.cc |  2 +-
 12 files changed, 77 insertions(+), 77 deletions(-)

diff --git a/gcc/diagnostic-color.cc b/gcc/diagnostic-color.cc
index b3bd6f997c6f..e95aaeb869cf 100644
--- a/gcc/diagnostic-color.cc
+++ b/gcc/diagnostic-color.cc
@@ -234,7 +234,7 @@ diagnostic_color_dict::parse_envvar_value (const char 
*const envvar_value)
   size_t name_len = 0, val_len = 0;
 
   name = q = envvar_value;
-  val = NULL;
+  val = nullptr;
   /* From now on, be well-formed or you're gone.  */
   for (;;)
 if (*q == ':' || *q == '\0')
@@ -259,7 +259,7 @@ diagnostic_color_dict::parse_envvar_value (const char 
*const envvar_value)
if (*q == '\0')
  return true;
name = ++q;
-   val = NULL;
+   val = nullptr;
   }
 else if (*q == '=')
   {
@@ -269,7 +269,7 @@ diagnostic_color_dict::parse_envvar_value (const char 
*const envvar_value)
name_len = q - name;
val = ++q; /* Can be the empty string.  */
   }
-else if (val == NULL)
+else if (val == nullptr)
   q++; /* Accumulate name.  */
 else if (*q == ';' || (*q >= '0' && *q <= '9'))
   q++; /* Accumulate val.  Protect the terminal from being sent
@@ -308,7 +308,7 @@ should_colorize (void)
 
   handle = GetStdHandle (STD_ERROR_HANDLE);
 
-  if ((handle != INVALID_HANDLE_VALUE) && (handle != NULL))
+  if ((handle != INVALID_HANDLE_VALUE) && (handle != nullptr))
 isconsole = GetConsoleMode (handle, &mode);
 
 #ifdef ENABLE_VIRTUAL_TERMINAL_PROCESSING
@@ -362,10 +362,10 @@ parse_env_vars_for_urls ()
   const char *p;
 
   p = getenv ("GCC_URLS"); /* Plural! */
-  if (p == NULL)
+  if (p == nullptr)
 p = getenv ("TERM_URLS");
 
-  if (p == NULL)
+  if (p == nullptr)
 return URL_FORMAT_DEFAULT;
 
   if (*p == '\0')
@@ -400,7 +400,7 @@ auto_enable_urls ()
   DWORD mode;
 
   handle = GetStdHandle (STD_ERROR_HANDLE);
-  if ((handle == INVALID_HANDLE_VALUE) || (handle == NULL))
+  if ((handle == INVALID_HANDLE_VALUE) || (handle == nullptr))
 return false;
 
   /* If ansi escape sequences aren't supported by the console, then URLs will
diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc
index 3fdc6134a1be..14cdbc2e0cdb 100644
--- a/gcc/diagnostic-format-sarif.cc
+++ b/gcc/diagnostic-format-sarif.cc
@@ -1722,12 +1722,12 @@ bt_callback (void *data, uintptr_t pc, const char 
*filename, int lineno,
 
   /* If we don't have any useful information, don't print
  anything.  */
-  if (filename == NULL && function == NULL)
+  if (filename == nullptr && function == nullptr)
 return 0;
 
   /* Skip functions in diagnostic.cc or diagnostic-global-context.cc.  */
   if (closure->m_frames_arr->size () == 0
-  && filename != NULL
+  && filename != nullptr
   && (strcmp (lbasename (filename), "diagnostic.cc") == 0
  || strcmp (lbasename (filename),
 "diagnostic-global-context.cc") == 0))
@@ -1741,13 +1741,13 @@ bt_callback (void *data, uintptr_t pc, const char 
*filename, int lineno,
   return 1;
 }
 
-  char *alc = NULL;
-  if (function != NULL)
+  char *alc = nullptr;
+  if (function != nullptr)
 {
   char *str = cplus_demangle_v3 (function,
 (DMGL_VERBOSE | DMGL_ANSI
  | DMGL_GNU_V3 | DMGL_PARAMS));
-  if (str != NULL)
+  if (str != nullptr)
{
  alc = str;
  function = str;
@@ -1759,7 +1759,7 @@ bt_callback (void *data, uintptr_t pc, const char 
*filename, int lineno,
  if (strncmp (function, bt_stop[i], len) == 0
 

[pushed: r16-1831] diagnostics: convert diagnostic_event::meaning enums to enum class

2025-06-30 Thread David Malcolm
Modernization; no functional change intended.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r16-1831-g8ac43bfa380b5c.

gcc/analyzer/ChangeLog:
* checker-event.cc (function_entry_event::get_meaning): Convert
diagnostic_event::meaning enums to enum class.
(cfg_edge_event::get_meaning): Likewise.
(call_event::get_meaning): Likewise.
(return_event::get_meaning): Likewise.
(start_consolidated_cfg_edges_event::get_meaning): Likewise.
(inlined_call_event::get_meaning): Likewise.
(warning_event::get_meaning): Likewise.
* sm-fd.cc (fd_diagnostic::get_meaning_for_state_change):
Likewise.
* sm-file.cc (file_diagnostic::get_meaning_for_state_change):
Likewise.
* sm-malloc.cc (malloc_diagnostic::get_meaning_for_state_change):
Likewise.
* sm-sensitive.cc
(exposure_through_output_file::get_meaning_for_state_change):
Likewise.
* sm-taint.cc (taint_diagnostic::get_meaning_for_state_change):
Likewise.
* varargs.cc
(va_list_sm_diagnostic::get_meaning_for_state_change): Likewise.

gcc/ChangeLog:
* diagnostic-format-sarif.cc
(sarif_builder::maybe_make_kinds_array): Convert
diagnostic_event::meaning enums to enum class.
* diagnostic-path-output.cc (path_label::get_text): Likewise.
* diagnostic-path.cc
(diagnostic_event::meaning::maybe_get_verb_str): Likewise.
(diagnostic_event::meaning::maybe_get_noun_str): Likewise.
(diagnostic_event::meaning::maybe_get_property_str): Likewise.
* diagnostic-path.h (diagnostic_event::verb): Likewise.
(diagnostic_event::noun): Likewise.
(diagnostic_event::property): Likewise.
(diagnostic_event::meaning): Likewise.

gcc/testsuite/ChangeLog:
* gcc.dg/plugin/analyzer_gil_plugin.cc
(gil_diagnostic::get_meaning_for_state_change): Convert
diagnostic_event::meaning enums to enum class.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/checker-event.cc | 18 +++---
 gcc/analyzer/sm-fd.cc |  8 +--
 gcc/analyzer/sm-file.cc   |  8 +--
 gcc/analyzer/sm-malloc.cc |  8 +--
 gcc/analyzer/sm-sensitive.cc  |  4 +-
 gcc/analyzer/sm-taint.cc  |  4 +-
 gcc/analyzer/varargs.cc   |  8 +--
 gcc/diagnostic-format-sarif.cc|  6 +-
 gcc/diagnostic-path-output.cc |  2 +-
 gcc/diagnostic-path.cc| 44 ++---
 gcc/diagnostic-path.h | 62 +--
 .../gcc.dg/plugin/analyzer_gil_plugin.cc  |  8 +--
 12 files changed, 90 insertions(+), 90 deletions(-)

diff --git a/gcc/analyzer/checker-event.cc b/gcc/analyzer/checker-event.cc
index 04b66bf85d63..767e962589e0 100644
--- a/gcc/analyzer/checker-event.cc
+++ b/gcc/analyzer/checker-event.cc
@@ -398,7 +398,7 @@ function_entry_event::print_desc (pretty_printer &pp) const
 diagnostic_event::meaning
 function_entry_event::get_meaning () const
 {
-  return meaning (VERB_enter, NOUN_function);
+  return meaning (verb::enter, noun::function);
 }
 
 /* class state_change_event : public checker_event.  */
@@ -632,9 +632,9 @@ cfg_edge_event::get_meaning () const
 {
   const cfg_superedge& cfg_sedge = get_cfg_superedge ();
   if (cfg_sedge.true_value_p ())
-return meaning (VERB_branch, PROPERTY_true);
+return meaning (verb::branch, property::true_);
   else if (cfg_sedge.false_value_p ())
-return meaning (VERB_branch, PROPERTY_false);
+return meaning (verb::branch, property::false_);
   else
 return meaning ();
 }
@@ -880,7 +880,7 @@ call_event::print_desc (pretty_printer &pp) const
 diagnostic_event::meaning
 call_event::get_meaning () const
 {
-  return meaning (VERB_call, NOUN_function);
+  return meaning (verb::call, noun::function);
 }
 
 /* Override of checker_event::is_call_p for calls.  */
@@ -964,7 +964,7 @@ return_event::print_desc (pretty_printer &pp) const
 diagnostic_event::meaning
 return_event::get_meaning () const
 {
-  return meaning (VERB_return, NOUN_function);
+  return meaning (verb::return_, noun::function);
 }
 
 /* Override of checker_event::is_return_p for returns.  */
@@ -991,8 +991,8 @@ start_consolidated_cfg_edges_event::print_desc 
(pretty_printer &pp) const
 diagnostic_event::meaning
 start_consolidated_cfg_edges_event::get_meaning () const
 {
-  return meaning (VERB_branch,
- (m_edge_sense ? PROPERTY_true : PROPERTY_false));
+  return meaning (verb::branch,
+ (m_edge_sense ? property::true_ : property::false_));
 }
 
 /* class inlined_call_event : public checker_event.  */
@@ -1012,7 +1012,7 @@ inlined_call_event::print_desc (pretty_printer &pp) const
 diagnostic_event::meaning
 inlined_call_event::get_meaning () const
 {
-  return meaning (VERB_call, NOUN_functio

Re: [PATCH v6 1/3][Middle-end] Provide more contexts for -Warray-bounds, -Wstringop-*warning messages due to code movements from compiler transformation (Part 1) [PR109071,PR85788,PR88771,PR106762,PR1

2025-06-30 Thread Qing Zhao


> On Jun 30, 2025, at 07:27, Richard Biener  wrote:
> 
> On Tue, Jun 10, 2025 at 5:28 PM Qing Zhao  wrote:
>> 
>> 
>> 
>>> On Jun 10, 2025, at 09:37, Richard Biener  
>>> wrote:
>>> 
>>> On Mon, Jun 9, 2025 at 8:06 PM Qing Zhao  wrote:
 
 
 
> On Jun 6, 2025, at 03:31, Richard Biener  
> wrote:
> 
> On Fri, May 30, 2025 at 5:13 PM Qing Zhao  wrote:
>> 
>> Hi, Richard,
>> 
>> Really appreciate for your suggestions.
>> 
>>> On May 30, 2025, at 05:22, Richard Biener  
>>> wrote:
>>> 
>>> On Fri, May 23, 2025 at 10:49 PM Qing Zhao  wrote:
 
 Hi, Richard,
 
 Thanks a lot for your comments and questions.
 Please see my answers embedded below:
 
> On May 19, 2025, at 06:44, Richard Biener 
>  wrote:
> 
> On Fri, May 16, 2025 at 3:34 PM Qing Zhao  
> wrote:
>> 
>> Control this with a new option -fdiagnostics-details.
>> 
>> $ cat t.c
>> extern void warn(void);
>> static inline void assign(int val, int *regs, int *index)
>> {
>> if (*index >= 4)
>> warn();
>> *regs = val;
>> }
>> struct nums {int vals[4];};
>> 
>> void sparx5_set (int *ptr, struct nums *sg, int index)
>> {
>> int *val = &sg->vals[index];
>> 
>> assign(0,ptr, &index);
>> assign(*val, ptr, &index);
>> }
>> 
>> $ gcc -Wall -O2  -c -o t.o t.c
>> t.c: In function ‘sparx5_set’:
>> t.c:12:23: warning: array subscript 4 is above array bounds of 
>> ‘int[4]’ [-Warray-bounds=]
>> 12 |   int *val = &sg->vals[index];
>>  |   ^~~
>> t.c:8:18: note: while referencing ‘vals’
>> 8 | struct nums {int vals[4];};
>>  |  ^~~~
>> 
>> In the above, Although the warning is correct in theory, the warning 
>> message
>> itself is confusing to the end-user since there is information that 
>> cannot
>> be connected to the source code directly.
>> 
>> It will be a nice improvement to add more information in the warning 
>> message
>> to report where such index value come from.
>> 
>> In order to achieve this, we add a new data structure "move_history" 
>> to record
>> 1. the "condition" that triggers the code movement;
>> 2. whether the code movement is on the true path of the "condition";
>> 3. the "compiler transformation" that triggers the code movement.
>> 
>> Whenever there is a code movement along control flow graph due to 
>> some
>> specific transformations, such as jump threading, path isolation, 
>> tree
>> sinking, etc., a move_history structure is created and attached to 
>> the
>> moved gimple statement.
>> 
>> During array out-of-bound checking or -Wstringop-* warning checking, 
>> the
>> "move_history" that was attached to the gimple statement is used to 
>> form
>> a sequence of diagnostic events that are added to the corresponding 
>> rich
>> location to be used to report the warning message.
>> 
>> This behavior is controled by the new option -fdiagnostics-details
>> which is off by default.
>> 
>> With this change, by adding -fdiagnostics-details,
>> the warning message for the above testing case is now:
>> 
>> $ gcc -Wall -O2 -fdiagnostics-details -c -o t.o t.c
>> t.c: In function ‘sparx5_set’:
>> t.c:12:23: warning: array subscript 4 is above array bounds of 
>> ‘int[4]’ [-Warray-bounds=]
>> 12 |   int *val = &sg->vals[index];
>>  |   ^~~
>> ‘sparx5_set’: events 1-2
>> 4 |   if (*index >= 4)
>>  |  ^
>>  |  |
>>  |  (1) when the condition is evaluated to true
>> ..
>> 12 |   int *val = &sg->vals[index];
>>  |   ~~~
>>  |   |
>>  |   (2) out of array bounds here
>> t.c:8:18: note: while referencing ‘vals’
>> 8 | struct nums {int vals[4];};
>>  |  ^~~~
>> 
>> The change was divided into 3 parts:
>> 
>> Part 1: Add new data structure move_history, record move_history 
>> during
>>transformation;
>> Part 2: In warning analysis, Use the new move_history to form a rich
>>location with a sequence of events, to report more context info
>>of the warnings.
>> Part 3: Add debugging mechanism for move_history.
> 
> Thanks for working on this.  I'm pasting my 

Re: [PATCH v6 1/3][Middle-end] Provide more contexts for -Warray-bounds, -Wstringop-*warning messages due to code movements from compiler transformation (Part 1) [PR109071,PR85788,PR88771,PR106762,PR1

2025-06-30 Thread Qing Zhao


> On Jun 30, 2025, at 07:33, Richard Biener  wrote:
> 
> On Fri, Jun 27, 2025 at 3:39 PM Qing Zhao  wrote:
>> 
>> Hi,
>> 
>> A status update on this patch:  (Actually a good news!)
>> 
>>> On Jun 10, 2025, at 11:32, Qing Zhao  wrote:
>>> 
>>> 
>>> 
>> 
> 
> It's difficult to do any meaningful pruning I think.  Consider
> 
> if (i == -1)
>  tem = a[i];
> 
> when we transform this to
> 
> if (i == -1)
> tem = a[-1];
> 
> and report the out-of-bounds access then we've lost the fact
> that -1 was originally 'i' and there's an interesting condition on that
> variable.  So unless we preserve some kind of optimization history
> on a stmt like the above we are lost.  The same is true for
> "altered" control edges where the most interesting are again those
> that are elided by optimization (the implied true/false conditions).
> 
> That said, I would expect the user to not use -fdiagnostics-show-context 
> by
> default but instead when being puzzled about a diagnostic, turn it on
> on-demand.  So it's probably useful to report all of the chain or maybe
> have -fdiagnostic-show-context=N with N limiting the depth (or a separate
> knob for this).
> 
> When there's still 'i' in a[i] but we figured out a range then we can see
> to do 1. to gather conditions that we consider.  The backwards threader
> has "interestingness" heuristics that could eventually be repurposed.
> The "good" thing is that once we decide to emit a diagnostic it's fair
> to spend quite some cycles on improving it.
 
 So as a summary I'd say we'd want to have -fdiagnostic-show-context
 (=1 for now) and simply display the immediate control condition for
 the select diagnostics your patch series handled and start from there,
 adding test coverage where that's useful (like for my simple a[i] example
 above) and see in what cases that's lacking.
>>> 
>>> Thanks for the summary, I agree.
>>> 
>>> The following is my plan:
>>> 
>>> 1. The first working version of -fdiagnostic-show-context=N should cover 
>>> all the current
>>> known testing cases: all the PRs and your testing case and Kees’s new 
>>> testing case.
>> 
>> I tried the following very simple heuristic to form the diagnostic path in 
>> my current working-in-progress patch:
>> 
>>  /* Starting from cur_bb, backtrace the CFG through the single predecessor
>>to form the path. For example:
>> B2
>>/  \
>>   V\
>>  B3 \
>>  / \ \
>> V   \>V
>> B4B7
>> 
>>In the above CFG, if the STMT is in B4, we backtrace to its single
>>predecessor B3 first, and then back to B3's single predecessor B2,
>>till there is no single predecessor anymore, or the # of backtrace
>>depth exceeds the value of flag_diagnostics_show_context.
> 
> Good.  Then we are sure we stop at a dominator of B4.
> 
>>For each single predecessor block, locate the conditional statement
>>in the end of the block. determine whether the STMT is on the taken
>>path of the condition. Add these two information to each event of
>>the path.  */
>> 
>> 
>> The good news is:  With the above simple heuristic and a simple back tracing 
>> of  the CFG, all the
>> current testing cases for the following PRs passed without any issue:
>> 
>> PR109071
>> PR88771
>> PR85788
>> PR108770
>> PR106762
>> PR115274
>> PR117179
> 
> Nice.  An incremental improvement would be to instead of handling
> single predecessors, skip to the immediate dominator - this way
> uninteresting intermediate CFG is skipped.  This might be confusing
> and the next "step" could be very far away, not sure how to best
> handle this.  But it would handle intermediate conditional code, like
> 
>  if (i < 10)
>{
>   if (dollar)
> printf ("dollar");
>   else
> printf ("euro");
>   printf ("%d", amout[i]);
>}
> 
> where you'd not able to go up to if (i < 10).

Yes, immediate dominator should work for such cases. 
>  Maybe a simple heuristic
> on number of line to not skip too far works, or simply ignore this
> for now, or simply only use immediate dominators for the first
> condition to be printed?

I will experiment a little bit on this.  Do you have any more complicate 
testing cases? That will be very helpful.

Thanks a lot for all the help.

Qing
> 
> Thanks,
> Richard.
> 
>> I will continue working on this to add more testing cases and also more 
>> warnings per the following discussion:
>> https://gcc.gnu.org/pipermail/gcc-patches/2025-May/684126.html
>> https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686323.html
>> https://gcc.gnu.org/pipermail/gcc-patches/2025-June/685852.html
>> https://gcc.gnu.org/pipermail/gcc-patches/2025-June/685854.html
>> 
>> Let me know if you have any comments or suggestions.
>> 
>> Thanks a lot for all the help.
>> 
>> Qing
>>> 
>>> 2. Then we can improve it later if new unc

Re: [PATCH 1/2] allow contraction to synthetic single-element vector FMA

2025-06-30 Thread Alexander Monakov


On Mon, 30 Jun 2025, Richard Biener wrote:

> > * gcc.target/i386/pr116979.c
> >
> > Here we check that FMA is used for complex multiplication. This is a case
> > where use of FMA is detrimental for accuracy, but I guess we can choose
> > to preserve the status quo. I can look into teaching
> > expand_complex_multiplication to emit FMAs.
> 
> Yeah, I guess that's within -ffp-contract=on constraints.  When you say it's
> detrimental for accuracy, is that a general statement for complex multiply
> lowering?  If so we possibly do not want FMAs?

We may want FMAs when completely disregarding accuracy for speed (-ffast-math),
but otherwise, yes, I meant that in general our strategy is not good. We are
lowering complex multiplication by components

  (x + yi)*(z + wi) = (x*z - y*w) + (x*w + y*z)i

and when FMA is available, we end up with something like

  fma(x, z, -y*w)

for the real part and likewise fma(x, w, y*z) for the imaginary part, which is
asymmetrical with respect to operands, and, for instance, yields wrong results
for conjugate vectors: take z=x and w=-y, then imaginary part fma(x, w, y*z) is
fma(x, -y, y*x), which is negated round-off tail of y*x, but should be zero.

FMA is useful for improving accuracy of sum/difference of two products, where
you'd compute x*w + y*z as

  xw = x*w
  xw_tail = fma(x, w, -xw)
  tmp = fma(y, z, xw)
  return tmp + xw_tail

but apart from this, I'd say we don't want to emit FMAs in
expand_complex_multiplication. LLVM seems to produce FMAs for complex product
only under -ffp-contract=fast.

What are the next steps here, then?

Thank you.
Alexander


Re: [PATCH] c++, v2: Fix up cp_build_array_ref COND_EXPR handling [PR120471]

2025-06-30 Thread Jakub Jelinek
On Mon, Jun 30, 2025 at 05:14:06PM +0200, Jakub Jelinek wrote:
> 1) for idx being INTEGER_CST (case for which I believe the change has been
>added) it keeps doing what it did
> 2) if both op1 and op2 are arrays with invariant address or pointers to
>something with invariant address, it uses
>SAVE_EXPR , SAVE_EXPR  SAVE_EXPR 
>as COND_EXPR condition and otherwise what it did
> 3) otherwise punt
> 
> Now, perhaps a predicate (but how to call it) whether idx doesn't
> contain any SAVE_EXPRs/TARGET_EXPRs/BIND_EXPRs and isn't really large
> expression (but how to measure it; perhaps also no CALL_EXPRs, and the
> question if it should allow say multiplication/division/modulo, those might
> need larger code as well) could be used instead of the INTEGER_CST check,
> either immediately or incrementally.
> But guess I should first try to reproduce the ICE you've mentioned.

So, the thing with the ICE is that the parsing gives us a COND_EXPR
of ARRAY_TYPE with ARRAY_TYPE operands.  So, when we punt (either always
by removing the COND_EXPR cp_build_array_ref optimization altogether or
conditionally), we risk the bogus COND_EXPR with ARRAY_TYPE remains in the
IL.
Now, with the v2 patch I've posted, neither
extern int a1[];
extern int a2[];
void foo(int p)
{
  int x = (p ? a1 : a2)[1];
}
nor
void bar(int p, int q)
{
  int x = (p ? a1 : a2)[q];
}
actually ICE, because in the first case idx is INTEGER_CST and in the
second case a1 and a2 are invariant address arrays.
But e.g.
extern int a1[], a2[], a3[], a4[];

int
foo (int p)
{
  return (p ? a1 : a2)[1];
}

int
bar (int p, int q)
{
  return (p ? a1 : a2)[q];
}

int
baz (int p, int q)
{
  return (p ? q ? a1 : a2 : q ? a3 : a4)[1];
}

int
qux (int p, int q, int r)
{
  return (p ? q ? a1 : a2 : q ? a3 : a4)[r];
}

already ICEs with my patch in baz and qux, because the gimplifier can't
handle ARRAY_TYPE COND_EXPRs with unknown bounds for obvious reasons.

So, what about the following patch then (or its variant with some
predicate of not large expression without
SAVE_EXPR/TARGET_EXPR/BIND_EXPR/CALL_EXPR/STATEMENT_EXPR/LABEL_EXPR))?

2025-06-30  Jakub Jelinek  

PR c++/120471
* typeck.cc (cp_build_array_ref) : If idx is not
INTEGER_CST, don't optimize the case (but cp_default_conversion on
array early if it has ARRAY_TYPE) or use
SAVE_EXPR , SAVE_EXPR , SAVE_EXPR  as new op0 depending
on flag_strong_eval_order and whether op1 and op2 are arrays with
invariant address or tree invariant pointers.  Formatting fixes.

* g++.dg/ubsan/pr120471.C: New test.
* g++.dg/parse/pr120471.C: New test.

--- gcc/cp/typeck.cc.jj 2025-06-30 12:19:16.398242029 +0200
+++ gcc/cp/typeck.cc2025-06-30 18:59:51.289774002 +0200
@@ -4001,13 +4001,91 @@ cp_build_array_ref (location_t loc, tree
   }
 
 case COND_EXPR:
-  ret = build_conditional_expr
-  (loc, TREE_OPERAND (array, 0),
-  cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
-  complain),
-  cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx,
-  complain),
-  complain);
+  tree op0, op1, op2;
+  op0 = TREE_OPERAND (array, 0);
+  op1 = TREE_OPERAND (array, 1);
+  op2 = TREE_OPERAND (array, 1);
+  if (TREE_CODE (idx) != INTEGER_CST)
+   {
+ /* If idx could possibly have some SAVE_EXPRs, turning
+(op0 ? op1 : op2)[idx] into
+op0 ? op1[idx] : op2[idx] can lead into temporaries
+initialized in one conditional path and uninitialized
+uses of them in the other path.
+And if idx is a really large expression, evaluating it
+twice is also not optimal.
+On the other side, op0 must be sequenced before evaluation
+of op1 and op2 and for C++17 op0, op1 and op2 must be
+sequenced before idx.
+If idx is INTEGER_CST, we can just do the optimization
+without any SAVE_EXPRs, if op1 and op2 are both ARRAY_TYPE
+VAR_DECLs or COMPONENT_REFs thereof (so their address
+is constant or relative to frame), optimize into
+(SAVE_EXPR , SAVE_EXPR , SAVE_EXPR )
+? op1[SAVE_EXPR ] : op2[SAVE_EXPR ]
+Otherwise avoid this optimization.  */
+ if (flag_strong_eval_order == 2)
+   {
+ if (TREE_CODE (TREE_TYPE (op1)) == ARRAY_TYPE)
+   {
+ tree xop1 = op1;
+ while (TREE_CODE (xop1) == COMPONENT_REF)
+   xop1 = TREE_OPERAND (xop1, 0);
+ STRIP_ANY_LOCATION_WRAPPER (xop1);
+ if (!decl_address_invariant_p (xop1))
+   {
+ /* Force default conversion on array if
+we can't optimize this and array has ARRAY_TYPE
+COND_EXPR, we can't leave COND_EXPRs wi

[COMMITTED 18/40] ada: Fix fallout of latest change to aggregate expansion

2025-06-30 Thread Marc Poulhiès
From: Eric Botcazou 

It exposed a small loophole in the Backend_Processing_Possible predicate.

gcc/ada/ChangeLog:

* exp_aggr.adb (Backend_Processing_Possible.Component_Check): Return
False for delayed conditional expressions.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_aggr.adb | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 48478f350bb..a25d28d2edd 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -865,7 +865,9 @@ package body Exp_Aggr is
 
 --  Checks 8: (no delayed components)
 
-if Is_Delayed_Aggregate (Expr) then
+if Is_Delayed_Aggregate (Expr)
+  or else Is_Delayed_Conditional_Expression (Expr)
+then
return False;
 end if;
 
-- 
2.43.0



[COMMITTED 04/40] ada: Fix Itype-related predicate check omissions.

2025-06-30 Thread Marc Poulhiès
From: Steve Baird 

Clean up problematic interactions between Itype subtypes and predicates,
which were causing required predicate checks to be (incorrectly) omitted.

gcc/ada/ChangeLog:

* einfo-utils.adb (Predicate_Function): Improve handling of a case
where a predicate specified for a subtype of a partial view of a
type was incorrectly ignored.
(Set_Predicate_Function): If the attribute has already been set to
the same value, then do nothing (instead of raising P_E).
* sem_ch13.adb (Build_Predicate_Function): Add new function
Has_Source_Predicate. If a subtype inherits a predicate but also
has its own explicitly specified predicate, then avoid
misinterpreting the presence of the function built for the
inherited predicate to mean that no additional predicate function
is needed.
* sem_util.adb (Build_Subtype): In the case where we are given a
constrained record or array subtype and we need to construct a
different subtype, subject to a different constraint, the
subtype_mark of the constructed subtype needs to reference an
unconstrained subtype (because a new constraint is going to be
imposed). If the Predicated_Parent attribute of the given subtype
is present and refers to a suitable unconstrained subtype, then
use that subtype instead of setting the Predicated_Parent
attribute on a new node (and performing the associated attribute
copying).

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/einfo-utils.adb | 40 +++--
 gcc/ada/sem_ch13.adb| 56 +
 gcc/ada/sem_util.adb| 25 +-
 3 files changed, 118 insertions(+), 3 deletions(-)

diff --git a/gcc/ada/einfo-utils.adb b/gcc/ada/einfo-utils.adb
index 91d273cb32d..60ee509da67 100644
--- a/gcc/ada/einfo-utils.adb
+++ b/gcc/ada/einfo-utils.adb
@@ -2376,6 +2376,37 @@ package body Einfo.Utils is
 if Ekind (Subp_Id) = E_Function
   and then Is_Predicate_Function (Subp_Id)
 then
+   --  We may have incorrectly looked through predicate-bearing
+   --  subtypes when going from a private subtype to its full
+   --  view, so compensate for that case. Unfortunately,
+   --  Subp_Id might not be analyzed at this point, so we
+   --  use a crude works-most-of-the-time text-based
+   --  test to detect the case where Id is a subtype (declared by
+   --  a subtype declaration) and no predicate was explicitly
+   --  specified for Id. Ugh. ???
+
+   if Nkind (Parent (Id)) = N_Subtype_Declaration
+ -- 1st choice ...
+ --   and then Etype (First_Entity (Subp_Id)) /= Id
+ -- but that doesn't work if Subp_Id is not analyzed.
+
+ --  so we settle for 2nd choice, ignoring cases like
+ --  "subtype Foo is Pkg.Foo;" where distinct subtypes
+ --  have the same identifier:
+ --
+ and then Get_Name_String (Chars (Subp_Id)) /=
+  Get_Name_String (Chars (Id)) & "Predicate"
+   then
+  declare
+ Mark : Node_Id := Subtype_Indication (Parent (Id));
+  begin
+ if Nkind (Mark) = N_Subtype_Indication then
+Mark := Subtype_Mark (Mark);
+ end if;
+ return Predicate_Function (Entity (Mark));
+  end;
+   end if;
+
return Subp_Id;
 end if;
 
@@ -2803,7 +2834,6 @@ package body Einfo.Utils is
   end if;
 
   Subp_Elmt := First_Elmt (Subps);
-  Prepend_Elmt (V, Subps);
 
   --  Check for a duplicate predication function
 
@@ -2813,11 +2843,17 @@ package body Einfo.Utils is
  if Ekind (Subp_Id) = E_Function
and then Is_Predicate_Function (Subp_Id)
  then
-raise Program_Error;
+if V = Subp_Id then
+   return;
+else
+   raise Program_Error;
+end if;
  end if;
 
  Next_Elmt (Subp_Elmt);
   end loop;
+
+  Prepend_Elmt (V, Subps);
end Set_Predicate_Function;
 
-
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 22575f9cbf5..dcca3fc57aa 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -9986,6 +9986,12 @@ package body Sem_Ch13 is
   --  Includes a call to the predicate function for type T in Expr if
   --  Predicate_Function (T) is non-empty.
 
+  function Has_Source_Predicate (T : Entity_Id) return Boolean;
+  --  Return True if one of the 3 predicate aspects is specified
+  --  explicitly (either via a pragma or an aspect specification, but
+

Re: [PATCH] c-family: Check backend for argument alignment on stack

2025-06-30 Thread Jason Merrill

On 6/28/25 7:00 AM, H.J. Lu wrote:

Since a backend may ignore user type alignment for arguments passed on
stack, check backend for argument alignment on stack when evaluating
__alignof.


I assume that's reflected in DECL_ALIGN, so could we just add PARM_DECL to


  else if (VAR_OR_FUNCTION_DECL_P (expr))
t = size_int (DECL_ALIGN_UNIT (expr));


?

Jason



Re: AFDO/FDO profile comparator

2025-06-30 Thread Jan Hubicka
> Hi Honza,
> 
> On Sun, Jun 29, 2025 at 10:45 PM Jan Hubicka  wrote:
> >
> > >
> > >
> > > > On 24 Jun 2025, at 7:43 pm, Jan Hubicka  wrote:
> > > >
> > > > External email: Use caution opening links or attachments
> > > >
> > > >
> > > > Hi,
> > > > this pass removes early-inlining from afdo pass since all inlining
> > > > should now happen from early inliner.  I tedted this on spec and there
> > > > are 3 inlines happening here which are blocked at early-inline time by
> > > > hitting large function growth limit.  We probably want to bypass that
> > > > limit, I will look into that incrementaly.
> > >
> > > Thanks for doing this. Is the inlining difference here is due to 
> > > annotation that happens in auto-profile pass in the earlier 
> > > implementation?
> > >
> > > One unrelated question about scaling profiles. We seem to scale-up AFDO  
> > > with and_count_scale and scale down local_profile in some other cases. 
> > > Should we instead scale up AFDO profile to local_profile scale. Lot of 
> > > the inlining and other parameters seem to work well with that.
> >
> > Hi,
> > I implemented simple afdo/fdo profile comparator.  I think we will need to 
> > figure out
> > what to print and what to look for.  It currently records the afdo, fdo 
> > count pairs
> > and then try to scale afdo counts to fdo counts printng differences.
> 
> I tried your patch on the current master and when I try running as you
> mentioned, it looks like PGO counters are not read. I am seeing
> something like (fdo is always zero):
> 
> update_stmt.part.0/2212 bb 0 (cold) afdo 3400152 (guessed) scaled 0
> (guessed) fdo 0 (precise) diff 0, +0.00%
> update_stmt.part.0/2212 bb 4 (cold) afdo 3400152 (auto FDO) scaled 0
> (guessed) fdo 0 (precise) diff 0, +0.00%
> 
> Also, the patch didn't apply cleanly to the current master. Is the
> patch complete?

Hello,
the patch I sent from airport only worked if you produced the gcda files with
unpatched compiler (which I did not notice since I was reusing thse). 
For some reason auto-profile reading is interwinded into
gcov reading which is not necessary.  Here is a cleaner version which also
makes the format bit more convenient.  One can now grep as:

grep "bb.*fdo.*very hot.*cold" *.profile | sort -n -k 5 -r | less

digits_2/30 bb 307 fdo 10273284651 (very hot) afdo 0 (auto FDO) (cold)  scaled 
0 diff -10273284651, -100.00%
digits_2/30 bb 201 fdo 2295561442 (very hot) afdo 19074 (auto FDO) (cold)  
scaled 1341585 diff -2294219857, -99.94%
digits_2/30 bb 203 fdo 1236123372 (very hot) afdo 9537 (auto FDO) (cold)  
scaled 670792 diff -1235452580, -99.95%
digits_2/30 bb 200 fdo 1236123372 (very hot) afdo 9537 (auto FDO) (cold)  
scaled 670792 diff -1235452580, -99.95%
digits_2/30 bb 202 fdo 1059438070 (very hot) afdo 9537 (auto FDO) (cold)  
scaled 670792 diff -1058767278, -99.94%
new_solver/9 bb 246 fdo 413879041 (very hot) afdo 76594 (guessed) (cold)  
scaled 5387299 diff -408491742, -98.70%
new_solver/9 bb 167 fdo 413792205 (very hot) afdo 76594 (guessed) (cold)  
scaled 5387299 diff -408404906, -98.70%
new_solver/9 bb 159 fdo 387809230 (very hot) afdo 57182 (guessed) (cold)  
scaled 4021940 diff -383787290, -98.96%
new_solver/9 bb 158 fdo 387809230 (very hot) afdo 60510 (guessed) (cold)  
scaled 4256018 diff -383553212, -98.90%
new_solver/9 bb 138 fdo 387809230 (very hot) afdo 40917 (guessed) (cold)  
scaled 2877929 diff -384931301, -99.26%
new_solver/9 bb 137 fdo 387809230 (very hot) afdo 43298 (guessed) (cold)  
scaled 3045398 diff -384763832, -99.21%

This dumps basic blocks that do have large counts by normal profile feedbakc
but autofdo gives them small count (so they get cold).  These seems to be
indeed mostly basic blocks controlling loops.

I plan push the patch after bit more testing tonight.

gcc/ChangeLog:

* auto-profile.cc (afdo_hot_bb_threshod): New global
variable.
(maybe_hot_afdo_count_p): New function.
(autofdo_source_profile::read): Do not set up dump file;
set afdo_hot_bb_threshod.
(afdo_annotate_cfg): Handle partial training.
(afdo_callsite_hot_enough_for_early_inline):
Use maybe_hot_afdo_count_p.
(auto_profile_offline::execute): Read autofdo file.
* auto-profile.h (maybe_hot_afdo_count_p): Declare.
(afdo_hot_bb_threshold): Declare.
* coverage.cc (read_counts_file): Also set gcov_profile_info.
(coverage_init): Do not read autofdo file.
* opts.cc (enable_fdo_optimizations): Add autofdo parameter;
do not set flag_branch_probabilities and flag_profile_values
with it.
(common_handle_option): Update.
* passes.cc (finish_optimization_passes): Do not end branch
prob here.
(pass_manager::dump_profile_report): Also mark change after
autofdo pass.
* profile.cc: Include auto-profile.h
(gcov_profile_info): New global variable.
(struct afdo_fdo_record): New struture.
(compute_branch_pr

[COMMITTED 38/40] ada: Make class-wide Max_Size_In_Storage_Elements return a large value

2025-06-30 Thread Marc Poulhiès
From: Bob Duff 

Max_Size_In_Storage_Elements is supposed to return a value greater or
equal to what is passed for any heap allocation for an object of the
type. For a tagged type T, we don't know the allocation size for
descendants; therefore T'Class'Max_Size_In_Storage_Elements should
return a huge number. In particular, it now returns Storage_Count'Last,
which is greater than any possible heap allocation.

Previously, T'Class'Max_Size_In_Storage_Elements was returning
the same value as T'Max_Size_In_Storage_Elements, which was
wrong.

gcc/ada/ChangeLog:

* exp_attr.adb (Attribute_Max_Size_In_Storage_Elements):
Return Storage_Count'Last converted to universal_integer.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_attr.adb | 34 +++---
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 3d1bff93b40..0f09ba587ac 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -5353,22 +5353,42 @@ package body Exp_Attr is
  Typ : constant Entity_Id := Etype (N);
 
   begin
- --  If the prefix is X'Class, we transform it into a direct reference
- --  to the class-wide type, because the back end must not see a 'Class
- --  reference. See also 'Size.
+ --  Tranform T'Class'Max_Size_In_Storage_Elements (for any T) into
+ --  Storage_Count'Pos (Storage_Count'Last), because it must include
+ --  all descendants, which can be arbitrarily large. Note that the
+ --  back end must not see any 'Class attribute references.
+ --  The 'Pos is to make it be of type universal_integer.
+ --
+ --  ???If T'Class'Size is specified, it should probably affect
+ --  T'Class'Max_Size_In_Storage_Elements accordingly.
 
  if Is_Entity_Name (Pref)
and then Is_Class_Wide_Type (Entity (Pref))
  then
-Rewrite (Prefix (N), New_Occurrence_Of (Entity (Pref), Loc));
-return;
- end if;
+declare
+   Storage_Count_Type : constant Entity_Id :=
+ RTE (RE_Storage_Count);
+   Attr : constant Node_Id :=
+ Make_Attribute_Reference (Loc,
+   Prefix => New_Occurrence_Of (Storage_Count_Type, Loc),
+   Attribute_Name => Name_Pos,
+   Expressions => New_List (
+ Make_Attribute_Reference (Loc,
+   Prefix => New_Occurrence_Of (Storage_Count_Type, Loc),
+   Attribute_Name => Name_Last)));
+begin
+   Rewrite (N, Attr);
+   Analyze_And_Resolve (N, Typ);
+   return;
+end;
 
  --  Heap-allocated controlled objects contain two extra pointers which
  --  are not part of the actual type. Transform the attribute reference
  --  into a runtime expression to add the size of the hidden header.
 
- if Needs_Finalization (Ptyp) and then not Header_Size_Added (N) then
+ elsif Needs_Finalization (Ptyp)
+   and then not Header_Size_Added (N)
+ then
 Set_Header_Size_Added (N);
 
 --  Generate:
-- 
2.43.0



[COMMITTED 25/40] ada: Filling in gaps in handling of inherited Pre/Post'Class aspects

2025-06-30 Thread Marc Poulhiès
From: Gary Dismukes 

The initial set of changes for doing proper mapping of calls to primitive
functions in Pre/Post'Class aspects inherited by derived types was not
handling some cases (such as when formals are referenced as part of
dereferences, certain aspects such as 'Old and 'Access, and conditional
and declare expressions), and mishandling other cases (such as nested
function calls).

This set of changes attempts to properly address those cases. It also
includes a change to suppress unneeded (and sometimes wrong) accessibility
checks on conversions of actual parameters of a derived type to the parent
type when passing them on calls to parent primitives (encountered while
developing these changes).

gcc/ada/ChangeLog:

* exp_util.adb (Must_Map_Call_To_Parent_Primitive): Change function
name (was Call_To_Parent_Dispatching_Op_Must_Be_Mapped). Move logic
for attributes and dereferences, plus testing for controlled formals,
into new function Expr_Has_Ctrl_Formal_Ref. Add handling for
access attributes, multiple levels of attributes/dereferences,
conditional_expressions, and declare_expressions. Properly account
for function calls with multiple operands and enclosing calls.
(Expr_Has_Ctrl_Formal_Ref): New function to determine whether
an expression is a reference to a controlling formal or has
a prefix that is such a reference.
(Is_Controlling_Formal_Ref): New function in Expr_Has_Ctrl_Formal_Ref
to determine if a node is a direct reference to a controlling formal.
* freeze.adb (Build_DTW_Body): Create an unchecked conversion instead
of a regular type conversion for converting actuals in calls to parent
inherited primitives that are wrapped for inherited pre/postconditions.
Avoids generating unnecessary checks (such as accessibility checks on
conversions for anonymous access formals).

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_util.adb | 197 ---
 gcc/ada/freeze.adb   |   7 +-
 2 files changed, 154 insertions(+), 50 deletions(-)

diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 3f6646b050c..79bf6da86ca 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -1528,31 +1528,135 @@ package body Exp_Util is
   Ctrl_Type : constant Entity_Id
 := Find_Dispatching_Type (Par_Subp);
 
-  function Call_To_Parent_Dispatching_Op_Must_Be_Mapped
-(Call_Node : Node_Id) return Boolean;
+  function Must_Map_Call_To_Parent_Primitive
+(Call_Node : Node_Id;
+ Check_Parents : Boolean := True) return Boolean;
   --  If Call_Node is a call to a primitive function F of the
   --  tagged type T associated with Par_Subp that either has
-  --  any actuals that are controlling formals of Par_Subp,
+  --  any actuals that involve controlling formals of Par_Subp,
   --  or else the call to F is an actual parameter of an
   --  enclosing call to a primitive of T that has any actuals
-  --  that are controlling formals of Par_Subp (and recursively
-  --  up the tree of enclosing function calls), returns True;
-  --  otherwise returns False. Returning True implies that the
-  --  call to F must be mapped to a call that instead targets
-  --  the corresponding function F of the tagged type for which
-  --  Subp is a primitive function.
+  --  that involve controlling formals of Par_Subp (and
+  --  recursively up the tree of enclosing function calls),
+  --  returns True; otherwise returns False. Returning True
+  --  implies that the call to F must be mapped to a call
+  --  that instead targets the corresponding function F of
+  --  the tagged type for which Subp is a primitive function.
+  --  Checks_Parent specifies whether this function should
+  --  recursively check enclosing calls.
 
-  --
-  -- Call_To_Parent_Dispatching_Op_Must_Be_Mapped --
-  --
+  ---
+  -- Must_Map_Call_To_Parent_Primitive --
+  ---
 
-  function Call_To_Parent_Dispatching_Op_Must_Be_Mapped
-(Call_Node : Node_Id) return Boolean
+  function Must_Map_Call_To_Parent_Primitive
+(Call_Node : Node_Id;
+ Check_Parents : Boolean := True) return Bool

[PATCH] c++, v2: Fix up cp_build_array_ref COND_EXPR handling [PR120471]

2025-06-30 Thread Jakub Jelinek
On Mon, Jun 30, 2025 at 10:51:38AM -0400, Jason Merrill wrote:
> > > So, kill the optimization unless idx is INTEGER_CST (am not sure
> > > TREE_SIDE_EFFECTS is sufficient because it could be e.g. reading
> > > from some
> > > VAR_DECL),
> > 
> > !TREE_SIDE_EFFECTS && tree_invariant_p?
> 
> Or perhaps introduce a predicate that checks whether it's safe to use an
> expression in both branches of a COND_EXPR, i.e. if there are no
> SAVE_EXPR/TARGET_EXPR/BIND_EXPR?

That might work too.

> > > and perhaps try to recover the optimization in GIMPLE?
> > > Though, I think we don't gimplify ARRAY_REF into ARRAY_REF if the first
> > > operand is not an array and don't create ARRAY_REFs for what has been
> > > written as *(arr + idx).  On the other side, ARRAY_REF is beneficial
> > > primary for the simple cases, so maybe if op1 and op2 are ADDR_EXPRs
> > > of non-volatile VAR_DECLs or COMPONENT_REFs with VAR_DECL bases so
> > > constant or constant offset from frame, E1 is sequenced before E2 won't
> > > be really observable and we could use the 3 SAVE_EXPRs.
> > > 
> > > I think it has been added for
> > > https://gcc.gnu.org/pipermail/gcc-patches/2001-April/thread.html#48160
> > > but I'm sure GIMPLE in between FE and expansion changed things
> > > sufficiently
> > > that it won't ICE anymore.
> > 
> > And my comment in that thread was that pushing the indexing down into
> > the COND_EXPR is probably undesirable once we start doing "significant
> > optimization on trees" so maybe we should just drop it?
> 
> I see that simply removing the COND_EXPR case from cp_build_array_ref brings
> back the ICE from that thread, so more work is needed.
> 
> I guess your suggestion of only pushing the indexing down for simple indexes
> makes sense, otherwise do the *(a ? &b : &c)[d] transformation.

For now I've bootstrapped/regtested on x86_64-linux and i686-linux the
following version, which
1) for idx being INTEGER_CST (case for which I believe the change has been
   added) it keeps doing what it did
2) if both op1 and op2 are arrays with invariant address or pointers to
   something with invariant address, it uses
   SAVE_EXPR , SAVE_EXPR  SAVE_EXPR 
   as COND_EXPR condition and otherwise what it did
3) otherwise punt

Now, perhaps a predicate (but how to call it) whether idx doesn't
contain any SAVE_EXPRs/TARGET_EXPRs/BIND_EXPRs and isn't really large
expression (but how to measure it; perhaps also no CALL_EXPRs, and the
question if it should allow say multiplication/division/modulo, those might
need larger code as well) could be used instead of the INTEGER_CST check,
either immediately or incrementally.
But guess I should first try to reproduce the ICE you've mentioned.

> > For release branches, would unshare_expr (idx) for the second arm be
> > enough?
> 
> Ah, no, that doesn't help with SAVE_EXPR.

Neither with TARGET_EXPRs I think, for neither of those I think unshare_expr
actually unshares them and for a good reason, it can't know where is the
SAVE_EXPR or TARGET_EXPR first used, whether inside of the expression, in
that case it might be desirable to unshare those, or if in some earlier
code, then it can't be unshared.

2025-06-30  Jakub Jelinek  

PR c++/120471
* typeck.cc (cp_build_array_ref) : If idx is not
INTEGER_CST, don't optimize the case or use
SAVE_EXPR , SAVE_EXPR , SAVE_EXPR  as new op0 depending
on flag_strong_eval_order and whether op1 and op2 are arrays with
invariant address or tree invariant pointers.  Formatting fixes.

* g++.dg/ubsan/pr120471.C: New test.

--- gcc/cp/typeck.cc.jj 2025-06-30 10:59:28.016583215 +0200
+++ gcc/cp/typeck.cc2025-06-30 11:49:54.879741494 +0200
@@ -4001,13 +4001,67 @@ cp_build_array_ref (location_t loc, tree
   }
 
 case COND_EXPR:
-  ret = build_conditional_expr
-  (loc, TREE_OPERAND (array, 0),
-  cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
-  complain),
-  cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx,
-  complain),
-  complain);
+  tree op0, op1, op2;
+  op0 = TREE_OPERAND (array, 0);
+  op1 = TREE_OPERAND (array, 1);
+  op2 = TREE_OPERAND (array, 1);
+  if (TREE_CODE (idx) != INTEGER_CST)
+   {
+ /* If idx could possibly have some SAVE_EXPRs, turning
+(op0 ? op1 : op2)[idx] into
+op0 ? op1[idx] : op2[idx] can lead into temporaries
+initialized in one conditional path and uninitialized
+uses of them in the other path.
+And if idx is a really large expression, evaluating it
+twice is also not optimal.
+On the other side, op0 must be sequenced before evaluation
+of op1 and op2 and for C++17 op0, op1 and op2 must be
+sequenced before idx.
+If idx is INTEGER_CST, we can just do the optimization
+without any SA

Re: [PATCH 2/2] libstdc++: Use ranges::iter_move in ranges::remove_if [PR120789]

2025-06-30 Thread Jonathan Wakely
OK for trunk and backports.

On Fri, 27 Jun 2025 at 03:51, Patrick Palka  wrote:
>
> PR libstdc++/120789
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/ranges_algo.h (__remove_if_fn::operator()): Use
> ranges::iter_move(iter) instead of std::move(*iter).
> * testsuite/25_algorithms/remove_if/120789.cc: New test.
> ---
>  libstdc++-v3/include/bits/ranges_algo.h   |  2 +-
>  .../25_algorithms/remove_if/120789.cc | 36 +++
>  2 files changed, 37 insertions(+), 1 deletion(-)
>  create mode 100644 libstdc++-v3/testsuite/25_algorithms/remove_if/120789.cc
>
> diff --git a/libstdc++-v3/include/bits/ranges_algo.h 
> b/libstdc++-v3/include/bits/ranges_algo.h
> index 3590c501c4cd..7ef761f9c977 100644
> --- a/libstdc++-v3/include/bits/ranges_algo.h
> +++ b/libstdc++-v3/include/bits/ranges_algo.h
> @@ -1294,7 +1294,7 @@ namespace ranges
> for (; __first != __last; ++__first)
>   if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
> {
> - *__result = std::move(*__first);
> + *__result = ranges::iter_move(__first);
>   ++__result;
> }
>
> diff --git a/libstdc++-v3/testsuite/25_algorithms/remove_if/120789.cc 
> b/libstdc++-v3/testsuite/25_algorithms/remove_if/120789.cc
> new file mode 100644
> index ..c1f4eeb9b4dd
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/25_algorithms/remove_if/120789.cc
> @@ -0,0 +1,36 @@
> +// PR libstdc++/120789 - ranges::remove_if should use ranges::iter_move
> +// { dg-do compile { target c++20 } }
> +
> +#include 
> +
> +struct A
> +{
> +  bool operator==(const A&) const;
> +};
> +
> +struct B
> +{
> +  B(B&&) = delete;
> +  B& operator=(const A&) const;
> +
> +  operator A() const;
> +  bool operator==(const B&) const;
> +};
> +
> +struct I
> +{
> +  using value_type = A;
> +  using difference_type = int;
> +  B operator*() const;
> +  I& operator++();
> +  I operator++(int);
> +  bool operator==(const I&) const;
> +  friend A iter_move(const I&);
> +};
> +
> +void
> +test01()
> +{
> +  std::ranges::subrange r;
> +  auto [begin, end] = std::ranges::remove_if(r, [](auto&&) { return true; });
> +}
> --
> 2.50.0.131.gcf6f63ea6b
>



Re: [PATCH 1/2] libstdc++: Use ranges::iter_move in ranges::unique [PR120789]

2025-06-30 Thread Jonathan Wakely
On Fri, 27 Jun 2025 at 03:44, Patrick Palka  wrote:
>
> Tested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps
> 15/14?

Yes for trunk and backports.

>
> -- >8 --
>
> PR libstdc++/120789
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/ranges_algo.h (__unique_fn::operator()): Use
> ranges::iter_move(iter) instead of std::move(*iter).
> * testsuite/25_algorithms/unique/120789.cc: New test.
> ---
>  libstdc++-v3/include/bits/ranges_algo.h   |  2 +-
>  .../testsuite/25_algorithms/unique/120789.cc  | 36 +++
>  2 files changed, 37 insertions(+), 1 deletion(-)
>  create mode 100644 libstdc++-v3/testsuite/25_algorithms/unique/120789.cc
>
> diff --git a/libstdc++-v3/include/bits/ranges_algo.h 
> b/libstdc++-v3/include/bits/ranges_algo.h
> index 83eaa7da28b9..3590c501c4cd 100644
> --- a/libstdc++-v3/include/bits/ranges_algo.h
> +++ b/libstdc++-v3/include/bits/ranges_algo.h
> @@ -1454,7 +1454,7 @@ namespace ranges
>   if (!std::__invoke(__comp,
>  std::__invoke(__proj, *__dest),
>  std::__invoke(__proj, *__first)))
> -   *++__dest = std::move(*__first);
> +   *++__dest = ranges::iter_move(__first);
> return {++__dest, __first};
>}
>
> diff --git a/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc 
> b/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc
> new file mode 100644
> index ..24b107132473
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/25_algorithms/unique/120789.cc
> @@ -0,0 +1,36 @@
> +// PR libstdc++/120789 - ranges::unique should use ranges::iter_move
> +// { dg-do compile { target c++20 } }
> +
> +#include 
> +
> +struct A
> +{
> +  bool operator==(const A&) const;
> +};
> +
> +struct B
> +{
> +  B(B&&) = delete;
> +  B& operator=(const A&) const;
> +
> +  operator A() const;
> +  bool operator==(const B&) const;
> +};
> +
> +struct I
> +{
> +  using value_type = A;
> +  using difference_type = int;
> +  B operator*() const;
> +  I& operator++();
> +  I operator++(int);
> +  bool operator==(const I&) const;
> +  friend A iter_move(const I&);
> +};
> +
> +void
> +test01()
> +{
> +  std::ranges::subrange r;
> +  auto [begin, end] = std::ranges::unique(r);
> +}
> --
> 2.50.0.131.gcf6f63ea6b
>



[COMMITTED] Regenerate common.opt.urls

2025-06-30 Thread Mark Wielaard
When -fauto-profile-inlining was added it was documented, but
common.opt.urls wasn't regenerated.

Fixes: aaf55e09b3d9 ("Add -fauto-profile-inlining")

gcc/ChangeLog:

* common.opt.urls: Regenerate.
---
 gcc/common.opt.urls | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls
index c7f234bce413..c7050895cc96 100644
--- a/gcc/common.opt.urls
+++ b/gcc/common.opt.urls
@@ -433,6 +433,9 @@ UrlSuffix(gcc/Optimize-Options.html#index-fauto-profile)
 fauto-profile=
 UrlSuffix(gcc/Optimize-Options.html#index-fauto-profile)
 
+fauto-profile-inlining
+UrlSuffix(gcc/Optimize-Options.html#index-fauto-profile-inlining)
+
 fbounds-check
 LangUrlSuffix_D(gdc/Runtime-Options.html#index-fbounds-check) 
LangUrlSuffix_Fortran(gfortran/Code-Gen-Options.html#index-fbounds-check)
 
-- 
2.49.0



Re: [Patch] builtins.def: Enable OpenMP/OpenACC builtins also with -fno-nonansi-builtins

2025-06-30 Thread Thomas Schwinge
Hi!

On 2025-06-05T10:42:00+0200, Tobias Burnus  wrote:
> Currently, using the ISO version of C and C++ will disable the
> OpenMP and OpenACC intrinsics, which is rather surprising. The
> reason is that those imply -fno-nonansi-builtins and the
> OpenMP/OpenACC are marked as non-ansi builtins.
>
> While the latter is true, -fopenmp/-fopenacc seems to be rather
> orthogonal and should be regarded as category of their own,
> uneffected by -std=c23 vs. -std=gnu23 or -std=c++23 vs. -std=gnu++23.

That rationale appears to make sense to me; this intends to handle these
OpenACC, OpenMP ones similar to 'DEF_GCC_BUILTIN', 'DEF_SYNC_BUILTIN',
for example.

> Comments before I commit this patch?

Can we please get test cases added for this?

> builtins.def: Enable OpenMP/OpenACC builtins also with -fno-nonansi-builtins
>
> The -std=c.. and -std=c++.. imply -fno-nonansi-builtins, which disabled the
> OpenMP/OpenACC intrinsics - but -fopenmp/-fopenacc builtin use should be
> rather othogonal to the user's choice between -std=c... and -std=gnuc...

> --- a/gcc/builtins.def
> +++ b/gcc/builtins.def
> @@ -217,6 +217,8 @@ along with GCC; see the file COPYING3.  If not see
>DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,\
>  false, true, true, ATTRS, false, \
>  flag_openacc)
> +/* Set NONANSI_P = false to enable the builtins also with 
> -fno-nonansi-builtins
> +   as -std=c++23 (which implies the former) and -fopenacc should be 
> othogonal. */
>  #undef DEF_GOACC_BUILTIN_COMPILER
>  #define DEF_GOACC_BUILTIN_COMPILER(ENUM, NAME, TYPE, ATTRS) \
>DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,\

You add the comment, but don't actually "Set NONANSI_P = false" here?

> @@ -232,10 +234,12 @@ along with GCC; see the file COPYING3.  If not see
>  (flag_openacc \
>   || flag_openmp \
>   || flag_tree_parallelize_loops > 1))
> +/* Set NONANSI_P = false to enable the builtins also with 
> -fno-nonansi-builtins
> +   as -std=c++23 (which implies the former) and -fopenmp should be 
> othogonal. */
>  #undef DEF_GOMP_BUILTIN_COMPILER
>  #define DEF_GOMP_BUILTIN_COMPILER(ENUM, NAME, TYPE, ATTRS) \
>DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,\
> -   flag_openmp, true, true, ATTRS, false, flag_openmp)
> +   flag_openmp, true, false, ATTRS, false, flag_openmp)

(... like you do here.)

Also, is this really applicable to 'DEF_GOACC_BUILTIN_COMPILER',
'DEF_GOMP_BUILTIN_COMPILER' only, but not the other ones:
'DEF_GOACC_BUILTIN', 'DEF_GOACC_BUILTIN_ONLY', 'DEF_GOMP_BUILTIN'?


Grüße
 Thomas


Re: [PATCH v6 1/3][Middle-end] Provide more contexts for -Warray-bounds, -Wstringop-*warning messages due to code movements from compiler transformation (Part 1) [PR109071,PR85788,PR88771,PR106762,PR1

2025-06-30 Thread David Malcolm
On Mon, 2025-06-30 at 16:47 +, Qing Zhao wrote:

[...snip...]

> The output with -fdiagnostics-show-context=1 is:
> 
> /home/opc/Work/GCC/latest-gcc-
> write/gcc/testsuite/gcc.dg/pr109071_7.c: In function ‘foo’:
> /home/opc/Work/GCC/latest-gcc-
> write/gcc/testsuite/gcc.dg/pr109071_7.c:12:6: warning: array
> subscript -1 is below array bounds of ‘int[10]’ [-Warray-bounds=]
>    12 | a[i] = -1; /* { dg-warning "is below array bounds of" }
> */
>   | ~^~~
>   ‘foo’: events 1-2
>    11 |   if (i == -1)
>   |  ^
>   |  |
>   |  (1) when the condition is evaluated to true

Looks great, but one caution: presumably "true" in this context refers
to the state of the IR when the warning is emitted, rather than what
the user wrote.  I've run into this in the analyzer;
see PR analyzer/100116 (which I don't have a good solution for, alas).

Is there a way to get at the original sense of the condition, in terms
of what the user wrote?  I'm guessing that this has been canonicalized
away long before the middle-end warnings see this.

Or perhaps the message for (1) could say exactly what condition it
considers to be true e.g.
  (1) when the condition "i == -1" is evaluated to true
or somesuch, which might give the user a better clue if the sense of
the conditional has been reversed during canonicalization/optimization.

Caveat: I didn't reread the latest version of your patch, but am just
assuming it's looking at the cfg edge flags when the warning is
emitted; sorry if I'm making a false assumption here.

> 
Dave



Re: [PATCH] c++, v2: Fix up cp_build_array_ref COND_EXPR handling [PR120471]

2025-06-30 Thread Jakub Jelinek
On Mon, Jun 30, 2025 at 03:55:46PM -0400, Jason Merrill wrote:
> Might go with my earlier !TREE_SIDE_EFFECTS && tree_invariant_p suggestion?

If you mean the following, it passes the 2 testcases and I can surely
bootstrap/regtest it tonight.

2025-06-30  Jakub Jelinek  

PR c++/120471
* typeck.cc (cp_build_array_ref) : If idx is not
INTEGER_CST, don't optimize the case (but cp_default_conversion on
array early if it has ARRAY_TYPE) or use
SAVE_EXPR , SAVE_EXPR , SAVE_EXPR  as new op0 depending
on flag_strong_eval_order and whether op1 and op2 are arrays with
invariant address or tree invariant pointers.  Formatting fixes.

* g++.dg/ubsan/pr120471.C: New test.
* g++.dg/parse/pr120471.C: New test.

--- gcc/cp/typeck.cc.jj 2025-06-30 12:19:16.398242029 +0200
+++ gcc/cp/typeck.cc2025-06-30 22:12:55.313206118 +0200
@@ -4001,13 +4001,91 @@ cp_build_array_ref (location_t loc, tree
   }
 
 case COND_EXPR:
-  ret = build_conditional_expr
-  (loc, TREE_OPERAND (array, 0),
-  cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
-  complain),
-  cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx,
-  complain),
-  complain);
+  tree op0, op1, op2;
+  op0 = TREE_OPERAND (array, 0);
+  op1 = TREE_OPERAND (array, 1);
+  op2 = TREE_OPERAND (array, 1);
+  if (TREE_SIDE_EFFECTS (idx) || !tree_invariant_p (idx))
+   {
+ /* If idx could possibly have some SAVE_EXPRs, turning
+(op0 ? op1 : op2)[idx] into
+op0 ? op1[idx] : op2[idx] can lead into temporaries
+initialized in one conditional path and uninitialized
+uses of them in the other path.
+And if idx is a really large expression, evaluating it
+twice is also not optimal.
+On the other side, op0 must be sequenced before evaluation
+of op1 and op2 and for C++17 op0, op1 and op2 must be
+sequenced before idx.
+If idx is INTEGER_CST, we can just do the optimization
+without any SAVE_EXPRs, if op1 and op2 are both ARRAY_TYPE
+VAR_DECLs or COMPONENT_REFs thereof (so their address
+is constant or relative to frame), optimize into
+(SAVE_EXPR , SAVE_EXPR , SAVE_EXPR )
+? op1[SAVE_EXPR ] : op2[SAVE_EXPR ]
+Otherwise avoid this optimization.  */
+ if (flag_strong_eval_order == 2)
+   {
+ if (TREE_CODE (TREE_TYPE (op1)) == ARRAY_TYPE)
+   {
+ tree xop1 = op1;
+ while (TREE_CODE (xop1) == COMPONENT_REF)
+   xop1 = TREE_OPERAND (xop1, 0);
+ STRIP_ANY_LOCATION_WRAPPER (xop1);
+ if (!decl_address_invariant_p (xop1))
+   {
+ /* Force default conversion on array if
+we can't optimize this and array has ARRAY_TYPE
+COND_EXPR, we can't leave COND_EXPRs with
+ARRAY_TYPE in the IL.  */
+ if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
+   {
+ array = cp_default_conversion (array, complain);
+ if (error_operand_p (array))
+   return error_mark_node;
+   }
+ break;
+   }
+   }
+ else if (!POINTER_TYPE_P (TREE_TYPE (op1))
+  || !tree_invariant_p (op1))
+   break;
+ if (TREE_CODE (TREE_TYPE (op2)) == ARRAY_TYPE)
+   {
+ tree xop2 = op2;
+ while (TREE_CODE (xop2) == COMPONENT_REF)
+   xop2 = TREE_OPERAND (xop2, 0);
+ STRIP_ANY_LOCATION_WRAPPER (xop2);
+ if (!decl_address_invariant_p (xop2))
+   {
+ /* Force default conversion on array if
+we can't optimize this and array has ARRAY_TYPE
+COND_EXPR, we can't leave COND_EXPRs with
+ARRAY_TYPE in the IL.  */
+ if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
+   {
+ array = cp_default_conversion (array, complain);
+ if (error_operand_p (array))
+   return error_mark_node;
+   }
+ break;
+   }
+   }
+ else if (!POINTER_TYPE_P (TREE_TYPE (op2))
+  || !tree_invariant_p (op2))
+   break;
+   }
+ if (TREE_SIDE_EFFECTS (idx))
+   {
+ idx = save_expr (idx);
+ op0 = save_expr (op0);
+ tree tem = build_compound

Re: [PATCH RFC] libgcc: don't use a weak ref for __cxa_finalize

2025-06-30 Thread Joseph Myers
On Sat, 28 Jun 2025, Jason Merrill wrote:

> +  if (!flag_use_cxa_atexit != !DEFAULT_USE_CXA_ATEXIT)
> +{
> +  const char *opt, *copt;
> +  if (flag_use_cxa_atexit)
> + opt = "-fuse-cxa-atexit", copt = "--enable-__cxa_atexit";
> +  else
> + opt = "-fno-use-cxa-atexit", copt = "--disable-__cxa_atexit";
> +  warning (0, "ignoring %s, configure gcc with %s instead", opt, copt);
> +  flag_use_cxa_atexit = DEFAULT_USE_CXA_ATEXIT;
> +}

The diagnostic style should use %qs for both those options.

-- 
Joseph S. Myers
josmy...@redhat.com



  1   2   >