[gcc r14-11807] gimple-fold: Avoid ICEs with bogus declarations like const attribute no snprintf [PR117358]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:e326152845584d78410963e5c3d31cdbdf8f50fe

commit r14-11807-ge326152845584d78410963e5c3d31cdbdf8f50fe
Author: Jakub Jelinek 
Date:   Thu Nov 28 10:51:16 2024 +0100

gimple-fold: Avoid ICEs with bogus declarations like const attribute no 
snprintf [PR117358]

When one puts incorrect const or pure attributes on declarations of various
C APIs which have corresponding builtins (vs. what they actually do), we can
get tons of ICEs in gimple-fold.cc.

The following patch fixes it by giving up gimple_fold_builtin_* folding
if the functions don't have gimple_vdef (or for pure functions like
bcmp/strchr/strstr gimple_vuse) when in SSA form (during gimplification
they will surely have both of those NULL even when declared correctly,
yet it is highly desirable to fold them).

Or shall I replace
!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)
tests with
(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE | ECF_NOVOPS)) != 0
and
!gimple_vuse (stmt) && gimple_in_ssa_p (cfun)
with
(gimple_call_flags (stmt) & (ECF_CONST | ECF_NOVOPS)) != 0
?

2024-11-28  Jakub Jelinek  

PR tree-optimization/117358
* gimple-fold.cc (gimple_fold_builtin_memory_op): Punt if stmt has 
no
vdef in ssa form.
(gimple_fold_builtin_bcmp): Punt if stmt has no vuse in ssa form.
(gimple_fold_builtin_bcopy): Punt if stmt has no vdef in ssa form.
(gimple_fold_builtin_bzero): Likewise.
(gimple_fold_builtin_memset): Likewise.  Use return false instead of
return NULL_TREE.
(gimple_fold_builtin_strcpy): Punt if stmt has no vdef in ssa form.
(gimple_fold_builtin_strncpy): Likewise.
(gimple_fold_builtin_strchr): Punt if stmt has no vuse in ssa form.
(gimple_fold_builtin_strstr): Likewise.
(gimple_fold_builtin_strcat): Punt if stmt has no vdef in ssa form.
(gimple_fold_builtin_strcat_chk): Likewise.
(gimple_fold_builtin_strncat): Likewise.
(gimple_fold_builtin_strncat_chk): Likewise.
(gimple_fold_builtin_string_compare): Likewise.
(gimple_fold_builtin_fputs): Likewise.
(gimple_fold_builtin_memory_chk): Likewise.
(gimple_fold_builtin_stxcpy_chk): Likewise.
(gimple_fold_builtin_stxncpy_chk): Likewise.
(gimple_fold_builtin_stpcpy): Likewise.
(gimple_fold_builtin_snprintf_chk): Likewise.
(gimple_fold_builtin_sprintf_chk): Likewise.
(gimple_fold_builtin_sprintf): Likewise.
(gimple_fold_builtin_snprintf): Likewise.
(gimple_fold_builtin_fprintf): Likewise.
(gimple_fold_builtin_printf): Likewise.
(gimple_fold_builtin_realloc): Likewise.

* gcc.c-torture/compile/pr117358.c: New test.

(cherry picked from commit 29032dfa57629d1713a97b17a785273823993a91)

Diff:
---
 gcc/gimple-fold.cc | 76 --
 gcc/testsuite/gcc.c-torture/compile/pr117358.c | 17 ++
 2 files changed, 77 insertions(+), 16 deletions(-)

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 3548c9144829..0d90bab595fc 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -936,6 +936,8 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
}
   goto done;
 }
+  else if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+return false;
   else
 {
   /* We cannot (easily) change the type of the copy if it is a storage
@@ -1377,6 +1379,8 @@ gimple_fold_builtin_bcmp (gimple_stmt_iterator *gsi)
   /* Transform bcmp (a, b, len) into memcmp (a, b, len).  */
 
   gimple *stmt = gsi_stmt (*gsi);
+  if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun))
+return false;
   tree a = gimple_call_arg (stmt, 0);
   tree b = gimple_call_arg (stmt, 1);
   tree len = gimple_call_arg (stmt, 2);
@@ -1403,6 +1407,8 @@ gimple_fold_builtin_bcopy (gimple_stmt_iterator *gsi)
  len) into memmove (dest, src, len).  */
 
   gimple *stmt = gsi_stmt (*gsi);
+  if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+return false;
   tree src = gimple_call_arg (stmt, 0);
   tree dest = gimple_call_arg (stmt, 1);
   tree len = gimple_call_arg (stmt, 2);
@@ -1428,6 +1434,8 @@ gimple_fold_builtin_bzero (gimple_stmt_iterator *gsi)
   /* Transform bzero (dest, len) into memset (dest, 0, len).  */
 
   gimple *stmt = gsi_stmt (*gsi);
+  if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+return false;
   tree dest = gimple_call_arg (stmt, 0);
   tree len = gimple_call_arg (stmt, 1);
 
@@ -1457,6 +1465,9 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, 
tree c, tree len)
   return true;
 }
 
+  if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+return false;
+
   if (! tree_fits_uhwi_p (len))
 return false;
 
@@ -1479,20 +1490,20 @@ gimple_fold_b

[gcc r16-876] Fixup gcc.target/i386/vect-epilogues-5.c

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:c61743a186cfecd646334817f356f799502ee71a

commit r16-876-gc61743a186cfecd646334817f356f799502ee71a
Author: Richard Biener 
Date:   Mon May 26 11:21:19 2025 +0200

Fixup gcc.target/i386/vect-epilogues-5.c

The following adjusts the expected messages after -fopt-info-vec
was improved for (masked) epilogues.

* gcc.target/i386/vect-epilogues-5.c: Adjust.

Diff:
---
 gcc/testsuite/gcc.target/i386/vect-epilogues-5.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/i386/vect-epilogues-5.c 
b/gcc/testsuite/gcc.target/i386/vect-epilogues-5.c
index 6772cabeb4a4..d7c75dfe5cc9 100644
--- a/gcc/testsuite/gcc.target/i386/vect-epilogues-5.c
+++ b/gcc/testsuite/gcc.target/i386/vect-epilogues-5.c
@@ -9,5 +9,6 @@ int test (signed char *data, int n)
   return sum;
 }
 
-/* { dg-final { scan-tree-dump-times "loop vectorized using 64 byte vectors" 2 
"vect" } } */
+/* { dg-final { scan-tree-dump-times "loop vectorized using 64 byte vectors" 1 
"vect" } } */
+/* { dg-final { scan-tree-dump-times "epilogue loop vectorized using masked 64 
byte vectors" 1 "vect" } } */
 /* { dg-final { scan-tree-dump-not "loop vectorized using 32 byte vectors" 
"vect" } } */


[gcc r16-877] libstdc++: Implement C++26 function_ref [PR119126]

2025-05-26 Thread Tomasz Kaminski via Gcc-cvs
https://gcc.gnu.org/g:545433e9bd32e965726956cb238d53b39844b85c

commit r16-877-g545433e9bd32e965726956cb238d53b39844b85c
Author: Tomasz Kamiński 
Date:   Wed May 14 12:04:24 2025 +0200

libstdc++: Implement C++26 function_ref [PR119126]

This patch implements C++26 function_ref as specified in P0792R14,
with correction for constraints for constructor accepting nontype_t
parameter from LWG 4256.

As function_ref may store a pointer to the const object, __Ptrs::_M_obj is
changed to const void*, so again we do not cast away const from const
objects. To help with necessary casts, a __polyfunc::__cast_to helper is
added, that accepts reference to or target type direclty.

The _Invoker now defines additional call methods used by function_ref:
_S_ptrs() for invoking target passed by reference, and __S_nttp, 
_S_bind_ptr,
_S_bind_ref for handling constructors accepting nontype_t. The existing
_S_call_storage is changed to thin wrapper, that initialies _Ptrs, and 
forwards
to _S_call_ptrs.

This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref,
so this functions was removed, and _Manager uses were adjusted.

Finally we make function_ref available in freestanding mode, as
move_only_function and copyable_function are currently only available in 
hosted,
so we define _Manager and _Mo_base only if either 
__glibcxx_move_only_function
or __glibcxx_copyable_function is defined.

PR libstdc++/119126

libstdc++-v3/ChangeLog:

* doc/doxygen/stdheader.cc: Added funcref_impl.h file.
* include/Makefile.am: Added funcref_impl.h file.
* include/Makefile.in: Added funcref_impl.h file.
* include/bits/funcref_impl.h: New file.
* include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify.
(_Storage::_M_ptr, _Storage::_M_ref): Remove.
(__polyfunc::__cast_to) Define.
(_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp)
(_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref)
(_Base_invoker::_S_call_ptrs): Define.
(_Base_invoker::_S_call_storage): Foward to _S_call_ptrs.
(_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being
const qualified.
(__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with
__glibcxx_move_only_function || __glibcxx_copyable_function.
(__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref)
(std::function_ref) [__glibcxx_function_ref]: Define.
* include/bits/utility.h (std::nontype_t, std::nontype)
(__is_nontype_v) [__glibcxx_function_ref]: Define.
* include/bits/version.def: Define function_ref.
* include/bits/version.h: Regenerate.
* include/std/functional: Define __cpp_lib_function_ref.
* src/c++23/std.cc.in (std::nontype_t, std::nontype)
(std::function_ref) [__cpp_lib_function_ref]: Export.
* testsuite/20_util/function_ref/assign.cc: New test.
* testsuite/20_util/function_ref/call.cc: New test.
* testsuite/20_util/function_ref/cons.cc: New test.
* testsuite/20_util/function_ref/cons_neg.cc: New test.
* testsuite/20_util/function_ref/conv.cc: New test.
* testsuite/20_util/function_ref/deduction.cc: New test.
* testsuite/20_util/function_ref/mutation.cc: New test.

Reviewed-by: Jonathan Wakely 
Signed-off-by: Tomasz Kamiński 

Diff:
---
 libstdc++-v3/doc/doxygen/stdheader.cc  |   1 +
 libstdc++-v3/include/Makefile.am   |   1 +
 libstdc++-v3/include/Makefile.in   |   1 +
 libstdc++-v3/include/bits/funcref_impl.h   | 198 
 libstdc++-v3/include/bits/funcwrap.h   | 188 +++
 libstdc++-v3/include/bits/utility.h|  17 ++
 libstdc++-v3/include/bits/version.def  |   8 +
 libstdc++-v3/include/bits/version.h|  10 +
 libstdc++-v3/include/std/functional|   3 +-
 libstdc++-v3/src/c++23/std.cc.in   |   7 +
 .../testsuite/20_util/function_ref/assign.cc   | 108 +
 .../testsuite/20_util/function_ref/call.cc | 186 +++
 .../testsuite/20_util/function_ref/cons.cc | 218 +
 .../testsuite/20_util/function_ref/cons_neg.cc |  30 +++
 .../testsuite/20_util/function_ref/conv.cc | 259 +
 .../testsuite/20_util/function_ref/deduction.cc| 103 
 .../testsuite/20_util/function_ref/mutation.cc |  85 +++
 17 files changed, 1376 insertions(+), 47 deletions(-)

diff --git a/libstdc++-v3/doc/doxygen/stdheader.cc 
b/libstdc++-v3/doc/doxygen/stdheader.cc
index 839bfc81bc02..938b2b04a262 100644
--- a/libstdc++-v3/doc/doxygen/stdheader.cc
+++ b/libstdc++-v3/doc/dox

[gcc r14-11809] cselib: Fix up previous patch for SPARC [PR117239]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:5499c332a60a6928274796af0667d40719bf0715

commit r14-11809-g5499c332a60a6928274796af0667d40719bf0715
Author: Jakub Jelinek 
Date:   Wed Feb 5 14:06:42 2025 +0100

cselib: Fix up previous patch for SPARC [PR117239]

Sorry, our CI bot just notified me I broke SPARC build.  There are two
 #ifdef STACK_ADDRESS_OFFSET
guarded snippets and the macro is only defined on SPARC target, so I didn't
notice there was a syntax error.

Fixed thusly.

2025-02-05  Jakub Jelinek  

PR rtl-optimization/117239
* cselib.cc (cselib_init): Remove spurious closing paren in
the #ifdef STACK_ADDRESS_OFFSET specific code.

(cherry picked from commit 6094801d6fd7849d2d95ce78f7c6ef01686b9f63)

Diff:
---
 gcc/cselib.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cselib.cc b/gcc/cselib.cc
index 2382e994ebc2..f0a8f2c7f8fb 100644
--- a/gcc/cselib.cc
+++ b/gcc/cselib.cc
@@ -3364,7 +3364,7 @@ cselib_init (int record_what)
 #ifdef STACK_ADDRESS_OFFSET
  /* On SPARC take stack pointer bias into account as well.  */
  off += (STACK_ADDRESS_OFFSET
- - FIRST_PARM_OFFSET (current_function_decl)));
+ - FIRST_PARM_OFFSET (current_function_decl));
 #endif
  callmem[1] = plus_constant (Pmode, stack_pointer_rtx, off);
}


[gcc r14-11810] alias: Perform offset arithmetics in poly_offset_int rather than poly_int64 [PR118819]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:4b9f2877e334b4108c33259753acfdd27820b4f5

commit r14-11810-g4b9f2877e334b4108c33259753acfdd27820b4f5
Author: Jakub Jelinek 
Date:   Thu Feb 27 08:48:18 2025 +0100

alias: Perform offset arithmetics in poly_offset_int rather than poly_int64 
[PR118819]

This PR is about ubsan error on the c - cx1 + cy1 evaluation in the first
hunk.

The following patch hopefully fixes that by doing the additions/subtractions
in poly_offset_int rather than poly_int64 and then converting back to 
poly_int64.
If it doesn't fit, -1 is returned (which means it is unknown if there is a 
conflict
or not).

2025-02-27  Jakub Jelinek  

PR middle-end/118819
* alias.cc (memrefs_conflict_p): Perform arithmetics on c, xsize and
ysize in poly_offset_int and return -1 if it is not representable in
poly_int64.

(cherry picked from commit b570f48c3dfb9ca3d640467cff67e569904009d4)

Diff:
---
 gcc/alias.cc | 68 ++--
 1 file changed, 57 insertions(+), 11 deletions(-)

diff --git a/gcc/alias.cc b/gcc/alias.cc
index 808e2095d9b4..fab7161f6941 100644
--- a/gcc/alias.cc
+++ b/gcc/alias.cc
@@ -2533,19 +2533,39 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 
ysize, rtx y,
return memrefs_conflict_p (xsize, x1, ysize, y1, c);
  if (poly_int_rtx_p (x1, &cx1))
{
+ poly_offset_int co = c;
+ co -= cx1;
  if (poly_int_rtx_p (y1, &cy1))
-   return memrefs_conflict_p (xsize, x0, ysize, y0,
-  c - cx1 + cy1);
+   {
+ co += cy1;
+ if (!co.to_shwi (&c))
+   return -1;
+ return memrefs_conflict_p (xsize, x0, ysize, y0, c);
+   }
+ else if (!co.to_shwi (&c))
+   return -1;
  else
-   return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
+   return memrefs_conflict_p (xsize, x0, ysize, y, c);
}
  else if (poly_int_rtx_p (y1, &cy1))
-   return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
+   {
+ poly_offset_int co = c;
+ co += cy1;
+ if (!co.to_shwi (&c))
+   return -1;
+ return memrefs_conflict_p (xsize, x, ysize, y0, c);
+   }
 
  return -1;
}
   else if (poly_int_rtx_p (x1, &cx1))
-   return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
+   {
+ poly_offset_int co = c;
+ co -= cx1;
+ if (!co.to_shwi (&c))
+   return -1;
+ return memrefs_conflict_p (xsize, x0, ysize, y, c);
+   }
 }
   else if (GET_CODE (y) == PLUS)
 {
@@ -2561,7 +2581,13 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 
ysize, rtx y,
 
   poly_int64 cy1;
   if (poly_int_rtx_p (y1, &cy1))
-   return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
+   {
+ poly_offset_int co = c;
+ co += cy1;
+ if (!co.to_shwi (&c))
+   return -1;
+ return memrefs_conflict_p (xsize, x, ysize, y0, c);
+   }
   else
return -1;
 }
@@ -2614,8 +2640,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 
ysize, rtx y,
  if (maybe_gt (xsize, 0))
xsize = -xsize;
  if (maybe_ne (xsize, 0))
-   xsize += sc + 1;
- c -= sc + 1;
+   {
+ poly_offset_int xsizeo = xsize;
+ xsizeo += sc + 1;
+ if (!xsizeo.to_shwi (&xsize))
+   return -1;
+   }
+ poly_offset_int co = c;
+ co -= sc + 1;
+ if (!co.to_shwi (&c))
+   return -1;
  return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
 ysize, y, c);
}
@@ -2629,8 +2663,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 
ysize, rtx y,
  if (maybe_gt (ysize, 0))
ysize = -ysize;
  if (maybe_ne (ysize, 0))
-   ysize += sc + 1;
- c += sc + 1;
+   {
+ poly_offset_int ysizeo = ysize;
+ ysizeo += sc + 1;
+ if (!ysizeo.to_shwi (&ysize))
+   return -1;
+   }
+ poly_offset_int co = c;
+ co += sc + 1;
+ if (!co.to_shwi (&c))
+   return -1;
  return memrefs_conflict_p (xsize, x,
 ysize, canon_rtx (XEXP (y, 0)), c);
}
@@ -2641,7 +2683,11 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 
ysize, rtx y,
   poly_int64 cx, cy;
   if (poly_int_rtx_p (x, &cx) && poly_int_rtx_p (y, &cy))
{
- c += cy - cx;
+ poly_offset_int co = c;
+ co += cy;
+ co -= cx;
+ if (!co.to_shwi (&c))
+   return -1;
  

[gcc r16-888] RISC-V: Add testcases for signed vector SAT_ADD IMM form 1

2025-05-26 Thread Li Xu via Gcc-cvs
https://gcc.gnu.org/g:a91679a3d9f7cbc079880f201fd8292c1d54baa7

commit r16-888-ga91679a3d9f7cbc079880f201fd8292c1d54baa7
Author: xuli 
Date:   Thu Dec 26 09:39:08 2024 +

RISC-V: Add testcases for signed vector SAT_ADD IMM form 1

This patch adds testcase for form1, as shown below:

void __attribute__((noinline))   \
vec_sat_s_add_imm_##T##_fmt_1##_##INDEX (T *out, T *op_1, unsigned limit) \
{\
  unsigned i;\
  for (i = 0; i < limit; i++)\
{\
  T x = op_1[i]; \
  T sum = (UT)x + (UT)IMM;   \
  out[i] = (x ^ IMM) < 0 \
? sum\
: (sum ^ x) >= 0 \
  ? sum  \
  : x < 0 ? MIN : MAX;   \
}\
}

Passed the rv64gcv regression test.

Signed-off-by: Li Xu 
gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h: add signed vec 
SAT_ADD IMM form1.
* gcc.target/riscv/rvv/autovec/sat/vec_sat_data.h: add 
sat_s_add_imm data.
* gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-1-i16.c: New 
test.
* gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-1-i32.c: New 
test.
* gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-1-i64.c: New 
test.
* gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-1-i8.c: New 
test.
* gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-run-1-i16.c: 
New test.
* gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-run-1-i32.c: 
New test.
* gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-run-1-i64.c: 
New test.
* gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-run-1-i8.c: 
New test.
* 
gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm_type_check-1-i16.c: New test.
* 
gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm_type_check-1-i32.c: New test.
* 
gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm_type_check-1-i8.c: New test.

Diff:
---
 .../riscv/rvv/autovec/sat/vec_sat_arith.h  |  25 +++
 .../riscv/rvv/autovec/sat/vec_sat_data.h   | 240 +
 .../rvv/autovec/sat/vec_sat_s_add_imm-1-i16.c  |  10 +
 .../rvv/autovec/sat/vec_sat_s_add_imm-1-i32.c  |  10 +
 .../rvv/autovec/sat/vec_sat_s_add_imm-1-i64.c  |  10 +
 .../riscv/rvv/autovec/sat/vec_sat_s_add_imm-1-i8.c |  10 +
 .../rvv/autovec/sat/vec_sat_s_add_imm-run-1-i16.c  |  28 +++
 .../rvv/autovec/sat/vec_sat_s_add_imm-run-1-i32.c  |  28 +++
 .../rvv/autovec/sat/vec_sat_s_add_imm-run-1-i64.c  |  28 +++
 .../rvv/autovec/sat/vec_sat_s_add_imm-run-1-i8.c   |  28 +++
 .../sat/vec_sat_s_add_imm_type_check-1-i16.c   |   9 +
 .../sat/vec_sat_s_add_imm_type_check-1-i32.c   |   9 +
 .../sat/vec_sat_s_add_imm_type_check-1-i8.c|  10 +
 13 files changed, 445 insertions(+)

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h
index 983c9b440abc..f78bdc047ca1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h
@@ -345,6 +345,31 @@ vec_sat_s_add_##T##_fmt_4 (T *out, T *op_1, T *op_2, 
unsigned limit) \
 #define RUN_VEC_SAT_S_ADD_FMT_4_WRAP(T, out, op_1, op_2, N) \
   RUN_VEC_SAT_S_ADD_FMT_4(T, out, op_1, op_2, N)
 
+#define DEF_VEC_SAT_S_ADD_IMM_FMT_1(INDEX, T, UT, IMM, MIN, MAX) \
+void __attribute__((noinline))   \
+vec_sat_s_add_imm_##T##_fmt_1##_##INDEX (T *out, T *op_1, unsigned limit) \
+{\
+  unsigned i;\
+  for (i = 0; i < limit; i++)\
+{\
+  T x = op_1[i]; \
+  T sum = (UT)x + (UT)IMM;   \
+  out[i] = (x ^ IMM) < 0 \
+? sum\
+: (sum ^ x) >= 0 \
+  ? sum  \
+  : x < 0 ? MIN : M

[gcc r16-887] Match:Support signed vector SAT_ADD IMM form 1

2025-05-26 Thread Li Xu via Gcc-cvs
https://gcc.gnu.org/g:70fdc02b60935bf8de886795dda13924b0c08cad

commit r16-887-g70fdc02b60935bf8de886795dda13924b0c08cad
Author: xuli 
Date:   Thu Dec 26 09:06:57 2024 +

Match:Support signed vector SAT_ADD IMM form 1

This patch would like to support vector SAT_ADD when one of the op
is singed IMM.

void __attribute__((noinline))   \
vec_sat_s_add_imm_##T##_fmt_1##_##INDEX (T *out, T *op_1, unsigned limit) \
{\
  unsigned i;\
  for (i = 0; i < limit; i++)\
{\
  T x = op_1[i]; \
  T sum = (UT)x + (UT)IMM;   \
  out[i] = (x ^ IMM) < 0 \
? sum\
: (sum ^ x) >= 0 \
  ? sum  \
  : x < 0 ? MIN : MAX;   \
}\
}

Take below form1 as example:
DEF_VEC_SAT_S_ADD_IMM_FMT_1(0, int8_t, uint8_t, 9, INT8_MIN, INT8_MAX)

Before this patch:
__attribute__((noinline))
void vec_sat_s_add_imm_int8_t_fmt_1_0 (int8_t * restrict out, int8_t * 
restrict op_1, unsigned int limit)
{
  vector([16,16]) signed char * vectp_out.28;
  vector([16,16]) signed char vect_iftmp.27;
  vector([16,16])  mask__28.26;
  vector([16,16])  mask__29.25;
  vector([16,16])  mask__19.19;
  vector([16,16])  mask__31.18;
  vector([16,16]) signed char vect__6.17;
  vector([16,16]) signed char vect__5.16;
  vector([16,16]) signed char vect_sum_15.15;
  vector([16,16]) unsigned char vect__4.14;
  vector([16,16]) unsigned char vect_x.13;
  vector([16,16]) signed char vect_x_14.12;
  vector([16,16]) signed char * vectp_op_1.10;
  vector([16,16])  _78;
  vector([16,16]) unsigned char _79;
  vector([16,16]) unsigned char _80;
  unsigned long _92;
  unsigned long ivtmp_93;
  unsigned long ivtmp_94;
  unsigned long _95;

   [local count: 118111598]:
  if (limit_12(D) != 0)
goto ; [89.00%]
  else
goto ; [11.00%]

   [local count: 105119322]:
  _92 = (unsigned long) limit_12(D);

   [local count: 955630226]:
  # vectp_op_1.10_62 = PHI 
  # vectp_out.28_89 = PHI 
  # ivtmp_93 = PHI 
  _95 = .SELECT_VL (ivtmp_93, POLY_INT_CST [16, 16]);
  vect_x_14.12_64 = .MASK_LEN_LOAD (vectp_op_1.10_62, 8B, { -1, ... }, _95, 
0);
  vect_x.13_65 = VIEW_CONVERT_EXPR(vect_x_14.12_64);
  vect__4.14_67 = vect_x.13_65 + { 9, ... };
  vect_sum_15.15_68 = VIEW_CONVERT_EXPR(vect__4.14_67);
  vect__5.16_70 = vect_x_14.12_64 ^ { 9, ... };
  vect__6.17_71 = vect_x_14.12_64 ^ vect_sum_15.15_68;
  mask__31.18_73 = vect__5.16_70 >= { 0, ... };
  mask__19.19_75 = vect_x_14.12_64 < { 0, ... };
  mask__29.25_85 = vect__6.17_71 < { 0, ... };
  mask__28.26_86 = mask__31.18_73 & mask__29.25_85;
  _78 = ~mask__28.26_86;
  _79 = .VCOND_MASK (mask__19.19_75, { 128, ... }, { 127, ... });
  _80 = .COND_ADD (_78, vect_x.13_65, { 9, ... }, _79);
  vect_iftmp.27_87 = VIEW_CONVERT_EXPR(_80);
  .MASK_LEN_STORE (vectp_out.28_89, 8B, { -1, ... }, _95, 0, 
vect_iftmp.27_87);
  vectp_op_1.10_63 = vectp_op_1.10_62 + _95;
  vectp_out.28_90 = vectp_out.28_89 + _95;
  ivtmp_94 = ivtmp_93 - _95;
  if (ivtmp_94 != 0)
goto ; [89.00%]
  else
goto ; [11.00%]

   [local count: 118111600]:
  return;

}

After this patch:
__attribute__((noinline))
void vec_sat_s_add_imm_int8_t_fmt_1_0 (int8_t * restrict out, int8_t * 
restrict op_1, unsigned int limit)
{
  vector([16,16]) signed char * vectp_out.12;
  vector([16,16]) signed char vect_patt_10.11;
  vector([16,16]) signed char vect_x_14.10;
  vector([16,16]) signed char D.2852;
  vector([16,16]) signed char * vectp_op_1.8;
  vector([16,16]) signed char _73(D);
  unsigned long _80;
  unsigned long ivtmp_81;
  unsigned long ivtmp_82;
  unsigned long _83;

   [local count: 118111598]:
  if (limit_12(D) != 0)
goto ; [89.00%]
  else
goto ; [11.00%]

   [local count: 105119322]:
  _80 = (unsigned long) limit_12(D);

   [local count: 955630226]:
  # vectp_op_1.8_71 = PHI 
  # vectp_out.12_77 = PHI 
  # ivtmp_81 = PHI 
  _83 = .SELECT_VL (ivtmp_81, POLY_INT_CST [16, 16]);
  vect_x_14.10_74 = .MASK_LEN_LOAD (ve

[gcc r16-886] RISC-V:Add testcases for signed .SAT_ADD IMM form 1 with IMM = -1.

2025-05-26 Thread Li Xu via Gcc-cvs
https://gcc.gnu.org/g:4962e6d0810823d68349cd019f5dd53524a62ac5

commit r16-886-g4962e6d0810823d68349cd019f5dd53524a62ac5
Author: xuli 
Date:   Fri Dec 27 07:59:31 2024 +

RISC-V:Add testcases for signed .SAT_ADD IMM form 1 with IMM = -1.

This patch adds testcase for form1, as shown below:

T __attribute__((noinline))  \
sat_s_add_imm_##T##_fmt_1##_##INDEX (T x) \
{\
  T sum = (UT)x + (UT)IMM; \
  return (x ^ IMM) < 0 \
? sum\
: (sum ^ x) >= 0 \
  ? sum  \
  : x < 0 ? MIN : MAX;   \
}

Passed the rv64gcv regression test.

Signed-off-by: Li Xu 

gcc/testsuite/ChangeLog:

* gcc.target/riscv/sat/sat_s_add_imm-2.c: Move to...
* gcc.target/riscv/sat/sat_s_add_imm-1-i16.c: ...here.
* gcc.target/riscv/sat/sat_s_add_imm-3.c: Move to...
* gcc.target/riscv/sat/sat_s_add_imm-1-i32.c: ...here.
* gcc.target/riscv/sat/sat_s_add_imm-4.c: Move to...
* gcc.target/riscv/sat/sat_s_add_imm-1-i64.c: ...here.
* gcc.target/riscv/sat/sat_s_add_imm-1.c: Move to...
* gcc.target/riscv/sat/sat_s_add_imm-1-i8.c: ...here.
* gcc.target/riscv/sat/sat_s_add_imm-run-2.c: Move to...
* gcc.target/riscv/sat/sat_s_add_imm-run-1-i16.c: ...here.
* gcc.target/riscv/sat/sat_s_add_imm-run-3.c: Move to...
* gcc.target/riscv/sat/sat_s_add_imm-run-1-i32.c: ...here.
* gcc.target/riscv/sat/sat_s_add_imm-run-4.c: Move to...
* gcc.target/riscv/sat/sat_s_add_imm-run-1-i64.c: ...here.
* gcc.target/riscv/sat/sat_s_add_imm-run-1.c: Move to...
* gcc.target/riscv/sat/sat_s_add_imm-run-1-i8.c: ...here.
* gcc.target/riscv/sat/sat_s_add_imm-2-1.c: Move to...
* gcc.target/riscv/sat/sat_s_add_imm_type_check-1-i16.c: ...here.
* gcc.target/riscv/sat/sat_s_add_imm-3-1.c: Move to...
* gcc.target/riscv/sat/sat_s_add_imm_type_check-1-i32.c: ...here.
* gcc.target/riscv/sat/sat_s_add_imm-1-1.c: Move to...
* gcc.target/riscv/sat/sat_s_add_imm_type_check-1-i8.c: ...here.

Diff:
---
 .../{sat_s_add_imm-2.c => sat_s_add_imm-1-i16.c}   | 27 +-
 .../{sat_s_add_imm-3.c => sat_s_add_imm-1-i32.c}   | 26 -
 .../{sat_s_add_imm-4.c => sat_s_add_imm-1-i64.c}   | 22 +-
 .../{sat_s_add_imm-1.c => sat_s_add_imm-1-i8.c}| 22 +-
 ...s_add_imm-run-2.c => sat_s_add_imm-run-1-i16.c} |  6 +
 ...s_add_imm-run-3.c => sat_s_add_imm-run-1-i32.c} |  6 +
 ...s_add_imm-run-4.c => sat_s_add_imm-run-1-i64.c} |  6 +
 ..._s_add_imm-run-1.c => sat_s_add_imm-run-1-i8.c} |  6 +
 ..._imm-2-1.c => sat_s_add_imm_type_check-1-i16.c} |  0
 ..._imm-3-1.c => sat_s_add_imm_type_check-1-i32.c} |  0
 ...d_imm-1-1.c => sat_s_add_imm_type_check-1-i8.c} |  0
 11 files changed, 117 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2.c 
b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i16.c
similarity index 53%
rename from gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2.c
rename to gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i16.c
index 3878286d207b..2e23af5d86b7 100644
--- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2.c
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i16.c
@@ -29,4 +29,29 @@
 */
 DEF_SAT_S_ADD_IMM_FMT_1(0, int16_t, uint16_t, -7, INT16_MIN, INT16_MAX)
 
-/* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */
+/*
+** sat_s_add_imm_int16_t_fmt_1_1:
+** addi\s+[atx][0-9]+,\s*a0,\s*-1
+** not\s+[atx][0-9]+,\s*a0
+** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15
+** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15
+** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
+** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1
+** srai\s+a0,\s*a0,\s*63
+** li\s+[atx][0-9]+,\s*32768
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0
+** neg\s+a0,\s*[atx][0-9]+
+** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** or\s+a0,\s*a0,\s*[atx][0-9]+
+** slliw\s+a0,\s*a0,\s*16
+** sraiw\s+a0,\s*a0,\s*16
+** ret
+*/
+DEF_SAT_S_ADD_IMM_FMT_1(1, int16_t, uint16_t, -1, INT16_MIN, INT16_MAX)
+
+/* { dg-final { scan-tree-dump-times ".SAT_ADD " 2 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-3.c 
b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i32.c
similarity index 53%
rename from gcc/tests

[gcc r16-885] Match:Support IMM=-1 for signed scalar SAT_ADD IMM form1

2025-05-26 Thread Li Xu via Gcc-cvs
https://gcc.gnu.org/g:7cf7149ec8303d0ed828fb7629417b28e6565d32

commit r16-885-g7cf7149ec8303d0ed828fb7629417b28e6565d32
Author: xuli 
Date:   Fri Dec 27 07:03:14 2024 +

Match:Support IMM=-1 for signed scalar SAT_ADD IMM form1

This patch would like to support .SAT_ADD when IMM=-1.

Form1:
T __attribute__((noinline))  \
sat_s_add_imm_##T##_fmt_1##_##INDEX (T x) \
{\
  T sum = (UT)x + (UT)IMM; \
  return (x ^ IMM) < 0 \
? sum\
: (sum ^ x) >= 0 \
  ? sum  \
  : x < 0 ? MIN : MAX;   \
}

Take below form1 as example:
DEF_SAT_S_ADD_IMM_FMT_1(0, int8_t, uint8_t, -1, INT8_MIN, INT8_MAX)

Before this patch:
__attribute__((noinline))
int8_t sat_s_add_imm_int8_t_fmt_1_0 (int8_t x)
{
  unsigned char x.0_1;
  unsigned char _2;
  unsigned char _3;
  int8_t iftmp.1_4;
  signed char _8;
  unsigned char _9;
  signed char _10;

   [local count: 1073741824]:
  x.0_1 = (unsigned char) x_5(D);
  _3 = -x.0_1;
  _10 = (signed char) _3;
  _8 = x_5(D) & _10;
  if (_8 < 0)
goto ; [1.40%]
  else
goto ; [98.60%]

   [local count: 434070867]:
  _2 = x.0_1 + 255;

   [local count: 1073741824]:
  # _9 = PHI <_2(3), 128(2)>
  iftmp.1_4 = (int8_t) _9;
  return iftmp.1_4;

}

After this patch:
__attribute__((noinline))
int8_t sat_s_add_imm_int8_t_fmt_1_0 (int8_t x)
{
  int8_t _4;

   [local count: 1073741824]:
  gimple_call <.SAT_ADD, _4, x_5(D), 255> [tail call]
  gimple_return <_4>

}

The below test suites are passed for this patch:
1. The rv64gcv fully regression tests.
2. The x86 bootstrap tests.
3. The x86 fully regression tests.

Signed-off-by: Li Xu 

gcc/ChangeLog:

* match.pd: Add signed scalar SAT_ADD IMM form1 with IMM=-1 
matching.
* tree-ssa-math-opts.cc (match_unsigned_saturation_add): Adapt 
function name.
(match_saturation_add_with_assign): Match signed and unsigned 
SAT_ADD with assign.
(math_opts_dom_walker::after_dom_children): Match imm=-1 signed 
SAT_ADD with NOP_EXPR case.

Diff:
---
 gcc/match.pd  | 19 ++-
 gcc/tree-ssa-math-opts.cc | 30 +-
 2 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 27f662f9714b..50bd853b39a8 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3461,7 +3461,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(bit_xor:c @0 INTEGER_CST@3)) integer_zerop)
 (signed_integer_sat_val @0)
 @2)
-  (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0
+  (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0)))
+
+(match (signed_integer_sat_add @0 @1)
+  /* T SUM = (T)((UT)X + (UT)-1);
+ SAT_S_ADD = (X ^ -1) < 0 ? SUM : (X ^ SUM) >= 0 ? SUM
+ : (x < 0) ? MIN : MAX  */
+  (convert (cond^ (lt (bit_and:c @0 (nop_convert (negate (nop_convert @0
+ integer_zerop)
+INTEGER_CST@2
+(plus (nop_convert @0) integer_all_onesp@1)))
+   (with
+{
+ unsigned precision = TYPE_PRECISION (type);
+ wide_int c1 = wi::to_wide (@1);
+ wide_int c2 = wi::to_wide (@2);
+ wide_int sum = wi::add (c1, c2);
+}
+(if (wi::eq_p (sum, wi::max_value (precision, SIGNED)))
 
 /* Saturation sub for signed integer.  */
 (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index eb03ebe102ad..7e819f37446c 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -4104,15 +4104,34 @@ build_saturation_binary_arith_call_and_insert 
(gimple_stmt_iterator *gsi,
  *   _10 = -_9;
  *   _12 = _7 | _10;
  *   =>
- *   _12 = .SAT_ADD (_4, _6);  */
+ *   _12 = .SAT_ADD (_4, _6);
+ *
+ * Try to match IMM=-1 saturation signed add with assign.
+ *  [local count: 1073741824]:
+ * x.0_1 = (unsigned char) x_5(D);
+ * _3 = -x.0_1;
+ * _10 = (signed char) _3;
+ * _8 = x_5(D) & _10;
+ * if (_8 < 0)
+ *   goto ; [1.40%]
+ * else
+ *   goto ; [98.60%]
+ *  [local count: 434070867]:
+ * _2 = x.0_1 + 255;
+ *  [local count: 1073741824]:
+ * # _9 = PHI <_2(3), 128(2)>
+ * _4 = (int8_t) _9;
+ *   =>
+ * _4 = .SAT_ADD (x_5, -1); */
 
 static void
-match_unsigned_saturation_add (gimple_stmt_iterator *gsi, gassign *stmt)
+match_saturation_add_with_assign (gimple_stmt_iterator *gsi, gassign *stmt)
 {
   tree ops[2];
   tree lhs = gimple_assign_lhs (stmt);
 
-  if (gimple_unsigned_integer_sat_add (lhs, ops, NULL))
+  if (gimple_unsigned_integer_sat_add

[gcc r16-889] driver: Fix multilib_os_dir and multiarch_dir for those target use TARGET_COMPUTE_MULTILIB

2025-05-26 Thread Kito Cheng via Gcc-cvs
https://gcc.gnu.org/g:447156e4d143d7f513c488dd0b44037524a01fba

commit r16-889-g447156e4d143d7f513c488dd0b44037524a01fba
Author: Kito Cheng 
Date:   Mon Mar 10 16:26:04 2025 +0800

driver: Fix multilib_os_dir and multiarch_dir for those target use 
TARGET_COMPUTE_MULTILIB

This patch fixes the multilib_os_dir and multiarch_dir for those targets
that use TARGET_COMPUTE_MULTILIB, since the TARGET_COMPUTE_MULTILIB hook
only update/fix the multilib_dir but not the multilib_os_dir and 
multiarch_dir,
so the multilib_os_dir and multiarch_dir are not set correctly for those 
targets.

Use RISC-V linux target (riscv64-unknown-linux-gnu) as an example:

```
$ riscv64-unknown-linux-gnu-gcc -print-multi-lib
.;
lib32/ilp32;@march=rv32imac@mabi=ilp32
lib32/ilp32d;@march=rv32imafdc@mabi=ilp32d
lib64/lp64;@march=rv64imac@mabi=lp64
lib64/lp64d;@march=rv64imafdc@mabi=lp64d
```

If we use the exactly same -march and -mabi options to compile a source 
file,
the multilib_os_dir and multiarch_dir are set correctly:

```
$ riscv64-unknown-linux-gnu-gcc -print-multi-os-directory -march=rv64imafdc 
-mabi=lp64d
../lib64/lp64d
$ riscv64-unknown-linux-gnu-gcc -print-multi-directory -march=rv64imafdc 
-mabi=lp64d
lib64/lp64d
```

However if we use the -march=rv64imafdcv -mabi=lp64d option to compile a 
source
file, the multilib_os_dir and multiarch_dir are not set correctly:
```
$ riscv64-unknown-linux-gnu-gcc -print-multi-os-directory -march=rv64imafdc 
-mabi=lp64d
lib64/lp64d
$ riscv64-unknown-linux-gnu-gcc -print-multi-directory -march=rv64imafdc 
-mabi=lp64d
lib64/lp64d
```

That's because the TARGET_COMPUTE_MULTILIB hook only update/fix the 
multilib_dir
but not the multilib_os_dir, so the multilib_os_dir is blank and will use 
same
value as multilib_dir, but that is not correct.

So we introduce second chance to fix the multilib_os_dir if it's not set, 
we do
also try to fix the multiarch_dir, because it may also not set correctly if
multilib_os_dir is not set.

Changes since v1:
- Fix non-multilib build.
- Fix fix indentation.

gcc/ChangeLog:

* gcc.cc (find_multilib_os_dir_by_multilib_dir): New.
(set_multilib_dir): Fix multilib_os_dir and multiarch_dir
if multilib_os_dir is not set.

Diff:
---
 gcc/gcc.cc | 108 -
 1 file changed, 107 insertions(+), 1 deletion(-)

diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 4fd87f2c4a13..4e61de2a47c3 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -9747,6 +9747,103 @@ default_arg (const char *p, int len)
   return 0;
 }
 
+/* Use multilib_dir as key to find corresponding multilib_os_dir and
+   multiarch_dir.  */
+
+static void
+find_multilib_os_dir_by_multilib_dir (const char *multilib_dir,
+ const char **p_multilib_os_dir,
+ const char **p_multiarch_dir)
+{
+  const char *p = multilib_select;
+  unsigned int this_path_len;
+  const char *this_path;
+  int ok = 0;
+
+  while (*p != '\0')
+{
+  /* Ignore newlines.  */
+  if (*p == '\n')
+   {
+ ++p;
+ continue;
+   }
+
+  /* Get the initial path.  */
+  this_path = p;
+  while (*p != ' ')
+   {
+ if (*p == '\0')
+   {
+ fatal_error (input_location, "multilib select %qs %qs is invalid",
+  multilib_select, multilib_reuse);
+   }
+ ++p;
+   }
+  this_path_len = p - this_path;
+
+  ok = 0;
+
+  /* Skip any arguments, we don't care at this stage.  */
+  while (*++p != ';');
+
+  if (this_path_len != 1
+ || this_path[0] != '.')
+   {
+ char *new_multilib_dir = XNEWVEC (char, this_path_len + 1);
+ char *q;
+
+ strncpy (new_multilib_dir, this_path, this_path_len);
+ new_multilib_dir[this_path_len] = '\0';
+ q = strchr (new_multilib_dir, ':');
+ if (q != NULL)
+   *q = '\0';
+
+ if (strcmp (new_multilib_dir, multilib_dir) == 0)
+   ok = 1;
+   }
+
+  /* Found matched multilib_dir, update multilib_os_dir and
+multiarch_dir.  */
+  if (ok)
+   {
+ const char *q = this_path, *end = this_path + this_path_len;
+
+ while (q < end && *q != ':')
+   q++;
+ if (q < end)
+   {
+ const char *q2 = q + 1, *ml_end = end;
+ char *new_multilib_os_dir;
+
+ while (q2 < end && *q2 != ':')
+   q2++;
+ if (*q2 == ':')
+   ml_end = q2;
+ if (ml_end - q == 1)
+   *p_multilib_os_dir = xstrdup (".");
+ else
+   {
+ new_multilib_os_dir = XNEWVEC (char, ml_end - q);
+ memcpy (new_mu

[gcc r13-9689] asan: Don't fold some strlens with -fsanitize=address [PR110676]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:c884148d3cb440fca6692452aabb42c340b987a9

commit r13-9689-gc884148d3cb440fca6692452aabb42c340b987a9
Author: Jakub Jelinek 
Date:   Tue Feb 6 13:00:04 2024 +0100

asan: Don't fold some strlens with -fsanitize=address [PR110676]

The UB on the following testcase isn't diagnosed by -fsanitize=address,
because we see that the array has a single element and optimize the
strlen to 0.  I think it is fine to assume e.g. for range purposes the
lower bound for the strlen as long as we don't try to optimize
strlen (str)
where we know that it returns [26, 42] to
26 + strlen (str + 26), but for the upper bound we really want to punt
on optimizing that for -fsanitize=address to read all the bytes of the
string and diagnose if we run to object end etc.

2024-02-06  Jakub Jelinek  

PR sanitizer/110676
* gimple-fold.cc (gimple_fold_builtin_strlen): For 
-fsanitize=address
reset maxlen to sizetype maximum.

* gcc.dg/asan/pr110676.c: New test.

(cherry picked from commit d3eac7d96de790df51859f63c13838f153b416de)

Diff:
---
 gcc/gimple-fold.cc   |  5 +
 gcc/testsuite/gcc.dg/asan/pr110676.c | 14 ++
 2 files changed, 19 insertions(+)

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 5bdd1d08a265..b5f4a9ec0a1c 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -4020,6 +4020,11 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
   maxlen = wi::to_wide (max_object_size (), prec) - 2;
 }
 
+  /* For -fsanitize=address, don't optimize the upper bound of the
+ length to be able to diagnose UB on non-zero terminated arrays.  */
+  if (sanitize_flags_p (SANITIZE_ADDRESS))
+maxlen = wi::max_value (TYPE_PRECISION (sizetype), UNSIGNED);
+
   if (minlen == maxlen)
 {
   /* Fold the strlen call to a constant.  */
diff --git a/gcc/testsuite/gcc.dg/asan/pr110676.c 
b/gcc/testsuite/gcc.dg/asan/pr110676.c
new file mode 100644
index ..0ae6fdd67b59
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/pr110676.c
@@ -0,0 +1,14 @@
+/* PR sanitizer/110676 */
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+/* { dg-shouldfail "asan" } */
+
+int
+main ()
+{
+  char s[1] = "A";
+  return __builtin_strlen (s);
+}
+
+/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow on 
address.*(\n|\r\n|\r)" } */
+/* { dg-output "READ of size.*" } */


[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] gimple-exec: correction prise en charge offset adresse MEM_REF

2025-05-26 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:947a0417737071a7fbc10a826a3bff75e252b660

commit 947a0417737071a7fbc10a826a3bff75e252b660
Author: Mikael Morin 
Date:   Mon May 26 10:47:41 2025 +0200

gimple-exec: correction prise en charge offset adresse MEM_REF

Diff:
---
 gcc/cgraphunit.cc | 251 ++
 1 file changed, 161 insertions(+), 90 deletions(-)

diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
index 62fb874dbdba..97013daa9fbd 100644
--- a/gcc/cgraphunit.cc
+++ b/gcc/cgraphunit.cc
@@ -3880,14 +3880,13 @@ exec_context::evaluate (tree expr) const
storage_address *address = val_ptr.get_address ();
gcc_assert (address != nullptr);
data_value storage_value = address->storage.get ().get_value ();
-   unsigned ptr_offset = address->offset;
+   wide_int ptr_off = wi::uhwi (address->offset,
+HOST_BITS_PER_WIDE_INT);
 
tree offset_bytes = TREE_OPERAND (expr, 1);
data_value val_off = evaluate (offset_bytes);
gcc_assert (val_off.classify () == VAL_CONSTANT);
wide_int wi_off = val_off.get_cst ();
-   gcc_assert (wi::fits_uhwi_p (wi_off));
-   unsigned offset = wi_off.to_uhwi ();
 
unsigned bit_width;
if (!get_constant_type_size (TREE_TYPE (expr), bit_width))
@@ -3909,13 +3908,14 @@ exec_context::evaluate (tree expr) const
gcc_assert (val_step.classify () == VAL_CONSTANT);
wide_int wi_step = val_step.get_cst ();
 
-   wide_int additional_off = wi_idx * wi_step;
-   gcc_assert (wi::fits_uhwi_p (additional_off));
-   offset += additional_off.to_uhwi ();
+   wi_off += wi_idx * wi_step;
  }
  }
 
-   return storage_value.get_at (offset * CHAR_BIT + ptr_offset, bit_width);
+   wi_off = wi_off * CHAR_BIT + ptr_off;
+   gcc_assert (wi::fits_uhwi_p (wi_off));
+
+   return storage_value.get_at (wi_off.to_shwi (), bit_width);
   }
   break;
 
@@ -4206,105 +4206,130 @@ exec_context::evaluate_binary (enum tree_code code, 
tree type, tree lhs, tree rh
 gcc_unreachable ();
 }
 
-void
-exec_context::decompose_ref (tree data_ref, data_storage * & storage, int & 
offset) const
+
+static bool
+is_zero_offset_data_ref (enum tree_code code)
 {
-  offset = -1;
-  enum tree_code code = TREE_CODE (data_ref);
   switch (code)
 {
 case VAR_DECL:
 case SSA_NAME:
-  {
-   tree var = data_ref;
-   offset = 0;
-   storage = find_reachable_var (var);
-  }
-  break;
+  return true;
 
-case ARRAY_REF:
-  {
-   data_storage *parent_storage = nullptr;
-   int parent_offset = -1;
-   tree parent_ref = TREE_OPERAND (data_ref, 0);
-   decompose_ref (parent_ref, parent_storage, parent_offset);
-   gcc_assert (parent_offset >= 0);
-   gcc_assert (parent_storage != nullptr);
-
-   tree idx = TREE_OPERAND (data_ref, 1);
-   data_value val = evaluate (idx);
-   gcc_assert (val.classify () == VAL_CONSTANT);
-   wide_int wi_idx = val.get_cst ();
-   gcc_assert (wi::fits_uhwi_p (wi_idx));
-   unsigned HOST_WIDE_INT hw_idx = wi_idx.to_uhwi ();
-
-   gcc_assert (TREE_OPERAND (data_ref, 3) == NULL_TREE);
-   tree elt_type = TREE_TYPE (TREE_TYPE (parent_ref));
-   unsigned size_bits;
-   bool found_size = get_constant_type_size (elt_type, size_bits);
-   gcc_assert (found_size);
-   unsigned this_offset = hw_idx * size_bits;
+default:
+  return false;
+}
+}
 
-   storage = parent_storage;
-   offset = parent_offset + this_offset;
-  }
-  break;
 
-case COMPONENT_REF:
-  {
-   data_storage *parent_storage = nullptr;
-   int parent_offset = -1;
-   decompose_ref (TREE_OPERAND (data_ref, 0), parent_storage, 
parent_offset);
-   gcc_assert (parent_offset >= 0);
-   gcc_assert (parent_storage != nullptr);
+void
+exec_context::decompose_ref (tree data_ref, data_storage * & storage, int & 
offset) const
+{
+  offset = -1;
+  enum tree_code code = TREE_CODE (data_ref);
+  if (is_zero_offset_data_ref (code))
+{
+  offset = 0;
+  storage = find_reachable_var (data_ref);
+}
+  else
+{
+  tree parent_data_ref = nullptr;
+  wide_int add_offset = wi::zero (HOST_BITS_PER_WIDE_INT);
+  wide_int add_index = wi::zero (HOST_BITS_PER_WIDE_INT);
+  wide_int add_multiplier = wi::zero (HOST_BITS_PER_WIDE_INT);
+  switch (code)
+   {
+   case ARRAY_REF:
+ {
+   parent_data_ref = TREE_OPERAND (data_ref, 0);
+
+   tree idx = TREE_OPERAND (data_ref, 1);
+   data_value val = evaluate (idx);
+   gcc_assert (val.classify () == VAL_CONSTANT);
+   add_index = val.get_cst ();
+
+   gcc_assert (TREE_OPERAND (data_ref, 3) == NULL_TREE);
+   tree elt_type = TREE_TYPE (TREE_TYPE (parent_data_ref));
+   unsigned size_bits;
+  

[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Revert modifs finalization

2025-05-26 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c28356e40bd6ed46c8bd259215351a4ac65372cd

commit c28356e40bd6ed46c8bd259215351a4ac65372cd
Author: Mikael Morin 
Date:   Mon May 26 17:22:25 2025 +0200

Revert modifs finalization

Diff:
---
 gcc/fortran/class.cc  | 369 --
 gcc/fortran/trans-expr.cc |   9 +-
 2 files changed, 324 insertions(+), 54 deletions(-)

diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index e6a99be93210..41be63bf768f 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -1343,12 +1343,14 @@ finalization_scalarizer (gfc_symbol *array, gfc_symbol 
*ptr,
  offset = 0
  do idx2 = 1, rank
offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
- end do  */
+ end do
+ offset = offset * byte_stride.  */
 
 static gfc_code*
 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
 gfc_symbol *strides, gfc_symbol *sizes,
-gfc_expr *rank, gfc_code *block, gfc_namespace *sub_ns)
+gfc_symbol *byte_stride, gfc_expr *rank,
+gfc_code *block, gfc_namespace *sub_ns)
 {
   gfc_iterator *iter;
   gfc_expr *expr, *expr2;
@@ -1441,6 +1443,17 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol 
*idx2, gfc_symbol *offset,
   block->block->next->expr2->ts = idx->ts;
   block->block->next->expr2->where = gfc_current_locus;
 
+  /* After the loop:  offset = offset * byte_stride.  */
+  block->next = gfc_get_code (EXEC_ASSIGN);
+  block = block->next;
+  block->expr1 = gfc_lval_expr_from_sym (offset);
+  block->expr2 = gfc_get_expr ();
+  block->expr2->expr_type = EXPR_OP;
+  block->expr2->value.op.op = INTRINSIC_TIMES;
+  block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
+  block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
+  block->expr2->ts = block->expr2->value.op.op1->ts;
+  block->expr2->where = gfc_current_locus;
   return block;
 }
 
@@ -1477,18 +1490,247 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol 
*idx2, gfc_symbol *offset,
 
 static void
 finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
- gfc_symbol *array, gfc_symbol *byte_stride 
ATTRIBUTE_UNUSED,
- gfc_symbol *nelem ATTRIBUTE_UNUSED, gfc_symbol 
*is_contiguous ATTRIBUTE_UNUSED,
- gfc_namespace *sub_ns ATTRIBUTE_UNUSED)
+ gfc_symbol *array, gfc_symbol *byte_stride,
+ gfc_symbol *idx, gfc_symbol *ptr,
+ gfc_symbol *nelem,
+ gfc_symbol *strides, gfc_symbol *sizes,
+ gfc_symbol *idx2, gfc_symbol *offset,
+ gfc_symbol *is_contiguous, gfc_expr *rank,
+ gfc_namespace *sub_ns)
 {
+  gfc_symbol *tmp_array, *ptr2;
+  gfc_expr *size_expr, *offset2, *expr;
+  gfc_namespace *ns;
+  gfc_iterator *iter;
+  gfc_code *block2;
+  int i;
+
+  block->next = gfc_get_code (EXEC_IF);
+  block = block->next;
+
+  block->block = gfc_get_code (EXEC_IF);
+  block = block->block;
+
+  /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE.  */
+  size_expr = gfc_get_expr ();
+  size_expr->where = gfc_current_locus;
+  size_expr->expr_type = EXPR_OP;
+  size_expr->value.op.op = INTRINSIC_DIVIDE;
+
+  /* STORAGE_SIZE (array,kind=c_intptr_t).  */
+  size_expr->value.op.op1
+   = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
+   "storage_size", gfc_current_locus, 2,
+   gfc_lval_expr_from_sym (array),
+   gfc_get_int_expr (gfc_index_integer_kind,
+ NULL, 0));
+
+  /* NUMERIC_STORAGE_SIZE.  */
+  size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
+ gfc_character_storage_size);
+  size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
+  size_expr->ts = size_expr->value.op.op1->ts;
+
+  /* IF condition: (stride == size_expr
+   && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
+   || is_contiguous)
+  || 0 == size_expr.  */
+  block->expr1 = gfc_get_expr ();
+  block->expr1->ts.type = BT_LOGICAL;
+  block->expr1->ts.kind = gfc_default_logical_kind;
+  block->expr1->expr_type = EXPR_OP;
+  block->expr1->where = gfc_current_locus;
+
+  block->expr1->value.op.op = INTRINSIC_OR;
+
+  /* byte_stride == size_expr */
+  expr = gfc_get_expr ();
+  expr->ts.type = BT_LOGICAL;
+  expr->ts.kind = gfc_default_logical_kind;
+  expr->expr_type = EXPR_OP;
+  expr->where = gfc_current_locus;
+  expr->value.op.op = INTRINSIC_EQ;
+  expr->value.op.op1
+   = gfc_lval_expr_from_sym (byte_stride);
+  expr->value.op.op2 = size_expr;
+
+  /* If strides aren't allowed (

[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régressions finalization

2025-05-26 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:fe8c567d6554f6e47fbea88be57450584442f6ed

commit fe8c567d6554f6e47fbea88be57450584442f6ed
Author: Mikael Morin 
Date:   Mon May 26 17:26:44 2025 +0200

Correction régressions finalization

Diff:
---
 gcc/fortran/class.cc | 13 +
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 41be63bf768f..aee7f2ce8f5e 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -1349,7 +1349,7 @@ finalization_scalarizer (gfc_symbol *array, gfc_symbol 
*ptr,
 static gfc_code*
 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
 gfc_symbol *strides, gfc_symbol *sizes,
-gfc_symbol *byte_stride, gfc_expr *rank,
+gfc_symbol *byte_stride ATTRIBUTE_UNUSED, gfc_expr 
*rank,
 gfc_code *block, gfc_namespace *sub_ns)
 {
   gfc_iterator *iter;
@@ -1443,17 +1443,6 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol 
*idx2, gfc_symbol *offset,
   block->block->next->expr2->ts = idx->ts;
   block->block->next->expr2->where = gfc_current_locus;
 
-  /* After the loop:  offset = offset * byte_stride.  */
-  block->next = gfc_get_code (EXEC_ASSIGN);
-  block = block->next;
-  block->expr1 = gfc_lval_expr_from_sym (offset);
-  block->expr2 = gfc_get_expr ();
-  block->expr2->expr_type = EXPR_OP;
-  block->expr2->value.op.op = INTRINSIC_TIMES;
-  block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
-  block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
-  block->expr2->ts = block->expr2->value.op.op1->ts;
-  block->expr2->where = gfc_current_locus;
   return block;
 }


[gcc r13-9695] cselib: Fix up previous patch for SPARC [PR117239]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:ffac0a49a88e0e366d35739d97fced2b01bfcf89

commit r13-9695-gffac0a49a88e0e366d35739d97fced2b01bfcf89
Author: Jakub Jelinek 
Date:   Wed Feb 5 14:06:42 2025 +0100

cselib: Fix up previous patch for SPARC [PR117239]

Sorry, our CI bot just notified me I broke SPARC build.  There are two
 #ifdef STACK_ADDRESS_OFFSET
guarded snippets and the macro is only defined on SPARC target, so I didn't
notice there was a syntax error.

Fixed thusly.

2025-02-05  Jakub Jelinek  

PR rtl-optimization/117239
* cselib.cc (cselib_init): Remove spurious closing paren in
the #ifdef STACK_ADDRESS_OFFSET specific code.

(cherry picked from commit 6094801d6fd7849d2d95ce78f7c6ef01686b9f63)

Diff:
---
 gcc/cselib.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cselib.cc b/gcc/cselib.cc
index fba96d5a8e30..476a94b08f2a 100644
--- a/gcc/cselib.cc
+++ b/gcc/cselib.cc
@@ -3359,7 +3359,7 @@ cselib_init (int record_what)
 #ifdef STACK_ADDRESS_OFFSET
  /* On SPARC take stack pointer bias into account as well.  */
  off += (STACK_ADDRESS_OFFSET
- - FIRST_PARM_OFFSET (current_function_decl)));
+ - FIRST_PARM_OFFSET (current_function_decl));
 #endif
  callmem[1] = plus_constant (Pmode, stack_pointer_rtx, off);
}


[gcc r13-9697] i386: Change RTL representation of bt[lq] [PR118623]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:b70fba168fb3b11998a80e21cec0eb7fa7a42da7

commit r13-9697-gb70fba168fb3b11998a80e21cec0eb7fa7a42da7
Author: Jakub Jelinek 
Date:   Mon Feb 10 10:40:22 2025 +0100

i386: Change RTL representation of bt[lq] [PR118623]

The following testcase is miscompiled because of RTL represententation
of bt{l,q} insn followed by e.g. j{c,nc} being misleading to what it
actually does.
Let's look e.g. at
(define_insn_and_split "*jcc_bt"
  [(set (pc)
(if_then_else (match_operator 0 "bt_comparison_operator"
[(zero_extract:SWI48
   (match_operand:SWI48 1 "nonimmediate_operand")
   (const_int 1)
   (match_operand:QI 2 "nonmemory_operand"))
 (const_int 0)])
  (label_ref (match_operand 3))
  (pc)))
   (clobber (reg:CC FLAGS_REG))]
  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
   && (CONST_INT_P (operands[2])
   ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (mode)
  && INTVAL (operands[2])
   >= (optimize_function_for_size_p (cfun) ? 8 : 32))
   : !memory_operand (operands[1], mode))
   && ix86_pre_reload_split ()"
  "#"
  "&& 1"
  [(set (reg:CCC FLAGS_REG)
(compare:CCC
  (zero_extract:SWI48
(match_dup 1)
(const_int 1)
(match_dup 2))
  (const_int 0)))
   (set (pc)
(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
  (label_ref (match_dup 3))
  (pc)))]
{
  operands[0] = shallow_copy_rtx (operands[0]);
  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
})
The define_insn part in RTL describes exactly what it does,
jumps to op3 if bit op2 in op1 is set (for op0 NE) or not set (for op0 EQ).
The problem is with what it splits into.
put_condition_code %C1 for CCCmode comparisons emits c for EQ and LTU,
nc for NE and GEU and ICEs otherwise.
CCCmode is used mainly for carry out of add/adc, borrow out of sub/sbb,
in those cases e.g. for add we have
(set (reg:CCC flags) (compare:CCC (plus:M x y) x))
and use (ltu (reg:CCC flags) (const_int 0)) for carry set and
(geu (reg:CCC flags) (const_int 0)) for carry not set.  These cases
model in RTL what is actually happening, compare in infinite precision
x from the result of finite precision addition in M mode and if it is
less than unsigned (i.e. overflow happened), carry is set.
Another use of CCCmode is in UNSPEC_* patterns, those are used with
(eq (reg:CCC flags) (const_int 0)) for carry set and ne for unset,
given the UNSPEC no big deal, the middle-end doesn't know what means
set or unset.
But for the bt{l,q}; j{c,nc} case the above splits it into
(set (reg:CCC flags) (compare:CCC (zero_extract) (const_int 0)))
for bt and
(set (pc) (if_then_else (eq (reg:CCC flags) (const_int 0)) (label_ref) 
(pc)))
for the bit set case (so that the jump expands to jc) and ne for
the bit not set case (so that the jump expands to jnc).
Similarly for the different splitters for cmov and set{c,nc} etc.
The problem is that when the middle-end reads this RTL, it feels
the exact opposite to it.  If zero_extract is 1, flags is set
to comparison of 1 and 0 and that would mean using ne ne in the
if_then_else, and vice versa.

So, in order to better describe in RTL what is actually happening,
one possibility would be to swap the behavior of put_condition_code
and use NE + LTU -> c and EQ + GEU -> nc rather than the current
EQ + LTU -> c and NE + GEU -> nc; and adjust everything.  The
following patch uses a more limited approach, instead of representing
bt{l,q}; j{c,nc} case as written above it uses
(set (reg:CCC flags) (compare:CCC (const_int 0) (zero_extract)))
and
(set (pc) (if_then_else (ltu (reg:CCC flags) (const_int 0)) (label_ref) 
(pc)))
which uses the existing put_condition_code but describes what the
insns actually do in RTL clearly.  If zero_extract is 1,
then flags are LTU, 0U < 1U, if zero_extract is 0, then flags are GEU,
0U >= 0U.  The patch adjusts the *bt define_insn and all the
splitters to it and its comparisons/conditional moves/setXX.

2025-02-10  Jakub Jelinek  

PR target/118623
* config/i386/i386.md (*bt): Represent bt as
compare:CCC of const0_rtx and zero_extract rather than
zero_extract and const0_rtx.
(*jcc_bt): Likewise.  Use LTU and GEU as flags test
instead of EQ and NE.
(*jcc_bt_1): Likewise.
(*jcc_bt_mask): Likewise.
(*jcc_bt_mask_1): Likewise.
(Help combine recogniz

[gcc r13-9696] alias: Perform offset arithmetics in poly_offset_int rather than poly_int64 [PR118819]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:b0502fbcee2a4eaf070f26201829478d8df51423

commit r13-9696-gb0502fbcee2a4eaf070f26201829478d8df51423
Author: Jakub Jelinek 
Date:   Thu Feb 27 08:48:18 2025 +0100

alias: Perform offset arithmetics in poly_offset_int rather than poly_int64 
[PR118819]

This PR is about ubsan error on the c - cx1 + cy1 evaluation in the first
hunk.

The following patch hopefully fixes that by doing the additions/subtractions
in poly_offset_int rather than poly_int64 and then converting back to 
poly_int64.
If it doesn't fit, -1 is returned (which means it is unknown if there is a 
conflict
or not).

2025-02-27  Jakub Jelinek  

PR middle-end/118819
* alias.cc (memrefs_conflict_p): Perform arithmetics on c, xsize and
ysize in poly_offset_int and return -1 if it is not representable in
poly_int64.

(cherry picked from commit b570f48c3dfb9ca3d640467cff67e569904009d4)

Diff:
---
 gcc/alias.cc | 68 ++--
 1 file changed, 57 insertions(+), 11 deletions(-)

diff --git a/gcc/alias.cc b/gcc/alias.cc
index 3672bf277b95..2ac46d207a58 100644
--- a/gcc/alias.cc
+++ b/gcc/alias.cc
@@ -2603,19 +2603,39 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 
ysize, rtx y,
return memrefs_conflict_p (xsize, x1, ysize, y1, c);
  if (poly_int_rtx_p (x1, &cx1))
{
+ poly_offset_int co = c;
+ co -= cx1;
  if (poly_int_rtx_p (y1, &cy1))
-   return memrefs_conflict_p (xsize, x0, ysize, y0,
-  c - cx1 + cy1);
+   {
+ co += cy1;
+ if (!co.to_shwi (&c))
+   return -1;
+ return memrefs_conflict_p (xsize, x0, ysize, y0, c);
+   }
+ else if (!co.to_shwi (&c))
+   return -1;
  else
-   return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
+   return memrefs_conflict_p (xsize, x0, ysize, y, c);
}
  else if (poly_int_rtx_p (y1, &cy1))
-   return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
+   {
+ poly_offset_int co = c;
+ co += cy1;
+ if (!co.to_shwi (&c))
+   return -1;
+ return memrefs_conflict_p (xsize, x, ysize, y0, c);
+   }
 
  return -1;
}
   else if (poly_int_rtx_p (x1, &cx1))
-   return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
+   {
+ poly_offset_int co = c;
+ co -= cx1;
+ if (!co.to_shwi (&c))
+   return -1;
+ return memrefs_conflict_p (xsize, x0, ysize, y, c);
+   }
 }
   else if (GET_CODE (y) == PLUS)
 {
@@ -2631,7 +2651,13 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 
ysize, rtx y,
 
   poly_int64 cy1;
   if (poly_int_rtx_p (y1, &cy1))
-   return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
+   {
+ poly_offset_int co = c;
+ co += cy1;
+ if (!co.to_shwi (&c))
+   return -1;
+ return memrefs_conflict_p (xsize, x, ysize, y0, c);
+   }
   else
return -1;
 }
@@ -2684,8 +2710,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 
ysize, rtx y,
  if (maybe_gt (xsize, 0))
xsize = -xsize;
  if (maybe_ne (xsize, 0))
-   xsize += sc + 1;
- c -= sc + 1;
+   {
+ poly_offset_int xsizeo = xsize;
+ xsizeo += sc + 1;
+ if (!xsizeo.to_shwi (&xsize))
+   return -1;
+   }
+ poly_offset_int co = c;
+ co -= sc + 1;
+ if (!co.to_shwi (&c))
+   return -1;
  return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
 ysize, y, c);
}
@@ -2699,8 +2733,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 
ysize, rtx y,
  if (maybe_gt (ysize, 0))
ysize = -ysize;
  if (maybe_ne (ysize, 0))
-   ysize += sc + 1;
- c += sc + 1;
+   {
+ poly_offset_int ysizeo = ysize;
+ ysizeo += sc + 1;
+ if (!ysizeo.to_shwi (&ysize))
+   return -1;
+   }
+ poly_offset_int co = c;
+ co += sc + 1;
+ if (!co.to_shwi (&c))
+   return -1;
  return memrefs_conflict_p (xsize, x,
 ysize, canon_rtx (XEXP (y, 0)), c);
}
@@ -2711,7 +2753,11 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 
ysize, rtx y,
   poly_int64 cx, cy;
   if (poly_int_rtx_p (x, &cx) && poly_int_rtx_p (y, &cy))
{
- c += cy - cx;
+ poly_offset_int co = c;
+ co += cy;
+ co -= cx;
+ if (!co.to_shwi (&c))
+   return -1;
  r

[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Sauvegarde code finalization

2025-05-26 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:acc34b33d1968cd74927f63a0103a07e5c980c8a

commit acc34b33d1968cd74927f63a0103a07e5c980c8a
Author: Mikael Morin 
Date:   Mon May 26 16:32:36 2025 +0200

Sauvegarde code finalization

Diff:
---
 gcc/fortran/class.cc  | 10 --
 gcc/fortran/trans-expr.cc |  9 +++--
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index f9a2c96f77d8..e6a99be93210 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -1622,7 +1622,6 @@ generate_finalization_wrapper (gfc_symbol *derived, 
gfc_namespace *ns,
   array->ts.u.derived = derived;
   array->attr.flavor = FL_VARIABLE;
   array->attr.dummy = 1;
-  array->attr.contiguous = 1;
   array->attr.dimension = 1;
   array->attr.artificial = 1;
   array->as = gfc_get_array_spec();
@@ -2125,8 +2124,15 @@ finish_assumed_rank:
   last_code->symtree = ancestor_wrapper->symtree;
   last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
 
+  gfc_expr *parent_type_array = gfc_lval_expr_from_sym (array);
+  gfc_ref **subref = &parent_type_array->ref;
+  if (*subref)
+   subref = &(*subref)->next;
+  insert_component_ref (&parent_type_array->ts, subref,
+   derived->components->name);
+
   last_code->ext.actual = gfc_get_actual_arglist ();
-  last_code->ext.actual->expr = gfc_lval_expr_from_sym (array);
+  last_code->ext.actual->expr = parent_type_array;
   last_code->ext.actual->next = gfc_get_actual_arglist ();
   last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride);
   last_code->ext.actual->next->next = gfc_get_actual_arglist ();
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 9845f7fe71d6..bd3f35245050 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -7546,7 +7546,10 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 
  else if (e->expr_type == EXPR_VARIABLE
&& is_subref_array (e)
-   && !(fsym && fsym->attr.pointer))
+   && !(fsym && fsym->attr.pointer)
+   && !(e->symtree->n.sym
+&& e->symtree->n.sym->as
+&& e->symtree->n.sym->as->type == AS_ASSUMED_RANK))
/* The actual argument is a component reference to an
   array of derived types.  In this case, the argument
   is converted to a temporary, which is passed and then
@@ -7591,7 +7594,9 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
   && (fsym->attr.target
   ? gfc_is_not_contiguous (e)
   : !gfc_is_simply_contiguous (e, false, true))
-  && gfc_expr_is_variable (e))
+  && gfc_expr_is_variable (e)
+  && !(e->symtree->n.sym->as
+   && e->symtree->n.sym->as->type == AS_ASSUMED_RANK))
{
  gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
 fsym->attr.intent,


[gcc r13-9692] doloop: Fix up doloop df use [PR116799]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:c1e55bcc1075aa74bebd7e1bb87d3939da2e498b

commit r13-9692-gc1e55bcc1075aa74bebd7e1bb87d3939da2e498b
Author: Jakub Jelinek 
Date:   Thu Dec 5 13:01:21 2024 +0100

doloop: Fix up doloop df use [PR116799]

The following testcases are miscompiled on s390x-linux, because the
doloop_optimize
  /* Ensure that the new sequence doesn't clobber a register that
 is live at the end of the block.  */
  {
bitmap modified = BITMAP_ALLOC (NULL);

for (rtx_insn *i = doloop_seq; i != NULL; i = NEXT_INSN (i))
  note_stores (i, record_reg_sets, modified);

basic_block loop_end = desc->out_edge->src;
bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified);
check doesn't work as intended.
The problem is that it uses df, but the df analysis was only done using
  iv_analysis_loop_init (loop);
->
  df_analyze_loop (loop);
which computes df inside on the bbs of the loop.
While loop_end bb is inside of the loop, df_get_live_out computed that
way includes registers set in the loop and used at the start of the next
iteration, but doesn't include registers set in the loop (or before the
loop) and used after the loop.

The following patch fixes that by doing whole function df_analyze first,
changes the loop iteration mode from 0 to LI_ONLY_INNERMOST (on many
targets which use can_use_doloop_if_innermost target hook a so are known
to only handle innermost loops) or LI_FROM_INNERMOST (I think only bfin
actually allows non-innermost loops) and checking not just
df_get_live_out (loop_end) (that is needed for something used by the
next iteration), but also df_get_live_in (desc->out_edge->dest),
i.e. what will be used after the loop.  df of such a bb shouldn't
be affected by the df_analyze_loop and so should be from df_analyze
of the whole function.

2024-12-05  Jakub Jelinek  

PR rtl-optimization/113994
PR rtl-optimization/116799
* loop-doloop.cc: Include targhooks.h.
(doloop_optimize): Also punt on intersection of modified
with df_get_live_in (desc->out_edge->dest).
(doloop_optimize_loops): Call df_analyze.  Use
LI_ONLY_INNERMOST or LI_FROM_INNERMOST instead of 0 as
second loops_list argument.

* gcc.c-torture/execute/pr116799.c: New test.
* g++.dg/torture/pr113994.C: New test.

(cherry picked from commit 0eed81612ad6eac2bec60286348a103d4dc02a5a)

Diff:
---
 gcc/loop-doloop.cc | 20 -
 gcc/testsuite/g++.dg/torture/pr113994.C| 31 +++
 gcc/testsuite/gcc.c-torture/execute/pr116799.c | 41 ++
 3 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/gcc/loop-doloop.cc b/gcc/loop-doloop.cc
index 4feb0a25ab93..d8a665fad7da 100644
--- a/gcc/loop-doloop.cc
+++ b/gcc/loop-doloop.cc
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "loop-unroll.h"
 #include "regs.h"
 #include "df.h"
+#include "targhooks.h"
 
 /* This module is used to modify loops with a determinable number of
iterations to use special low-overhead looping instructions.
@@ -770,6 +771,18 @@ doloop_optimize (class loop *loop)
 
 basic_block loop_end = desc->out_edge->src;
 bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified);
+/* iv_analysis_loop_init calls df_analyze_loop, which computes just
+   partial df for blocks of the loop only.  The above will catch if
+   any of the modified registers are use inside of the loop body, but
+   it will most likely not have accurate info on registers used
+   at the destination of the out_edge.  We call df_analyze on the
+   whole function at the start of the pass though and iterate only
+   on innermost loops or from innermost loops, so
+   live in on desc->out_edge->dest should be still unmodified from
+   the initial df_analyze.  */
+if (!fail)
+  fail = bitmap_intersect_p (df_get_live_in (desc->out_edge->dest),
+modified);
 BITMAP_FREE (modified);
 
 if (fail)
@@ -795,7 +808,12 @@ doloop_optimize_loops (void)
   df_live_set_all_dirty ();
 }
 
-  for (auto loop : loops_list (cfun, 0))
+  df_analyze ();
+
+  for (auto loop : loops_list (cfun,
+  targetm.can_use_doloop_p
+  == can_use_doloop_if_innermost
+  ? LI_ONLY_INNERMOST : LI_FROM_INNERMOST))
 doloop_optimize (loop);
 
   if (optimize == 1)
diff --git a/gcc/testsuite/g++.dg/torture/pr113994.C 
b/gcc/testsuite/g++.dg/torture/pr113994.C
new file mode 100644
index ..c9c186d45ee7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr113994.C
@@ -0,0 +1,31 @@
+// PR rtl-optimization/113994
+// { dg-do run }
+
+#include 
+

[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Simplification code finalization

2025-05-26 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:66e5dcba5f8713fa57e5857c079348379c6eff29

commit 66e5dcba5f8713fa57e5857c079348379c6eff29
Author: Mikael Morin 
Date:   Mon May 26 13:28:57 2025 +0200

Simplification code finalization

Diff:
---
 gcc/fortran/class.cc | 138 ++-
 1 file changed, 4 insertions(+), 134 deletions(-)

diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index e92760db51dd..f9a2c96f77d8 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -1477,148 +1477,18 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol 
*idx2, gfc_symbol *offset,
 
 static void
 finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
- gfc_symbol *array, gfc_symbol *byte_stride,
- gfc_symbol *nelem, gfc_symbol *is_contiguous,
- gfc_namespace *sub_ns)
+ gfc_symbol *array, gfc_symbol *byte_stride 
ATTRIBUTE_UNUSED,
+ gfc_symbol *nelem ATTRIBUTE_UNUSED, gfc_symbol 
*is_contiguous ATTRIBUTE_UNUSED,
+ gfc_namespace *sub_ns ATTRIBUTE_UNUSED)
 {
-  gfc_symbol *ptr2;
-  gfc_expr *size_expr, *expr;
-  gfc_namespace *ns;
-
-  block->next = gfc_get_code (EXEC_IF);
-  block = block->next;
-
-  block->block = gfc_get_code (EXEC_IF);
-  block = block->block;
-
-  /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE.  */
-  size_expr = gfc_get_expr ();
-  size_expr->where = gfc_current_locus;
-  size_expr->expr_type = EXPR_OP;
-  size_expr->value.op.op = INTRINSIC_DIVIDE;
-
-  /* STORAGE_SIZE (array,kind=c_intptr_t).  */
-  size_expr->value.op.op1
-   = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
-   "storage_size", gfc_current_locus, 2,
-   gfc_lval_expr_from_sym (array),
-   gfc_get_int_expr (gfc_index_integer_kind,
- NULL, 0));
-
-  /* NUMERIC_STORAGE_SIZE.  */
-  size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
- gfc_character_storage_size);
-  size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
-  size_expr->ts = size_expr->value.op.op1->ts;
-
-  /* IF condition: (stride == size_expr
-   && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
-   || is_contiguous)
-  || 0 == size_expr.  */
-  block->expr1 = gfc_get_expr ();
-  block->expr1->ts.type = BT_LOGICAL;
-  block->expr1->ts.kind = gfc_default_logical_kind;
-  block->expr1->expr_type = EXPR_OP;
-  block->expr1->where = gfc_current_locus;
-
-  block->expr1->value.op.op = INTRINSIC_OR;
-
-  /* byte_stride == size_expr */
-  expr = gfc_get_expr ();
-  expr->ts.type = BT_LOGICAL;
-  expr->ts.kind = gfc_default_logical_kind;
-  expr->expr_type = EXPR_OP;
-  expr->where = gfc_current_locus;
-  expr->value.op.op = INTRINSIC_EQ;
-  expr->value.op.op1
-   = gfc_lval_expr_from_sym (byte_stride);
-  expr->value.op.op2 = size_expr;
-
-  /* If strides aren't allowed (not assumed shape or CONTIGUOUS),
- add is_contiguous check.  */
-
-  if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE
-  || fini->proc_tree->n.sym->formal->sym->attr.contiguous)
-{
-  gfc_expr *expr2;
-  expr2 = gfc_get_expr ();
-  expr2->ts.type = BT_LOGICAL;
-  expr2->ts.kind = gfc_default_logical_kind;
-  expr2->expr_type = EXPR_OP;
-  expr2->where = gfc_current_locus;
-  expr2->value.op.op = INTRINSIC_AND;
-  expr2->value.op.op1 = expr;
-  expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous);
-  expr = expr2;
-}
-
-  block->expr1->value.op.op1 = expr;
-
-  /* 0 == size_expr */
-  block->expr1->value.op.op2 = gfc_get_expr ();
-  block->expr1->value.op.op2->ts.type = BT_LOGICAL;
-  block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind;
-  block->expr1->value.op.op2->expr_type = EXPR_OP;
-  block->expr1->value.op.op2->where = gfc_current_locus;
-  block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ;
-  block->expr1->value.op.op2->value.op.op1 =
-   gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
-  block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr);
-
   /* IF body: call final subroutine.  */
   block->next = gfc_get_code (EXEC_CALL);
-  block->next->symtree = fini->proc_tree;
-  block->next->resolved_sym = fini->proc_tree->n.sym;
-  block->next->ext.actual = gfc_get_actual_arglist ();
-  block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
-
-  /* ELSE.  */
-
-  block->block = gfc_get_code (EXEC_IF);
-  block = block->block;
-
-  /* BLOCK ... END BLOCK.  */
-  block->next = gfc_get_code (EXEC_BLOCK);
   block = block->next;
 
-  ns = gfc_build_block_ns (sub_ns);
-  block->ext.block.ns = ns;
-  block->ext.block.assoc = NULL;
-
-  gfc_get_symbol ("

[gcc r13-9698] c++: Fix explicit instantiation of const variable templates after earlier implicit instantation [PR1

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:5e72938390fb49549a38e5800b2c635c061b07d8

commit r13-9698-g5e72938390fb49549a38e5800b2c635c061b07d8
Author: Jakub Jelinek 
Date:   Wed Feb 28 23:20:13 2024 +0100

c++: Fix explicit instantiation of const variable templates after earlier 
implicit instantation [PR113976]

Already previously instantiated const variable templates had
cp_apply_type_quals_to_decl called when they were instantiated,
but if they need runtime initialization, their TREE_READONLY flag
has been subsequently cleared.
Explicit variable template instantiation calls grokdeclarator which
calls cp_apply_type_quals_to_decl on them again, setting TREE_READONLY
flag again, but nothing clears it afterwards, so we emit such
instantiations into rodata sections and segfault when the dynamic
initialization attempts to initialize them.

The following patch fixes that by not calling cp_apply_type_quals_to_decl
on already instantiated variable declarations.

2024-02-28  Jakub Jelinek  
Patrick Palka  

PR c++/113976
* decl.cc (grokdeclarator): Don't call cp_apply_type_quals_to_decl
on DECL_TEMPLATE_INSTANTIATED VAR_DECLs.

* g++.dg/cpp1y/var-templ87.C: New test.

(cherry picked from commit 29ac92436aa5c702e9e02c206e7590ebd806398e)

Diff:
---
 gcc/cp/decl.cc   |  7 +-
 gcc/testsuite/g++.dg/cpp1y/var-templ87.C | 43 
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index e49641680231..9a5f2ee87421 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -14858,7 +14858,12 @@ grokdeclarator (const cp_declarator *declarator,
 /* Record constancy and volatility on the DECL itself .  There's
no need to do this when processing a template; we'll do this
for the instantiated declaration based on the type of DECL.  */
-if (!processing_template_decl)
+if (!processing_template_decl
+   /* Don't do it for instantiated variable templates either,
+  cp_apply_type_quals_to_decl should have been called on it
+  already and might have been overridden in cp_finish_decl
+  if initializer needs runtime initialization.  */
+   && (!VAR_P (decl) || !DECL_TEMPLATE_INSTANTIATED (decl)))
   cp_apply_type_quals_to_decl (type_quals, decl);
 
 return decl;
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ87.C 
b/gcc/testsuite/g++.dg/cpp1y/var-templ87.C
new file mode 100644
index ..e62d06d172c5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/var-templ87.C
@@ -0,0 +1,43 @@
+// PR c++/113976
+// { dg-do run { target c++14 } }
+
+int
+foo ()
+{
+  return 42;
+}
+
+template 
+const int a = foo ();
+const int *b = &a <0>;
+template 
+const int c = foo ();
+template const int c <0>;
+template 
+const int d = foo ();
+const int *e = &d <0>;
+template const int d <0>;
+template 
+const int f = foo ();
+template const int f <0>;
+const int *g = &f <0>;
+struct S { int a, b; };
+template 
+const S h = { 42, foo () };
+const S *i = &h <0>;
+template 
+const S j =  { 42, foo () };
+template const S j <0>;
+template 
+const S k =  { 42, foo () };
+const S *l = &k <0>;
+template const S k <0>;
+template 
+const S m =  { 42, foo () };
+template const S m <0>;
+const S *n = &m <0>;
+
+int
+main ()
+{
+}


[gcc r13-9690] c++: vtable referring to "unavailable" virtual fn [PR116606]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:d0f2b0711f24238c5daefc97448d2f1b3a856359

commit r13-9690-gd0f2b0711f24238c5daefc97448d2f1b3a856359
Author: Marek Polacek 
Date:   Thu Sep 5 13:01:59 2024 -0400

c++: vtable referring to "unavailable" virtual fn [PR116606]

mark_vtable_entries already has

   /* It's OK for the vtable to refer to deprecated virtual functions.  */
   warning_sentinel w(warn_deprecated_decl);

but that doesn't cover __attribute__((unavailable)).  We can use the
following override to cover both.

PR c++/116606

gcc/cp/ChangeLog:

* decl2.cc (mark_vtable_entries): Temporarily override 
deprecated_state to
UNAVAILABLE_DEPRECATED_SUPPRESS.  Remove a warning_sentinel.

gcc/testsuite/ChangeLog:

* g++.dg/ext/attr-unavailable-13.C: New test.

(cherry picked from commit d9d34f9a91371dea4bab0b54b2d7f762a6cc23e0)

Diff:
---
 gcc/cp/decl2.cc| 3 ++-
 gcc/testsuite/g++.dg/ext/attr-unavailable-13.C | 8 
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 89c64277b5d6..fb2241b48133 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -2075,7 +2075,8 @@ static void
 mark_vtable_entries (tree decl, vec &consteval_vtables)
 {
   /* It's OK for the vtable to refer to deprecated virtual functions.  */
-  warning_sentinel w(warn_deprecated_decl);
+  auto du = make_temp_override (deprecated_state,
+   UNAVAILABLE_DEPRECATED_SUPPRESS);
 
   bool consteval_seen = false;
 
diff --git a/gcc/testsuite/g++.dg/ext/attr-unavailable-13.C 
b/gcc/testsuite/g++.dg/ext/attr-unavailable-13.C
new file mode 100644
index ..9ca400054190
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attr-unavailable-13.C
@@ -0,0 +1,8 @@
+// PR c++/116606
+// { dg-do compile }
+
+struct C {
+__attribute__((unavailable)) virtual void f() {}
+};
+
+C c;


[gcc r16-881] OpenMP/C++: Avoid ICE for BIND_EXPR with empty BIND_EXPR_BLOCK [PR120413]

2025-05-26 Thread Tobias Burnus via Gcc-cvs
https://gcc.gnu.org/g:45b849d05b733a25ec7ce612229084b8f4b86d3d

commit r16-881-g45b849d05b733a25ec7ce612229084b8f4b86d3d
Author: Tobias Burnus 
Date:   Mon May 26 17:58:07 2025 +0200

OpenMP/C++: Avoid ICE for BIND_EXPR with empty BIND_EXPR_BLOCK [PR120413]

PR c++/120413

gcc/cp/ChangeLog:

* semantics.cc (finish_omp_target_clauses_r): Handle
BIND_EXPR with empty BIND_EXPR_BLOCK.

gcc/testsuite/ChangeLog:

* g++.dg/gomp/target-4.C: New test.

Diff:
---
 gcc/cp/semantics.cc  |  8 
 gcc/testsuite/g++.dg/gomp/target-4.C | 22 ++
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 43a0eabfa127..ef4a668a4e4d 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -10565,10 +10565,10 @@ finish_omp_target_clauses_r (tree *tp, int 
*walk_subtrees, void *ptr)
 
   if (TREE_CODE (t) == BIND_EXPR)
 {
-  tree block = BIND_EXPR_BLOCK (t);
-  for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
-   if (!data->local_decls.contains (var))
- data->local_decls.add (var);
+  if (tree block = BIND_EXPR_BLOCK (t))
+   for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
+ if (!data->local_decls.contains (var))
+   data->local_decls.add (var);
   return NULL_TREE;
 }
 
diff --git a/gcc/testsuite/g++.dg/gomp/target-4.C 
b/gcc/testsuite/g++.dg/gomp/target-4.C
new file mode 100644
index ..80fc9dfe9365
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/target-4.C
@@ -0,0 +1,22 @@
+// { dg-do compile { target c++11 } }
+// PR c++/120413
+
+struct S
+{
+  S() {}
+  ~S() {}
+};
+
+struct array
+{
+  S _arr[1];
+};
+
+int main()
+{
+#pragma omp target
+  {
+array arr{};
+  }
+  return 0;
+}


[gcc r16-882] libstdc++: Run in_place constructor test for std::indirect [PR119152]

2025-05-26 Thread Tomasz Kaminski via Gcc-cvs
https://gcc.gnu.org/g:97e8cd9295dadad32fb5866e96cb7e403c1d993d

commit r16-882-g97e8cd9295dadad32fb5866e96cb7e403c1d993d
Author: Tomasz Kamiński 
Date:   Mon May 26 17:35:08 2025 +0200

libstdc++: Run in_place constructor test for std::indirect [PR119152]

In indirect/ctor.cc test_inplace_ctor function was defined, but never
called.

PR libstdc++/119152

libstdc++-v3/ChangeLog:

* testsuite/std/memory/indirect/ctor.cc: Run test_inplace_ctor.

Diff:
---
 libstdc++-v3/testsuite/std/memory/indirect/ctor.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc 
b/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc
index 67e7a8aba037..124874d02fe6 100644
--- a/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc
+++ b/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc
@@ -139,7 +139,6 @@ test_inplace_ctor()
 
   std::indirect> i5(std::in_place);
   VERIFY( i5->size() == 0 );
-  VERIFY( i5->at(0) == 13 );
 
   std::indirect> i6(std::in_place, 5, 13);
   VERIFY( i6->size() == 5 );
@@ -194,10 +193,12 @@ int main()
 {
   test_default_ctor();
   test_forwarding_ctor();
+  test_inplace_ctor();
 
   static_assert([] {
 test_default_ctor();
 test_forwarding_ctor();
+test_inplace_ctor();
 return true;
   });
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] gimple-exec: réutilisation decompose_ref

2025-05-26 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:630d555a49b2b503b7cfb5c3bcdcd374d9cacf14

commit 630d555a49b2b503b7cfb5c3bcdcd374d9cacf14
Author: Mikael Morin 
Date:   Mon May 26 11:13:56 2025 +0200

gimple-exec: réutilisation decompose_ref

Diff:
---
 gcc/cgraphunit.cc | 71 ---
 1 file changed, 15 insertions(+), 56 deletions(-)

diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
index 97013daa9fbd..40b1af804be9 100644
--- a/gcc/cgraphunit.cc
+++ b/gcc/cgraphunit.cc
@@ -3850,6 +3850,8 @@ exec_context::evaluate (tree expr) const
 {
 case ARRAY_REF:
 case COMPONENT_REF:
+case MEM_REF:
+case TARGET_MEM_REF:
   {
data_storage *storage = nullptr;
int offset = -1;
@@ -3871,54 +3873,6 @@ exec_context::evaluate (tree expr) const
   }
   break;
 
-case MEM_REF:
-case TARGET_MEM_REF:
-  {
-   tree ptr = TREE_OPERAND (expr, 0);
-   data_value val_ptr = evaluate (ptr);
-   gcc_assert (val_ptr.classify () == VAL_ADDRESS);
-   storage_address *address = val_ptr.get_address ();
-   gcc_assert (address != nullptr);
-   data_value storage_value = address->storage.get ().get_value ();
-   wide_int ptr_off = wi::uhwi (address->offset,
-HOST_BITS_PER_WIDE_INT);
-
-   tree offset_bytes = TREE_OPERAND (expr, 1);
-   data_value val_off = evaluate (offset_bytes);
-   gcc_assert (val_off.classify () == VAL_CONSTANT);
-   wide_int wi_off = val_off.get_cst ();
-
-   unsigned bit_width;
-   if (!get_constant_type_size (TREE_TYPE (expr), bit_width))
- gcc_unreachable ();
-
-   if (code == TARGET_MEM_REF)
- {
-   tree index = TREE_OPERAND (expr, 2);
-   tree step = TREE_OPERAND (expr, 3);
-   if (index || step)
- {
-   gcc_assert (index && step);
-
-   data_value val_idx = evaluate (index);
-   gcc_assert (val_idx.classify () == VAL_CONSTANT);
-   wide_int wi_idx = val_idx.get_cst ();
-
-   data_value val_step = evaluate (step);
-   gcc_assert (val_step.classify () == VAL_CONSTANT);
-   wide_int wi_step = val_step.get_cst ();
-
-   wi_off += wi_idx * wi_step;
- }
- }
-
-   wi_off = wi_off * CHAR_BIT + ptr_off;
-   gcc_assert (wi::fits_uhwi_p (wi_off));
-
-   return storage_value.get_at (wi_off.to_shwi (), bit_width);
-  }
-  break;
-
 case INTEGER_CST:
   {
data_value result (TREE_TYPE (expr));
@@ -4288,15 +4242,20 @@ exec_context::decompose_ref (tree data_ref, 
data_storage * & storage, int & offs
if (code == TARGET_MEM_REF)
  {
tree index = TREE_OPERAND (data_ref, 2);
-   data_value idx_val = evaluate (index);
-   gcc_assert (idx_val.classify () == VAL_CONSTANT);
-   add_index = idx_val.get_cst ();
-
tree step = TREE_OPERAND (data_ref, 3);
-   data_value step_val = evaluate (step);
-   gcc_assert (step_val.classify () == VAL_CONSTANT);
-   add_multiplier = step_val.get_cst ();
-   add_multiplier *= CHAR_BIT;
+   if (index || step)
+ {
+   gcc_assert (index && step);
+
+   data_value idx_val = evaluate (index);
+   gcc_assert (idx_val.classify () == VAL_CONSTANT);
+   add_index = idx_val.get_cst ();
+
+   data_value step_val = evaluate (step);
+   gcc_assert (step_val.classify () == VAL_CONSTANT);
+   add_multiplier = step_val.get_cst ();
+   add_multiplier *= CHAR_BIT;
+ }
  }
  }
  break;


[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régression assign_10

2025-05-26 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:f3275b34704c8463bdfeecc0f0dffa838d8db986

commit f3275b34704c8463bdfeecc0f0dffa838d8db986
Author: Mikael Morin 
Date:   Mon May 26 18:52:29 2025 +0200

Correction régression assign_10

Diff:
---
 gcc/fortran/trans-array.cc  | 2 +-
 gcc/testsuite/gfortran.dg/assign_10.f90 | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 264abd407b46..11a203e474b8 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -3518,7 +3518,7 @@ conv_array_index (gfc_se * se, gfc_ss * ss, int dim, int 
i, gfc_array_ref * ar)
  index = gfc_build_array_ref (data, index,
   non_negative_strides_array_p (desc),
   se->loop->from[i],
-  gfc_conv_array_spacing (desc, 0));
+  
info->subscript[dim]->info->data.array.spacing[0]);
  index = gfc_evaluate_now (index, &se->pre);
  index = fold_convert (gfc_array_index_type, index);
 
diff --git a/gcc/testsuite/gfortran.dg/assign_10.f90 
b/gcc/testsuite/gfortran.dg/assign_10.f90
index c207f9e5e2b4..965e91c66bb2 100644
--- a/gcc/testsuite/gfortran.dg/assign_10.f90
+++ b/gcc/testsuite/gfortran.dg/assign_10.f90
@@ -23,5 +23,5 @@ end
 ! cases will all yield a temporary, so that atmp appears 18 times.
 ! Note that it is the kind conversion that generates the temp.
 !
-! { dg-final { scan-tree-dump-times "parm" 20 "original" } }
+! { dg-final { scan-tree-dump-times "parm" 18 "original" } }
 ! { dg-final { scan-tree-dump-times "atmp" 20 "original" } }


[gcc r15-9729] OpenMP/C++: Avoid ICE for BIND_EXPR with empty BIND_EXPR_BLOCK [PR120413]

2025-05-26 Thread Tobias Burnus via Gcc-cvs
https://gcc.gnu.org/g:9c8e20a8425f123abd54261d03af5a956d4d01c6

commit r15-9729-g9c8e20a8425f123abd54261d03af5a956d4d01c6
Author: Tobias Burnus 
Date:   Mon May 26 17:58:07 2025 +0200

OpenMP/C++: Avoid ICE for BIND_EXPR with empty BIND_EXPR_BLOCK [PR120413]

PR c++/120413

gcc/cp/ChangeLog:

* semantics.cc (finish_omp_target_clauses_r): Handle
BIND_EXPR with empty BIND_EXPR_BLOCK.

gcc/testsuite/ChangeLog:

* g++.dg/gomp/target-4.C: New test.

(cherry picked from commit 45b849d05b733a25ec7ce612229084b8f4b86d3d)

Diff:
---
 gcc/cp/semantics.cc  |  8 
 gcc/testsuite/g++.dg/gomp/target-4.C | 22 ++
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index a10ef34383c2..804c22d4661a 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -10543,10 +10543,10 @@ finish_omp_target_clauses_r (tree *tp, int 
*walk_subtrees, void *ptr)
 
   if (TREE_CODE (t) == BIND_EXPR)
 {
-  tree block = BIND_EXPR_BLOCK (t);
-  for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
-   if (!data->local_decls.contains (var))
- data->local_decls.add (var);
+  if (tree block = BIND_EXPR_BLOCK (t))
+   for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
+ if (!data->local_decls.contains (var))
+   data->local_decls.add (var);
   return NULL_TREE;
 }
 
diff --git a/gcc/testsuite/g++.dg/gomp/target-4.C 
b/gcc/testsuite/g++.dg/gomp/target-4.C
new file mode 100644
index ..80fc9dfe9365
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/target-4.C
@@ -0,0 +1,22 @@
+// { dg-do compile { target c++11 } }
+// PR c++/120413
+
+struct S
+{
+  S() {}
+  ~S() {}
+};
+
+struct array
+{
+  S _arr[1];
+};
+
+int main()
+{
+#pragma omp target
+  {
+array arr{};
+  }
+  return 0;
+}


[gcc r15-9730] libgomp.c-c++-common/metadirective-1.c: Expect 'error:' for nvptx compile [PR118694]

2025-05-26 Thread Tobias Burnus via Gcc-cvs
https://gcc.gnu.org/g:cf619d4a366ad428421fdb7ad617b4749799cf93

commit r15-9730-gcf619d4a366ad428421fdb7ad617b4749799cf93
Author: Tobias Burnus 
Date:   Fri May 23 11:30:48 2025 +0200

libgomp.c-c++-common/metadirective-1.c: Expect 'error:' for nvptx compile 
[PR118694]

OpenMP's 'target teams' is strictly coupled with 'teams'; if the latter
exists, the kernel is launched in directly with multiple teams. Thus,
the host has to know whether the teams construct exists or not. For

   #pragma omp target
 #pragma omp metadirective when (device={arch("nvptx")}: teams loop)

it is simple when 'nvptx' offloading is not supported, otherwise it depends
on the default device at runtime as the user code asks for a single team for
host fallback and gcn offload and multiple for nvptx offload.

In any case, this commit ensures that no FAIL is printed, whatever a
future solution might look like. Instead of a dg-bogus combined with an
'xfail offload_target_nvptx', one an also argue that a dg-error for
'target offload_target_nvptx' would be more appropriate.

libgomp/ChangeLog:

PR middle-end/118694
* testsuite/libgomp.c-c++-common/metadirective-1.c: xfail when
compiling (also) for nvptx offloading as an error is then expected.

(cherry picked from commit b3d07ec7ac2ccd935a79b29e1a0e2eb16225286a)

Diff:
---
 libgomp/testsuite/libgomp.c-c++-common/metadirective-1.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libgomp/testsuite/libgomp.c-c++-common/metadirective-1.c 
b/libgomp/testsuite/libgomp.c-c++-common/metadirective-1.c
index a57d6fd56714..fbe4ac3a954e 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/metadirective-1.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/metadirective-1.c
@@ -1,4 +1,5 @@
-/* { dg-do run } */
+/* { dg-do run { target { ! offload_target_nvptx } } } */
+/* { dg-do compile { target offload_target_nvptx } } */
 
 #define N 100
 
@@ -7,12 +8,17 @@ f (int x[], int y[], int z[])
 {
   int i;
 
+  // The following fails as on the host the target side cannot be
+  // resolved - and the 'teams' or not status affects how 'target'
+  // is called.
+  // Note also the dg-do compile above for offload_target_nvptx
   #pragma omp target map(to: x[0:N], y[0:N]) map(from: z[0:N])
 #pragma omp metadirective \
when (device={arch("nvptx")}: teams loop) \
default (parallel loop)
   for (i = 0; i < N; i++)
z[i] = x[i] * y[i];
+  /* { dg-bogus "'target' construct with nested 'teams' construct contains 
directives outside of the 'teams' construct" "PR118694" { xfail 
offload_target_nvptx } .-6 }  */
 }
 
 int


[gcc r13-9693] gimple-fold: Avoid ICEs with bogus declarations like const attribute no snprintf [PR117358]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:65724317b26eb16a3cd7279aacd68f4c85b355c0

commit r13-9693-g65724317b26eb16a3cd7279aacd68f4c85b355c0
Author: Jakub Jelinek 
Date:   Thu Nov 28 10:51:16 2024 +0100

gimple-fold: Avoid ICEs with bogus declarations like const attribute no 
snprintf [PR117358]

When one puts incorrect const or pure attributes on declarations of various
C APIs which have corresponding builtins (vs. what they actually do), we can
get tons of ICEs in gimple-fold.cc.

The following patch fixes it by giving up gimple_fold_builtin_* folding
if the functions don't have gimple_vdef (or for pure functions like
bcmp/strchr/strstr gimple_vuse) when in SSA form (during gimplification
they will surely have both of those NULL even when declared correctly,
yet it is highly desirable to fold them).

Or shall I replace
!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)
tests with
(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE | ECF_NOVOPS)) != 0
and
!gimple_vuse (stmt) && gimple_in_ssa_p (cfun)
with
(gimple_call_flags (stmt) & (ECF_CONST | ECF_NOVOPS)) != 0
?

2024-11-28  Jakub Jelinek  

PR tree-optimization/117358
* gimple-fold.cc (gimple_fold_builtin_memory_op): Punt if stmt has 
no
vdef in ssa form.
(gimple_fold_builtin_bcmp): Punt if stmt has no vuse in ssa form.
(gimple_fold_builtin_bcopy): Punt if stmt has no vdef in ssa form.
(gimple_fold_builtin_bzero): Likewise.
(gimple_fold_builtin_memset): Likewise.  Use return false instead of
return NULL_TREE.
(gimple_fold_builtin_strcpy): Punt if stmt has no vdef in ssa form.
(gimple_fold_builtin_strncpy): Likewise.
(gimple_fold_builtin_strchr): Punt if stmt has no vuse in ssa form.
(gimple_fold_builtin_strstr): Likewise.
(gimple_fold_builtin_strcat): Punt if stmt has no vdef in ssa form.
(gimple_fold_builtin_strcat_chk): Likewise.
(gimple_fold_builtin_strncat): Likewise.
(gimple_fold_builtin_strncat_chk): Likewise.
(gimple_fold_builtin_string_compare): Likewise.
(gimple_fold_builtin_fputs): Likewise.
(gimple_fold_builtin_memory_chk): Likewise.
(gimple_fold_builtin_stxcpy_chk): Likewise.
(gimple_fold_builtin_stxncpy_chk): Likewise.
(gimple_fold_builtin_stpcpy): Likewise.
(gimple_fold_builtin_snprintf_chk): Likewise.
(gimple_fold_builtin_sprintf_chk): Likewise.
(gimple_fold_builtin_sprintf): Likewise.
(gimple_fold_builtin_snprintf): Likewise.
(gimple_fold_builtin_fprintf): Likewise.
(gimple_fold_builtin_printf): Likewise.
(gimple_fold_builtin_realloc): Likewise.

* gcc.c-torture/compile/pr117358.c: New test.

(cherry picked from commit 29032dfa57629d1713a97b17a785273823993a91)

Diff:
---
 gcc/gimple-fold.cc | 76 --
 gcc/testsuite/gcc.c-torture/compile/pr117358.c | 17 ++
 2 files changed, 77 insertions(+), 16 deletions(-)

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index b5f4a9ec0a1c..180817cc8680 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -938,6 +938,8 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
}
   goto done;
 }
+  else if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+return false;
   else
 {
   /* We cannot (easily) change the type of the copy if it is a storage
@@ -1376,6 +1378,8 @@ gimple_fold_builtin_bcmp (gimple_stmt_iterator *gsi)
   /* Transform bcmp (a, b, len) into memcmp (a, b, len).  */
 
   gimple *stmt = gsi_stmt (*gsi);
+  if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun))
+return false;
   tree a = gimple_call_arg (stmt, 0);
   tree b = gimple_call_arg (stmt, 1);
   tree len = gimple_call_arg (stmt, 2);
@@ -1402,6 +1406,8 @@ gimple_fold_builtin_bcopy (gimple_stmt_iterator *gsi)
  len) into memmove (dest, src, len).  */
 
   gimple *stmt = gsi_stmt (*gsi);
+  if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+return false;
   tree src = gimple_call_arg (stmt, 0);
   tree dest = gimple_call_arg (stmt, 1);
   tree len = gimple_call_arg (stmt, 2);
@@ -1427,6 +1433,8 @@ gimple_fold_builtin_bzero (gimple_stmt_iterator *gsi)
   /* Transform bzero (dest, len) into memset (dest, 0, len).  */
 
   gimple *stmt = gsi_stmt (*gsi);
+  if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+return false;
   tree dest = gimple_call_arg (stmt, 0);
   tree len = gimple_call_arg (stmt, 1);
 
@@ -1456,6 +1464,9 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, 
tree c, tree len)
   return true;
 }
 
+  if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun))
+return false;
+
   if (! tree_fits_uhwi_p (len))
 return false;
 
@@ -1477,20 +1488,20 @@ gimple_fold_bu

[gcc r16-883] c-c++-common/gomp/{attrs-, }metadirective-3.c: Fix expected result [PR118694]

2025-05-26 Thread Tobias Burnus via Gcc-cvs
https://gcc.gnu.org/g:5d6ed6d604ff949b650e48fa4eaed3ec8b6489c1

commit r16-883-g5d6ed6d604ff949b650e48fa4eaed3ec8b6489c1
Author: Tobias Burnus 
Date:   Mon May 26 19:50:40 2025 +0200

c-c++-common/gomp/{attrs-,}metadirective-3.c: Fix expected result [PR118694]

With compilation for nvptx enabled, two issues showed up:
(a) "error: 'target' construct with nested 'teams' construct contains
 directives outside of the 'teams' construct"
See PR comment 9 why this is difficult to fix.
Solution: Add dg-bogus and accept/expect the error for 'target 
offload_nvptx'.

(b) The assumptions about the dump for 'target offload_nvptx' were wrong
as the metadirective was already expanded to a OMP_NEXT_VARIANT
construct such that no 'omp metadirective' was left in either case.
Solution: Check that no 'omp metadirective' is left; additionally, expect
either OMP_NEXT_VARIANT (when offload_nvptx is available) or no 'teams'
directive at all (if not).

gcc/testsuite/ChangeLog:

PR middle-end/118694
* c-c++-common/gomp/attrs-metadirective-3.c: Change to never
expect 'omp metadirective' in the dump. If !offload_nvptx, check
that no 'teams' shows up in the dump; for offload_nvptx, expect
OMP_NEXT_VARIANT and an error about directive between 'target'
and 'teams'.
* c-c++-common/gomp/metadirective-3.c: Likewise.

Diff:
---
 gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c | 7 ---
 gcc/testsuite/c-c++-common/gomp/metadirective-3.c   | 7 ---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c 
b/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c
index 31dd054922fc..803bf0ad1ebf 100644
--- a/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c
+++ b/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c
@@ -9,7 +9,7 @@ f (int x[], int y[], int z[])
 {
   int i;
 
-  [[omp::sequence (directive (target map(to: x, y) map(from: z)),
+  [[omp::sequence (directive (target map(to: x, y) map(from: z)),  /* { 
dg-bogus "'target' construct with nested 'teams' construct contains directives 
outside of the 'teams' construct" "PR118694" { xfail offload_nvptx } }  */ 
   directive (metadirective
  when (device={arch("nvptx")}: teams loop)
  default (parallel loop)))]]
@@ -20,5 +20,6 @@ f (int x[], int y[], int z[])
 /* If offload device "nvptx" isn't supported, the front end can eliminate
that alternative and not produce a metadirective at all.  Otherwise this
won't be resolved until late.  */
-/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" { 
target { ! offload_nvptx } } } } */
-/* { dg-final { scan-tree-dump "#pragma omp metadirective" "gimple" { target { 
offload_nvptx } } } } */
+/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" } } */
+/* { dg-final { scan-tree-dump-not " teams" "gimple" { target { ! 
offload_nvptx } } } } */
+/* { dg-final { scan-tree-dump "variant.\[0-9\]+ = \\\[omp_next_variant\\\] 
OMP_NEXT_VARIANT <0,\[\r\n \]+construct context = 14\[\r\n \]+1: device = 
\\{arch \\(.nvptx.\\)\\}\[\r\n \]+2: >;" "gimple" { target { offload_nvptx } } 
} } */
diff --git a/gcc/testsuite/c-c++-common/gomp/metadirective-3.c 
b/gcc/testsuite/c-c++-common/gomp/metadirective-3.c
index 0ac0d1d329d8..b6c1601f7b10 100644
--- a/gcc/testsuite/c-c++-common/gomp/metadirective-3.c
+++ b/gcc/testsuite/c-c++-common/gomp/metadirective-3.c
@@ -8,7 +8,7 @@ f (int x[], int y[], int z[])
 {
   int i;
 
-  #pragma omp target map(to: x, y) map(from: z)
+  #pragma omp target map(to: x, y) map(from: z)  /* { dg-bogus "'target' 
construct with nested 'teams' construct contains directives outside of the 
'teams' construct" "PR118694" { xfail offload_nvptx } }  */ 
 #pragma omp metadirective \
when (device={arch("nvptx")}: teams loop) \
default (parallel loop)
@@ -19,5 +19,6 @@ f (int x[], int y[], int z[])
 /* If offload device "nvptx" isn't supported, the front end can eliminate
that alternative and not produce a metadirective at all.  Otherwise this
won't be resolved until late.  */
-/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" { 
target { ! offload_nvptx } } } } */
-/* { dg-final { scan-tree-dump "#pragma omp metadirective" "gimple" { target { 
offload_nvptx } } } } */
+/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" } } */
+/* { dg-final { scan-tree-dump-not " teams" "gimple" { target { ! 
offload_nvptx } } } } */
+/* { dg-final { scan-tree-dump "variant.\[0-9\]+ = \\\[omp_next_variant\\\] 
OMP_NEXT_VARIANT <0,\[\r\n \]+construct context = 14\[\r\n \]+1: device = 
\\{arch \\(.nvptx.\\)\\}\[\r\n \]+2: >;" "gimple" { target { offload_nvptx } } 
} } */


[gcc/devel/omp/gcc-15] Merge branch 'releases/gcc-15' into devel/omp/gcc-15

2025-05-26 Thread Tobias Burnus via Libstdc++-cvs
https://gcc.gnu.org/g:499d610ac358f9b8dd3f788c6728f05ecea7c3e3

commit 499d610ac358f9b8dd3f788c6728f05ecea7c3e3
Merge: e841798c07dc d390c7e5bd03
Author: Tobias Burnus 
Date:   Mon May 26 19:59:34 2025 +0200

Merge branch 'releases/gcc-15' into devel/omp/gcc-15

Merge up to r15-9731-gd390c7e5bd0349 (26th May 2025)

Diff:

 gcc/ChangeLog  |  32 ++
 gcc/DATESTAMP  |   2 +-
 gcc/cgraph.cc  |   2 +-
 gcc/cgraph.h   |   2 +-
 gcc/cgraphclones.cc|   4 +-
 gcc/config/microblaze/microblaze.cc|   4 +
 gcc/cp/ChangeLog   |  35 ++
 gcc/cp/decl2.cc|   3 +-
 gcc/cp/module.cc   |   3 +-
 gcc/cp/semantics.cc|   8 +-
 gcc/fortran/ChangeLog  |  19 
 gcc/fortran/dependency.cc  |   6 +-
 gcc/fortran/resolve.cc |   8 +-
 gcc/ipa-cp.cc  |   2 +-
 gcc/ipa-sra.cc |   2 +-
 gcc/symtab.cc  |   4 +-
 gcc/testsuite/ChangeLog|  79 +
 .../c-c++-common/gomp/attrs-metadirective-3.c  |   7 +-
 gcc/testsuite/c-c++-common/gomp/metadirective-3.c  |   7 +-
 gcc/testsuite/g++.dg/gomp/target-4.C   |  22 
 .../g++.dg/modules/{pr113292_a.H => tls-1_a.H} |   0
 .../g++.dg/modules/{pr113292_b.C => tls-1_b.C} |   2 +-
 .../g++.dg/modules/{pr113292_c.C => tls-1_c.C} |   2 +-
 gcc/testsuite/g++.dg/modules/tls-2_a.C |  12 ++
 gcc/testsuite/g++.dg/modules/tls-2_b.C |   5 +
 gcc/testsuite/g++.dg/modules/tls-2_c.C |  11 ++
 gcc/testsuite/g++.dg/modules/tls-3.h   |  42 +++
 gcc/testsuite/g++.dg/modules/tls-3_a.H |   4 +
 gcc/testsuite/g++.dg/modules/tls-3_b.C |   4 +
 gcc/testsuite/g++.dg/modules/using-31_a.C  |  18 +++
 gcc/testsuite/g++.dg/modules/using-31_b.C  |   5 +
 gcc/testsuite/gcc.dg/ipa/pr120044-1.c  |  17 +++
 gcc/testsuite/gcc.dg/ipa/pr120044-2.c  |  17 +++
 gcc/testsuite/gcc.dg/tree-ssa/pr114864.c   |  15 +++
 .../gfortran.dg/alloc_comp_auto_array_3.f90|   4 +-
 gcc/testsuite/gfortran.dg/alloc_comp_class_3.f03   |   3 +-
 gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03   |   5 +-
 .../gfortran.dg/allocate_with_source_14.f03|   2 +-
 .../gfortran.dg/derived_constructor_comps_6.f90|   2 +-
 gcc/testsuite/gfortran.dg/derived_result_5.f90 | 123 +
 .../gfortran.dg/transfer_array_subref.f90  |  48 
 gcc/tree-sra.cc|   4 +-
 .../libgomp.c-c++-common/metadirective-1.c |   8 +-
 libstdc++-v3/ChangeLog |  12 ++
 44 files changed, 577 insertions(+), 39 deletions(-)


[gcc/devel/omp/gcc-15] (17 commits) Merge branch 'releases/gcc-15' into devel/omp/gcc-15

2025-05-26 Thread Tobias Burnus via Gcc-cvs
The branch 'devel/omp/gcc-15' was updated to point to:

 499d610ac358... Merge branch 'releases/gcc-15' into devel/omp/gcc-15

It previously pointed to:

 e841798c07dc... ChangeLog.omp bump

Diff:

Summary of changes (added commits):
---

  499d610... Merge branch 'releases/gcc-15' into devel/omp/gcc-15
  d390c7e... c-c++-common/gomp/{attrs-,}metadirective-3.c: Fix expected  (*)
  cf619d4... libgomp.c-c++-common/metadirective-1.c: Expect 'error:' for (*)
  9c8e20a... OpenMP/C++: Avoid ICE for BIND_EXPR with empty BIND_EXPR_BL (*)
  afa69f8... Daily bump. (*)
  4ac1fb5... MicroBlaze does not support speculative execution (CVE-2017 (*)
  65c2baf... Daily bump. (*)
  18f937f... Daily bump. (*)
  a8f62a9... c++/modules: Fix merge of TLS init functions [PR120363] (*)
  2486d94... c++/modules: Fix stream-in of member using-decls [PR120414] (*)
  fd2a11e... Daily bump. (*)
  6fb3dd1... Fortran: default-initialization and functions returning der (*)
  8c4b236... Daily bump. (*)
  7e58022... Daily bump. (*)
  6683c72... Fortran: fix passing of inquiry ref of complex array to TRA (*)
  c1db46f... tree-sra: Do not create stores into const aggregates (PR111 (*)
  76d16fb... ipa: Dump cgraph_node UID instead of order into ipa-clones  (*)

(*) This commit already exists in another branch.
Because the reference `refs/heads/devel/omp/gcc-15' matches
your hooks.email-new-commits-only configuration,
no separate email is sent for this commit.


[gcc r13-9688] s390: Fix tf_to_fprx2

2025-05-26 Thread Stefan Schulze Frielinghaus via Gcc-cvs
https://gcc.gnu.org/g:a0fe50437ec2e207876a489ce0fdd4d35aeeebb0

commit r13-9688-ga0fe50437ec2e207876a489ce0fdd4d35aeeebb0
Author: Stefan Schulze Frielinghaus 
Date:   Wed May 14 09:22:00 2025 +0200

s390: Fix tf_to_fprx2

Insn tf_to_fprx2 moves a TF value into a floating-point register pair.
For alternative 0, the input is a vector register, however, in the else
case instruction ldr is emitted which expects floating-point register
operands only.  Thus, this works only for vector registers which overlap
with floating-point registers.  Replace ldr with vlr so that the
remaining vector registers are dealt with, too.  Emitting a vlr instead
of a ldr is fine since the destination register %v0 is part of a
floating-point register pair which means that the low half of %v0 is
ignored in the end anyway and therefore may be clobbered.

gcc/ChangeLog:

* config/s390/vector.md: Fix tf_to_fprx2 by using vlr instead of
ldr.

(cherry picked from commit 8519b8ba9dd9567a5f90966351c1e758dbf511a4)

Diff:
---
 gcc/config/s390/vector.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 8cf39e0cd4b6..b65b3ee88d14 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -936,7 +936,7 @@
   else
{
  reg_pair += 2;  // get rid of prefix %f
- snprintf (buf, sizeof (buf), 
"ldr\t%%f0,%%f1;vpdi\tv%s,%%v1,v%s,5", reg_pair, reg_pair);
+ snprintf (buf, sizeof (buf), 
"vlr\t%%v0,%%v1;vpdi\tv%s,%%v1,v%s,5", reg_pair, reg_pair);
  output_asm_insn (buf, operands);
  return "";
}


[gcc r13-9694] cselib: For CALL_INSNs to const/pure fns invalidate memory below sp [PR117239]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:af5d43648bd942a9c273218432b2cd0c446a9f04

commit r13-9694-gaf5d43648bd942a9c273218432b2cd0c446a9f04
Author: Jakub Jelinek 
Date:   Wed Feb 5 13:16:17 2025 +0100

cselib: For CALL_INSNs to const/pure fns invalidate memory below sp 
[PR117239]

The following testcase is miscompiled on x86_64 during postreload.
After reload (with IPA-RA figuring out the calls don't modify any
registers but %rax for return value) postreload sees
(insn 14 12 15 2 (set (mem:DI (plus:DI (reg/f:DI 7 sp)
(const_int 16 [0x10])) [0  S8 A64])
(reg:DI 1 dx [orig:105 q+16 ] [105])) "pr117239.c":18:7 95 
{*movdi_internal}
 (nil))
(call_insn/i 15 14 16 2 (set (reg:SI 0 ax)
(call (mem:QI (symbol_ref:DI ("baz") [flags 0x3]  ) [0 baz S1 A8])
(const_int 24 [0x18]))) "pr117239.c":18:7 1476 {*call_value}
 (expr_list:REG_CALL_DECL (symbol_ref:DI ("baz") [flags 0x3]  
)
(expr_list:REG_EH_REGION (const_int 0 [0])
(nil)))
(nil))
(insn 16 15 18 2 (parallel [
(set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int 24 [0x18])))
(clobber (reg:CC 17 flags))
]) "pr117239.c":18:7 285 {*adddi_1}
 (expr_list:REG_ARGS_SIZE (const_int 0 [0])
(nil)))
...
(call_insn/i 19 18 21 2 (set (reg:SI 0 ax)
(call (mem:QI (symbol_ref:DI ("foo") [flags 0x3]  ) [0 foo S1 A8])
(const_int 0 [0]))) "pr117239.c":19:3 1476 {*call_value}
 (expr_list:REG_CALL_DECL (symbol_ref:DI ("foo") [flags 0x3]  
)
(expr_list:REG_EH_REGION (const_int 0 [0])
(nil)))
(nil))
(insn 21 19 26 2 (parallel [
(set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int -24 [0xffe8])))
(clobber (reg:CC 17 flags))
]) "pr117239.c":19:3 discrim 1 285 {*adddi_1}
 (expr_list:REG_ARGS_SIZE (const_int 24 [0x18])
(nil)))
(insn 26 21 24 2 (set (mem:DI (plus:DI (reg/f:DI 7 sp)
(const_int 16 [0x10])) [0  S8 A64])
(reg:DI 1 dx [orig:105 q+16 ] [105])) "pr117239.c":19:3 discrim 1 
95 {*movdi_internal}
 (nil))
i.e.
movq%rdx, 16(%rsp)
callbaz
addq$24, %rsp
...
callfoo
subq$24, %rsp
movq%rdx, 16(%rsp)
Now, postreload uses cselib and cselib remembered that %rdx value has been
stored into 16(%rsp).  Both baz and foo are pure calls.  If they weren't,
when processing those CALL_INSNs cselib would invalidate all MEMs
  if (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
  || !(RTL_CONST_OR_PURE_CALL_P (insn)))
cselib_invalidate_mem (callmem);
where callmem is (mem:BLK (scratch)).  But they are pure, so instead the
code just invalidates the argument slots from CALL_INSN_FUNCTION_USAGE.
The calls actually clobber more than that, even const/pure calls clobber
all memory below the stack pointer.  And that is something that hasn't been
invalidated.  In this failing testcase, the call to baz is not a big deal,
we don't have anything remembered in memory below %rsp at that call.
But then we increment %rsp by 24, so the %rsp+16 is now 8 bytes below stack
and do the call to foo.  And that call now actually, not just in theory,
clobbers the memory below the stack pointer (in particular overwrites it
with the return value).  But cselib does not invalidate.  Then %rsp
is decremented again (in preparation for another call, to bar) and cselib
is processing store of %rdx (which IPA-RA says has not been modified by
either baz or foo calls) to %rsp + 16, and it sees the memory already has
that value, so the store is useless, let's remove it.
But it is not, the call to foo has changed it, so it needs to be stored
again.

The following patch adds targetted invalidation of memory below stack
pointer (or on SPARC memory below stack pointer + 2047 when stack bias is
used, or on PA memory above stack pointer instead).
It does so only in !ACCUMULATE_OUTGOING_ARGS or cfun->calls_alloca 
functions,
because in other functions the stack pointer should be constant from
the end of prologue till start of epilogue and so nothing should be stored
within the function below the stack pointer.

Now, memory below stack pointer is special, except for functions using
alloca/VLAs I believe no addressable memory should be there, it should be
purely outgoing function argument area, if we take address of some automatic
variable, it should live all the time above the outgoing function argument
area.  So on top of just trying to flush memory below stack pointer
(represented by %rsp - PTRDIFF_MAX with

[gcc r15-9731] c-c++-common/gomp/{attrs-, }metadirective-3.c: Fix expected result [PR118694]

2025-05-26 Thread Tobias Burnus via Gcc-cvs
https://gcc.gnu.org/g:d390c7e5bd03490485a0b036add096e2e8b811b9

commit r15-9731-gd390c7e5bd03490485a0b036add096e2e8b811b9
Author: Tobias Burnus 
Date:   Mon May 26 19:50:40 2025 +0200

c-c++-common/gomp/{attrs-,}metadirective-3.c: Fix expected result [PR118694]

With compilation for nvptx enabled, two issues showed up:
(a) "error: 'target' construct with nested 'teams' construct contains
 directives outside of the 'teams' construct"
See PR comment 9 why this is difficult to fix.
Solution: Add dg-bogus and accept/expect the error for 'target 
offload_nvptx'.

(b) The assumptions about the dump for 'target offload_nvptx' were wrong
as the metadirective was already expanded to a OMP_NEXT_VARIANT
construct such that no 'omp metadirective' was left in either case.
Solution: Check that no 'omp metadirective' is left; additionally, expect
either OMP_NEXT_VARIANT (when offload_nvptx is available) or no 'teams'
directive at all (if not).

gcc/testsuite/ChangeLog:

PR middle-end/118694
* c-c++-common/gomp/attrs-metadirective-3.c: Change to never
expect 'omp metadirective' in the dump. If !offload_nvptx, check
that no 'teams' shows up in the dump; for offload_nvptx, expect
OMP_NEXT_VARIANT and an error about directive between 'target'
and 'teams'.
* c-c++-common/gomp/metadirective-3.c: Likewise.

(cherry picked from commit 5d6ed6d604ff949b650e48fa4eaed3ec8b6489c1)

Diff:
---
 gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c | 7 ---
 gcc/testsuite/c-c++-common/gomp/metadirective-3.c   | 7 ---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c 
b/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c
index 31dd054922fc..803bf0ad1ebf 100644
--- a/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c
+++ b/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c
@@ -9,7 +9,7 @@ f (int x[], int y[], int z[])
 {
   int i;
 
-  [[omp::sequence (directive (target map(to: x, y) map(from: z)),
+  [[omp::sequence (directive (target map(to: x, y) map(from: z)),  /* { 
dg-bogus "'target' construct with nested 'teams' construct contains directives 
outside of the 'teams' construct" "PR118694" { xfail offload_nvptx } }  */ 
   directive (metadirective
  when (device={arch("nvptx")}: teams loop)
  default (parallel loop)))]]
@@ -20,5 +20,6 @@ f (int x[], int y[], int z[])
 /* If offload device "nvptx" isn't supported, the front end can eliminate
that alternative and not produce a metadirective at all.  Otherwise this
won't be resolved until late.  */
-/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" { 
target { ! offload_nvptx } } } } */
-/* { dg-final { scan-tree-dump "#pragma omp metadirective" "gimple" { target { 
offload_nvptx } } } } */
+/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" } } */
+/* { dg-final { scan-tree-dump-not " teams" "gimple" { target { ! 
offload_nvptx } } } } */
+/* { dg-final { scan-tree-dump "variant.\[0-9\]+ = \\\[omp_next_variant\\\] 
OMP_NEXT_VARIANT <0,\[\r\n \]+construct context = 14\[\r\n \]+1: device = 
\\{arch \\(.nvptx.\\)\\}\[\r\n \]+2: >;" "gimple" { target { offload_nvptx } } 
} } */
diff --git a/gcc/testsuite/c-c++-common/gomp/metadirective-3.c 
b/gcc/testsuite/c-c++-common/gomp/metadirective-3.c
index 0ac0d1d329d8..b6c1601f7b10 100644
--- a/gcc/testsuite/c-c++-common/gomp/metadirective-3.c
+++ b/gcc/testsuite/c-c++-common/gomp/metadirective-3.c
@@ -8,7 +8,7 @@ f (int x[], int y[], int z[])
 {
   int i;
 
-  #pragma omp target map(to: x, y) map(from: z)
+  #pragma omp target map(to: x, y) map(from: z)  /* { dg-bogus "'target' 
construct with nested 'teams' construct contains directives outside of the 
'teams' construct" "PR118694" { xfail offload_nvptx } }  */ 
 #pragma omp metadirective \
when (device={arch("nvptx")}: teams loop) \
default (parallel loop)
@@ -19,5 +19,6 @@ f (int x[], int y[], int z[])
 /* If offload device "nvptx" isn't supported, the front end can eliminate
that alternative and not produce a metadirective at all.  Otherwise this
won't be resolved until late.  */
-/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" { 
target { ! offload_nvptx } } } } */
-/* { dg-final { scan-tree-dump "#pragma omp metadirective" "gimple" { target { 
offload_nvptx } } } } */
+/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" } } */
+/* { dg-final { scan-tree-dump-not " teams" "gimple" { target { ! 
offload_nvptx } } } } */
+/* { dg-final { scan-tree-dump "variant.\[0-9\]+ = \\\[omp_next_variant\\\] 
OMP_NEXT_VARIANT <0,\[\r\n \]+construct context = 14\[\r\n \]+1: device = 
\\{arch \\(.nvptx.\\)\\}\[\r\n \]+2: >;" "gimple" { target { offl

[gcc r13-9691] c++: Disable deprecated/unavailable diagnostics when creating thunks for methods with such attribute

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:17dcde03ec2fcc1856b9026f8479f57495c949ae

commit r13-9691-g17dcde03ec2fcc1856b9026f8479f57495c949ae
Author: Jakub Jelinek 
Date:   Thu Sep 12 18:22:21 2024 +0200

c++: Disable deprecated/unavailable diagnostics when creating thunks for 
methods with such attributes [PR116636]

On the following testcase, we emit false positive warnings/errors about 
using
the deprecated or unavailable methods when creating thunks for them, even
when nothing (in the testcase so far) actually used those.

The following patch temporarily disables that diagnostics when creating
the thunks.

2024-09-12  Jakub Jelinek  

PR c++/116636
* method.cc: Include decl.h.
(use_thunk): Temporarily change deprecated_state to
UNAVAILABLE_DEPRECATED_SUPPRESS.

* g++.dg/warn/deprecated-19.C: New test.

(cherry picked from commit 4026d89d623e322920b052f7ac0d940ef267dc0f)

Diff:
---
 gcc/cp/method.cc  |  6 ++
 gcc/testsuite/g++.dg/warn/deprecated-19.C | 22 ++
 2 files changed, 28 insertions(+)

diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index c9d9e3516f3b..0e701d64b130 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "target.h"
 #include "cp-tree.h"
+#include "decl.h"
 #include "stringpool.h"
 #include "cgraph.h"
 #include "varasm.h"
@@ -283,6 +284,11 @@ use_thunk (tree thunk_fndecl, bool emit_p)
   /* Thunks are always addressable; they only appear in vtables.  */
   TREE_ADDRESSABLE (thunk_fndecl) = 1;
 
+  /* Don't diagnose deprecated or unavailable functions just because they
+ have thunks emitted for them.  */
+  auto du = make_temp_override (deprecated_state,
+UNAVAILABLE_DEPRECATED_SUPPRESS);
+
   /* Figure out what function is being thunked to.  It's referenced in
  this translation unit.  */
   TREE_ADDRESSABLE (function) = 1;
diff --git a/gcc/testsuite/g++.dg/warn/deprecated-19.C 
b/gcc/testsuite/g++.dg/warn/deprecated-19.C
new file mode 100644
index ..e49af4f74d0d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/deprecated-19.C
@@ -0,0 +1,22 @@
+// PR c++/116636
+// { dg-do compile { target c++11 } }
+// { dg-options "-pedantic -Wdeprecated" }
+
+struct A {
+  virtual int foo () = 0;
+};
+struct B : virtual A {
+  [[deprecated]] int foo () { return 0; }  // { dg-message "declared here" 
}
+};
+struct C : virtual A {
+  [[gnu::unavailable]] int foo () { return 0; }// { dg-message 
"declared here" }
+};
+
+void
+bar ()
+{
+  B b;
+  b.foo ();// { dg-warning "'virtual int 
B::foo\\\(\\\)' is deprecated" }
+  C c;
+  c.foo ();// { dg-error "'virtual int 
C::foo\\\(\\\)' is unavailable" }
+}


[gcc r14-11811] s390: Fix tf_to_fprx2

2025-05-26 Thread Stefan Schulze Frielinghaus via Gcc-cvs
https://gcc.gnu.org/g:1dd54c5ad3930e27c4206ec3c08f4baecd9b4543

commit r14-11811-g1dd54c5ad3930e27c4206ec3c08f4baecd9b4543
Author: Stefan Schulze Frielinghaus 
Date:   Wed May 14 09:22:00 2025 +0200

s390: Fix tf_to_fprx2

Insn tf_to_fprx2 moves a TF value into a floating-point register pair.
For alternative 0, the input is a vector register, however, in the else
case instruction ldr is emitted which expects floating-point register
operands only.  Thus, this works only for vector registers which overlap
with floating-point registers.  Replace ldr with vlr so that the
remaining vector registers are dealt with, too.  Emitting a vlr instead
of a ldr is fine since the destination register %v0 is part of a
floating-point register pair which means that the low half of %v0 is
ignored in the end anyway and therefore may be clobbered.

gcc/ChangeLog:

* config/s390/vector.md: Fix tf_to_fprx2 by using vlr instead of
ldr.

(cherry picked from commit 8519b8ba9dd9567a5f90966351c1e758dbf511a4)

Diff:
---
 gcc/config/s390/vector.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 35defb7043a4..a79f21b05c73 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -938,7 +938,7 @@
   else
{
  reg_pair += 2;  // get rid of prefix %f
- snprintf (buf, sizeof (buf), 
"ldr\t%%f0,%%f1;vpdi\tv%s,%%v1,v%s,5", reg_pair, reg_pair);
+ snprintf (buf, sizeof (buf), 
"vlr\t%%v0,%%v1;vpdi\tv%s,%%v1,v%s,5", reg_pair, reg_pair);
  output_asm_insn (buf, operands);
  return "";
}


[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régressions vector_subscript*

2025-05-26 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:57a48a2b589ccf9ec3457825cc487b15674e835e

commit 57a48a2b589ccf9ec3457825cc487b15674e835e
Author: Mikael Morin 
Date:   Mon May 26 21:52:17 2025 +0200

Correction régressions vector_subscript*

Diff:
---
 gcc/fortran/trans-array.cc | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 11a203e474b8..27d8dda70573 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -2780,6 +2780,7 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, 
bool subscript,
  gfc_add_block_to_block (&outer_loop->pre, &se.pre);
  gfc_add_block_to_block (&outer_loop->post, &se.post);
  info->descriptor = se.expr;
+ gfc_conv_array_lbound_spacing (&outer_loop->pre, ss, 0);
  break;
 
case GFC_SS_INTRINSIC:
@@ -4308,7 +4309,8 @@ gfc_conv_array_lbound_spacing (stmtblock_t * block, 
gfc_ss * ss, int dim)
   gfc_array_info *info;
 
   gcc_assert (ss->info->type == GFC_SS_SECTION
- || ss->info->type == GFC_SS_COMPONENT);
+ || ss->info->type == GFC_SS_COMPONENT
+ || ss->info->type == GFC_SS_VECTOR);
 
   info = &ss->info->data.array;
   tree desc = info->descriptor;


[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régression assign_10

2025-05-26 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c9be2ad052f90cdc55f7a28f55f8f574fc17dc49

commit c9be2ad052f90cdc55f7a28f55f8f574fc17dc49
Author: Mikael Morin 
Date:   Mon May 26 22:49:46 2025 +0200

Correction régression assign_10

Diff:
---
 gcc/fortran/trans-array.cc  |  2 +-
 gcc/fortran/trans-descriptor.cc | 10 +-
 gcc/fortran/trans-descriptor.h  |  2 +-
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 27d8dda70573..dc4c0399cb2f 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -7825,7 +7825,7 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
 
   gfc_set_descriptor (&loop.pre, parm, desc, expr, loop.dimen, codim,
  ss, info, loop.from, loop.to, !se->data_not_needed,
- subref_array_target);
+ subref_array_target, !se->direct_byref);
 
   desc = parm;
 }
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index e41809f0037a..600c1bd43a5a 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -2955,6 +2955,9 @@ gfc_set_temporary_descriptor (stmtblock_t *block, tree 
desc, tree class_src,
  tree this_lbound = shift_bounds ? gfc_index_zero_node : lbound[n];
  set_descriptor_dimension (block, desc, n, this_lbound, ubound[n],
spacing[n], &offset, nullptr);
+ if (TREE_CODE (spacing[n]) == INTEGER_CST
+ && GFC_TYPE_ARRAY_SPACING (TREE_TYPE (desc), n) == NULL_TREE)
+   GFC_TYPE_ARRAY_SPACING (TREE_TYPE (desc), n) = spacing[n];
}
 }
 
@@ -3024,7 +3027,7 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree 
src, gfc_expr *src_expr,
int rank, int corank, gfc_ss *ss, gfc_array_info *info,
tree lowers[GFC_MAX_DIMENSIONS],
tree uppers[GFC_MAX_DIMENSIONS], bool data_needed,
-   bool subref)
+   bool subref, bool update_spacing_in_type)
 {
   int ndim = info->ref ? info->ref->u.ar.dimen : rank;
 
@@ -3138,6 +3141,11 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree 
src, gfc_expr *src_expr,
   offset = fold_build2_loc (input_location, MINUS_EXPR,
   TREE_TYPE (offset), offset, tmp);
 
+  if (update_spacing_in_type
+ && TREE_CODE (spacing) == INTEGER_CST
+ && GFC_TYPE_ARRAY_SPACING (TREE_TYPE (dest), dim) == NULL_TREE)
+   GFC_TYPE_ARRAY_SPACING (TREE_TYPE (dest), dim) = spacing;
+
   /* Store the new spacing.  */
   gfc_conv_descriptor_spacing_set (block, dest, gfc_rank_cst[dim], 
spacing);
 }
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index e431aeb9a7a3..4c4c82d227ab 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -91,7 +91,7 @@ void gfc_set_temporary_descriptor (stmtblock_t *, tree, tree, 
tree, tree,
 
 void gfc_set_descriptor (stmtblock_t *, tree, tree, gfc_expr *, int, int,
 gfc_ss *, gfc_array_info *, tree [GFC_MAX_DIMENSIONS],
-tree [GFC_MAX_DIMENSIONS], bool, bool);
+tree [GFC_MAX_DIMENSIONS], bool, bool, bool);
 
 tree gfc_descr_init_count (tree, int, int, gfc_expr **, gfc_expr **,
   stmtblock_t *, stmtblock_t *, tree *, tree,


[gcc r13-9675] dwarf2out: Propagate dtprel into the .debug_addr table in resolve_addr_in_expr

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:95e204dbc28f479b6b4116e5efacacde6c81ad75

commit r13-9675-g95e204dbc28f479b6b4116e5efacacde6c81ad75
Author: Kyle Huey 
Date:   Tue May 13 20:26:26 2025 -0700

dwarf2out: Propagate dtprel into the .debug_addr table in 
resolve_addr_in_expr

For a debugger to display statically-allocated[0] TLS variables the compiler
must communicate information[1] that can be used in conjunction with 
knowledge
of the runtime enviroment[2] to calculate a location for the variable for
each thread. That need gives rise to dw_loc_dtprel in dwarf2out, a flag 
tracking
whether the location description is dtprel, or relative to the
"dynamic thread pointer". Location descriptions in the .debug_info section 
for
TLS variables need to be relocated by the static linker accordingly, and
dw_loc_dtprel controls emission of the needed relocations.

This is further complicated by -gsplit-dwarf. -gsplit-dwarf is designed to 
allow
as much debugging information as possible to bypass the static linker to 
improve
linking performance. One of the ways that is done is by introducing a layer 
of
indirection for relocatable values[3]. That gives rise to addr_index_table 
which
ultimately results in the .debug_addr section.

While the code handling addr_index_table clearly contemplates the existence 
of
dtprel entries[4] resolve_addr_in_expr does not, and the result is that when
using -gsplit-dwarf the DWARF for TLS variables contains an address[5] 
rather
than an offset, and debuggers can't work with that.

This is visible on a trivial example. Compile

```
static __thread int tls_var;

int main(void) {
  tls_var = 42;
  return 0;
}
```

with -g and -g -gsplit-dwarf. Run the program under gdb. When examining the
value of tls_var before and after the assignment, -g behaves as one would
expect but -g -gsplit-dwarf does not. If the user is lucky and the 
miscalculated
address is not mapped, gdb will print "Cannot access memory at address ...".
If the user is unlucky and the miscalculated address is mapped, gdb will 
simply
give the wrong value. You can further confirm that the issue is the address
calculation by asking gdb for the address of tls_var and comparing that to 
what
one would expect.[6]

Thankfully this is trivial to fix by modifying resolve_addr_in_expr to 
propagate
the dtprel character of the location where necessary. gdb begins working as
expected and the diff in the generated assembly is clear.

```
.section.debug_addr,"",@progbits
.long   0x14
.value  0x5
.byte   0x8
.byte   0
 .Ldebug_addr0:
-   .quad   tls_var
+   .long   tls_var@dtpoff, 0
.quad   .LFB0
```

[0] Referring to e.g. __thread as statically-allocated vs. e.g. a
dynamically-allocated pthread_key_create() call.
[1] Generally an offset in a TLS block.
[2] With glibc, provided by libthread_db.so.
[3] Relocatable values are moved to a table in the .debug_addr section, 
those
values in .debug_info are replaced with special values that look up 
indexes
in that table, and then the static linker elsewhere assigns a single 
per-CU
starting index in the .debug_addr section, allowing those special 
values to
remain permanently fixed and the resulting data to be ignored by the 
linker.
[4] ate_kind_rtx_dtprel exists, after all, and new_addr_loc_descr does 
produce
it where appropriate.
[5] e.g. an address in the .tbss/.tdata section.
[6] e.g. on x86-64 by examining %fsbase and the offset in the assembly

2025-05-01  Kyle Huey  

* dwarf2out.cc (resolve_addr_in_expr): Propagate dtprel into the 
address
table when appropriate.

(cherry picked from commit 02e95abdde9742cecd7d1211e572549c1e56b8b1)

Diff:
---
 gcc/dwarf2out.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index b1a846c55a3e..5d1f75c6d0f6 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -30797,7 +30797,8 @@ resolve_addr_in_expr (dw_attr_node *a, dw_loc_descr_ref 
loc)
   return false;
 remove_addr_table_entry (loc->dw_loc_oprnd1.val_entry);
loc->dw_loc_oprnd1.val_entry
- = add_addr_table_entry (rtl, ate_kind_rtx);
+ = add_addr_table_entry (rtl, loc->dtprel
+ ? ate_kind_rtx_dtprel : ate_kind_rtx);
   }
break;
   case DW_OP_const4u:


[gcc r13-9676] middle-end/119706 - allow POLY_INT_CST as is_gimple_mem_ref_addr

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:fa2089e8dd1632e4597d61230e33375628368fc1

commit r13-9676-gfa2089e8dd1632e4597d61230e33375628368fc1
Author: Richard Biener 
Date:   Thu Apr 10 13:30:42 2025 +0200

middle-end/119706 - allow POLY_INT_CST as is_gimple_mem_ref_addr

We currently only INTEGER_CST, but not POLY_INT_CST, which leads
to the situation that when the POLY_INT_CST is only indrectly
present via a SSA def the IL is valid but when propagated it's not.
That's unsustainable.

PR middle-end/119706
* gimple-expr.cc (is_gimple_mem_ref_addr): Also allow
POLY_INT_CST.

(cherry picked from commit bf812c6ad83ec0b241bb3fecc7e68f883b6083df)

Diff:
---
 gcc/gimple-expr.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/gimple-expr.cc b/gcc/gimple-expr.cc
index 83dc340a35df..5cd5dd5e48fe 100644
--- a/gcc/gimple-expr.cc
+++ b/gcc/gimple-expr.cc
@@ -877,7 +877,7 @@ bool
 is_gimple_mem_ref_addr (tree t)
 {
   return (is_gimple_reg (t)
- || TREE_CODE (t) == INTEGER_CST
+ || poly_int_tree_p (t)
  || (TREE_CODE (t) == ADDR_EXPR
  && (CONSTANT_CLASS_P (TREE_OPERAND (t, 0))
  || decl_address_invariant_p (TREE_OPERAND (t, 0);


[gcc r13-9677] aarch64: Add test case.

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:b73dffc733524f05634ab0321a6978fc798d1384

commit r13-9677-gb73dffc733524f05634ab0321a6978fc798d1384
Author: Jennifer Schmitz 
Date:   Thu Apr 10 06:46:15 2025 -0700

aarch64: Add test case.

This patch adds a test case to the testsuite for PR119706.
The bug was already fixed by
https://gcc.gnu.org/pipermail/gcc-patches/2025-April/680573.html.

OK for mainline?

Signed-off-by: Jennifer Schmitz 

gcc/testsuite/
PR tree-optimization/119706
* g++.target/aarch64/sve/pr119706.C: New test.

(cherry picked from commit f6e6e6d9ba1d71fdd02a2c570d60217db6c5a31b)

Diff:
---
 gcc/testsuite/g++.target/aarch64/sve/pr119706.C | 178 
 1 file changed, 178 insertions(+)

diff --git a/gcc/testsuite/g++.target/aarch64/sve/pr119706.C 
b/gcc/testsuite/g++.target/aarch64/sve/pr119706.C
new file mode 100644
index ..40fefe5f4fb2
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/sve/pr119706.C
@@ -0,0 +1,178 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mcpu=neoverse-v2 
--param=aarch64-autovec-preference=sve-only -w" } */
+
+namespace a {
+typedef long unsigned b;
+typedef int c;
+template  struct e { using f = d; };
+template  using h = typename e::f;
+template  class> struct i {
+  using f = aa;
+};
+template  class j> using k = i;
+template  class j>
+using l = typename k::f;
+} // namespace a
+inline void *operator new(a::b, void *ab) { return ab; }
+namespace a {
+template  class ac {
+public:
+  typedef b m;
+  template  void ae(ad *ab, n... w) {
+new (ab) ad(w...);
+  }
+};
+template  using x = ac;
+template  class af : public x {
+public:
+  typedef d o;
+  template  struct ag { typedef af ah; };
+};
+struct ai {};
+struct aj : ai {};
+struct ak : aj {};
+template  struct al;
+template  struct al {
+  typedef ak an;
+  typedef c ao;
+  typedef d ap;
+};
+template  typename aq ::an ar(aq) { return typename aq ::an(); }
+template  typename as ::ao at(as au, as av, ak) { return av - au; 
}
+template  typename aw ::ao ax(aw au, aw av) {
+  return at(au, av, ar(au));
+}
+template  struct ay { typedef c ao; };
+} // namespace a
+namespace az {
+template  class ba {
+  am bb;
+  typedef a::al bc;
+
+public:
+  typedef typename bc::an an;
+  typedef typename bc::ao ao;
+  typedef typename bc::ap ap;
+  ba(am bd) : bb(bd) {}
+  ap operator*() { return *bb; }
+  ba operator++() {
+++bb;
+return *this;
+  }
+  am base() { return bb; }
+};
+template 
+bool operator!=(ba bh, ba p) {
+  return bh.base() != p.base();
+}
+template 
+auto operator-(ba bh, ba p) {
+  return bh.base() - p.base();
+}
+} // namespace az
+namespace a {
+struct bi {
+  template  struct bj {
+using f = typename d::ag::ah;
+  };
+  template  using bk = b;
+  template  static constexpr bool bl = false;
+  template  static constexpr bool bm = bl<>;
+  template  static constexpr bool bn = bm;
+};
+template  using bp = typename bi::bj::f;
+template  struct bq : bi {
+  typedef typename bo::o o;
+  using br = l;
+  template  struct bt { using f = typename ay::ao; 
};
+  template  struct bv { using f = typename bu::m; };
+  using ao = typename bt::f;
+  using m = typename bv::f;
+  template  using bw = bp;
+  static br allocate(bo, m);
+  template 
+  static h> ae(bo ci, d ab, n... w) {
+ci.ae(ab, w...);
+  }
+};
+template  struct bx {
+  static bool by(d &bz) try { d(bz.begin(), bz.ca(), bz.cb()); } catch (...) {
+  }
+};
+} // namespace a
+namespace az {
+template  struct cc : a::bq {
+  typedef a::bq q;
+  template  struct ag { typedef typename q::bw ah; };
+};
+} // namespace az
+enum cd {};
+using ce = double;
+namespace a {
+template 
+cg cj(aw au, cf av, cg ck, ch cl) {
+  typedef az::cc cx;
+  for (; au != av; ++au, ++ck)
+cx::ae(cl, ck, *au);
+}
+template  struct cm {
+  typedef typename az::cc::ag::ah cn;
+  typedef typename az::cc::br br;
+  struct co {
+br db;
+br cp;
+  };
+  struct cq : cn, co {
+cq(cn) {}
+  } typedef cr;
+  cn cs();
+  cr cb() noexcept;
+  cm(cr ci) : ct(ci) {}
+  cq ct;
+  br cu(b cv) {
+typedef az::cc cw;
+return cv ? cw::allocate(ct, cv) : c();
+  }
+};
+template > class cy : cm {
+  typedef cm cz;
+
+public:
+  typedef typename cz::br br;
+  typedef az::ba da;
+  typedef b m;
+  typedef bo cr;
+  cz::cs;
+  template  cy(aw au, aw av, cr ci) : cz(ci) {
+dg(au, av, ar(au));
+  }
+  cz::cb;
+  da begin() { return this->ct.db; }
+  da ca() { return this->ct.cp; }
+  void r() { s(); }
+  void clear() { t(this->ct.db); }
+  template  void dg(cg au, cg av, ai) { y(au, av, ax(au, av)); }
+  template  void y(am au, cf av, m cv) {
+br z = this->cu(dc(cv, cs()));
+cj(au, av, z, cs());
+  }
+  bool s();
+  m dc(m cv, cr) { return cv; }
+  void t(br dd) {
+if (this->ct.cp - dd)
+  this->ct.cp = dd;
+  }
+};
+template  bool cy::s() { bx::by(*this); }
+namespace basic {
+class u {
+  using de = ce;
+  void v(cd, b);
+  cy df;
+};
+void u::v(cd, b)

[gcc r13-9678] [14] Use --param=aarch64-autovec-preference=2 instead of =sve-only

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:d02be6073d902925510736855e7f044eb8755aa4

commit r13-9678-gd02be6073d902925510736855e7f044eb8755aa4
Author: Richard Biener 
Date:   Tue Apr 22 16:40:42 2025 +0200

[14] Use --param=aarch64-autovec-preference=2 instead of =sve-only

This updates the backported test.

PR tree-optimization/119706
* g++.target/aarch64/sve/pr119706.C: Adjust --param
aarch64-autovec-preference.

(cherry picked from commit d7b5fe3400cf15150ae18d522859cafcdd6a9315)

Diff:
---
 gcc/testsuite/g++.target/aarch64/sve/pr119706.C | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/g++.target/aarch64/sve/pr119706.C 
b/gcc/testsuite/g++.target/aarch64/sve/pr119706.C
index 40fefe5f4fb2..b185c12496f0 100644
--- a/gcc/testsuite/g++.target/aarch64/sve/pr119706.C
+++ b/gcc/testsuite/g++.target/aarch64/sve/pr119706.C
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O3 -mcpu=neoverse-v2 
--param=aarch64-autovec-preference=sve-only -w" } */
+/* { dg-options "-O3 -mcpu=neoverse-v2 --param=aarch64-autovec-preference=2 
-w" } */
 
 namespace a {
 typedef long unsigned b;
@@ -175,4 +175,4 @@ void u::v(cd, b) {
   df.r();
 }
 } // namespace basic
-} // namespace a
\ No newline at end of file
+} // namespace a


[gcc r13-9680] tree-optimization/117979 - failed irreducible loop update from DCE

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:6e6b9bbe9aadbfec4130c442ace9cabab50400c2

commit r13-9680-g6e6b9bbe9aadbfec4130c442ace9cabab50400c2
Author: Richard Biener 
Date:   Wed Jan 8 09:25:52 2025 +0100

tree-optimization/117979 - failed irreducible loop update from DCE

When CD-DCE creates forwarders to reduce false control dependences
it fails to update the irreducible state of edge and the forwarder
block in case the fowarder groups both normal (entry) and edges
from an irreducible region (necessarily backedges).  This is because
when we split the first edge, if that's a normal edge, the forwarder
and its edge to the original block will not be marked as part
of the irreducible region but when we then redirect an edge from
within the region it becomes so.

The following fixes this up.

Note I think creating a forwarder that includes backedges is
likely not going to help, but at this stage I don't want to change
the CFG going into DCE.  For regular loops we'll have a single
entry and a single backedge by means of loop init and will never
create a forwarder - so this is solely happening for irreducible
regions where it's harder to prove that such forwarder doesn't help.

PR tree-optimization/117979
* tree-ssa-dce.cc (make_forwarders_with_degenerate_phis):
Properly update the irreducible region state.

* gcc.dg/torture/pr117979.c: New testcase.

(cherry picked from commit eca04660a2c9546c8ecefc5288395eb8a9fdc168)

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr117979.c | 21 +
 gcc/tree-ssa-dce.cc | 10 ++
 2 files changed, 31 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/torture/pr117979.c 
b/gcc/testsuite/gcc.dg/torture/pr117979.c
new file mode 100644
index ..646cd70776b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr117979.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+int a, b;
+void foo (void);
+int __attribute__((returns_twice)) bar (int);
+
+int __attribute__((const))
+baz (int f)
+{
+  if (f)
+{
+  l:;
+  for (f = 0; f < 6; ++f)
+if (bar (b))
+  goto l;
+  for (;; a--)
+;
+}
+  foo ();
+  return 0;
+}
diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index 0ae998f86f98..8de1a276288d 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -1857,12 +1857,22 @@ make_forwarders_with_degenerate_phis (function *fn)
}
  free_dominance_info (fn, CDI_DOMINATORS);
  basic_block forwarder = split_edge (args[start].first);
+ bool irr = false;
  for (unsigned j = start + 1; j < i; ++j)
{
  edge e = args[j].first;
+ if (e->flags & EDGE_IRREDUCIBLE_LOOP)
+   irr = true;
  redirect_edge_and_branch_force (e, forwarder);
  redirect_edge_var_map_clear (e);
}
+ if (irr)
+   {
+ forwarder->flags |= BB_IRREDUCIBLE_LOOP;
+ single_succ_edge (forwarder)->flags
+   |= EDGE_IRREDUCIBLE_LOOP;
+   }
+
  if (vphi)
{
  tree def = copy_ssa_name (vphi_args[0]);


[gcc r13-9684] tree-optimization/119534 - reject bogus emulated vectorized gather

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:cdc47838cba79380bb5caa8f3934aabf2b44a7d5

commit r13-9684-gcdc47838cba79380bb5caa8f3934aabf2b44a7d5
Author: Richard Biener 
Date:   Tue Apr 1 14:13:03 2025 +0200

tree-optimization/119534 - reject bogus emulated vectorized gather

The following makes sure to reject the attempts to emulate a vector
gather when the discovered index vector type is a vector mask.

PR tree-optimization/119534
* tree-vect-stmts.cc (get_load_store_type): Reject
VECTOR_BOOLEAN_TYPE_P offset vector type for emulated gathers.

* gcc.dg/vect/pr119534.c: New testcase.

(cherry picked from commit d0cc14c62ad7403afcab3c2e38851d3ab179352f)

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr119534.c | 11 +++
 gcc/tree-vect-stmts.cc   |  1 +
 2 files changed, 12 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/vect/pr119534.c 
b/gcc/testsuite/gcc.dg/vect/pr119534.c
new file mode 100644
index ..0b4130b7cfaa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr119534.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mavx512bw" { target { x86_64-*-* i?86-*-* } } } */
+
+void f(int w, int *out, double *d)
+{
+  for (int j = 0; j < w; j++)
+{
+  const int i = (j >= w / 2);
+  out[j] += d[i];
+}
+}
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 98cf3f2bfc07..52face23c10c 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -2513,6 +2513,7 @@ get_load_store_type (vec_info  *vinfo, stmt_vec_info 
stmt_info,
  else if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant ()
   || !TYPE_VECTOR_SUBPARTS
 (gs_info->offset_vectype).is_constant ()
+  || VECTOR_BOOLEAN_TYPE_P (gs_info->offset_vectype)
   || !constant_multiple_p (TYPE_VECTOR_SUBPARTS
  (gs_info->offset_vectype),
TYPE_VECTOR_SUBPARTS (vectype)))


[gcc r13-9683] tree-optimization/98845 - ICE with tail-merging and DCE/DSE disabled

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:9e7c7e567704bd12d65b01246a655d8628bb521d

commit r13-9683-g9e7c7e567704bd12d65b01246a655d8628bb521d
Author: Richard Biener 
Date:   Mon Feb 17 15:53:11 2025 +0100

tree-optimization/98845 - ICE with tail-merging and DCE/DSE disabled

The following shows that tail-merging will make dead SSA defs live
in paths where it wasn't before, possibly introducing UB or as
in this case, uses of abnormals that eventually fail coalescing
later.  The fix is to register such defs for stmt comparison.

PR tree-optimization/98845
* tree-ssa-tail-merge.cc (stmt_local_def): Consider a
def with no uses not local.

* gcc.dg/pr98845.c: New testcase.
* gcc.dg/pr81192.c: Adjust.

(cherry picked from commit 6b8a8c9fd68c5dabaec5ddbc25efeade44f37a14)

Diff:
---
 gcc/testsuite/gcc.dg/pr81192.c | 68 --
 gcc/testsuite/gcc.dg/pr98845.c | 33 
 gcc/tree-ssa-tail-merge.cc |  8 +
 3 files changed, 100 insertions(+), 9 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/pr81192.c b/gcc/testsuite/gcc.dg/pr81192.c
index 6cab60565585..87a7a7a19c80 100644
--- a/gcc/testsuite/gcc.dg/pr81192.c
+++ b/gcc/testsuite/gcc.dg/pr81192.c
@@ -1,5 +1,62 @@
-/* { dg-options "-Os -fdump-tree-pre-details -fdisable-tree-evrp 
-fno-tree-dse" } */
+/* { dg-options "-Os -fgimple -fdump-tree-pre-details -fdisable-tree-evrp 
-fno-tree-dse" } */
 
+#if __SIZEOF_INT__ == 2
+#define unsigned __UINT32_TYPE__
+#define int __INT32_TYPE__
+#endif
+
+unsigned a;
+int b, c;
+
+void __GIMPLE(ssa, startwith("pre")) fn2   ()
+{
+  int b_lsm6;
+  int j;
+  int c0_1;
+  int iftmp2_8;
+
+  __BB(2):
+  a = _Literal (unsigned)30;
+  c0_1 = c;
+  b_lsm6_9 = b;
+  goto __BB7;
+
+  __BB(3):
+  if (j_6(D) != _Literal (int)2147483647)
+goto __BB4;
+  else
+goto __BB9;
+
+  __BB(4):
+  iftmp2_8 = j_6(D) + _Literal (int)1;
+  goto __BB5;
+
+  __BB(9):
+  iftmp2_8 = j_6(D) + _Literal (int)1;
+  goto __BB5;
+
+  __BB(5):
+  b_lsm6_10 = _Literal (int)2147483647;
+  goto __BB6;
+
+  __BB(6):
+  if (c0_1 != _Literal (int) 0)
+goto __BB3;
+  else
+goto __BB8;
+
+  __BB(8):
+  goto __BB7;
+
+  __BB(7):
+  goto __BB6;
+
+}
+
+#if 0
+/* This used to be a C based testcase but ccp3 would now would remove
+   the setting of iftmp2_8 (in the above gimple) which would cause PRE
+   not to test what PRE was doing incorrectly. The original code is below. */
 /* Disable tree-evrp because the new version of evrp sees
  :
   if (j_8(D) != 2147483647)
@@ -18,14 +75,6 @@ which causes the situation being tested to dissapear before 
we get to PRE.  */
 
 /* Likewise disable DSE which also elides the tail merging "opportunity".  */
 
-#if __SIZEOF_INT__ == 2
-#define unsigned __UINT32_TYPE__
-#define int __INT32_TYPE__
-#endif
-
-unsigned a;
-int b, c;
-
 static int
 fn1 (int p1, int p2)
 {
@@ -41,5 +90,6 @@ fn2 (void)
 for (; c; b = fn1 (j, 1))
   ;
 }
+#endif
 
 /* { dg-final { scan-tree-dump-times "(?n)find_duplicates:  duplicate 
of " 1 "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/pr98845.c b/gcc/testsuite/gcc.dg/pr98845.c
new file mode 100644
index ..074c979678f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr98845.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-dce -fno-tree-dse" } */
+
+int n;
+
+__attribute__ ((returns_twice)) void
+foo (void);
+
+void
+bar (void);
+
+void
+quux (int x)
+{
+  if (x)
+++x;
+  else
+{
+  if (n)
+{
+  x = 1;
+  foo ();
+}
+  else
+bar ();
+
+  if (n)
+{
+  ++x;
+  ++n;
+}
+}
+}
diff --git a/gcc/tree-ssa-tail-merge.cc b/gcc/tree-ssa-tail-merge.cc
index 33acb649d5d6..a94108da9f48 100644
--- a/gcc/tree-ssa-tail-merge.cc
+++ b/gcc/tree-ssa-tail-merge.cc
@@ -336,10 +336,13 @@ stmt_local_def (gimple *stmt)
 
   def_bb = gimple_bb (stmt);
 
+  bool any_use = false;
   FOR_EACH_IMM_USE_FAST (use_p, iter, val)
 {
   if (is_gimple_debug (USE_STMT (use_p)))
continue;
+
+  any_use = true;
   bb = gimple_bb (USE_STMT (use_p));
   if (bb == def_bb)
continue;
@@ -351,6 +354,11 @@ stmt_local_def (gimple *stmt)
   return false;
 }
 
+  /* When there is no use avoid making the stmt live on other paths.
+ This can happen with DCE disabled or not done as seen in PR98845.  */
+  if (!any_use)
+return false;
+
   return true;
 }


[gcc r13-9682] middle-end/119119 - re-gimplification of empty CTOR assignments

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:5a855127604e4df40afb25326a449b066c4a3527

commit r13-9682-g5a855127604e4df40afb25326a449b066c4a3527
Author: Richard Biener 
Date:   Thu Mar 6 09:08:07 2025 +0100

middle-end/119119 - re-gimplification of empty CTOR assignments

The following testcase runs into a re-gimplification issue during
inlining when processing

  MEM[(struct e *)this_2(D)].a = {};

where re-gimplification does not handle assignments in the same
way than the gimplifier but instead relies on rhs_predicate_for
and gimplifying the RHS standalone.  This fails to handle
special-casing of CTORs.  The is_gimple_mem_rhs_or_call predicate
already handles clobbers but not empty CTORs so we end up in
the fallback code trying to force the CTOR into a separate stmt
using a temporary - but as we have a non-copyable type here that ICEs.

The following generalizes empty CTORs in is_gimple_mem_rhs_or_call
since those need no additional re-gimplification.

PR middle-end/119119
* gimplify.cc (is_gimple_mem_rhs_or_call): All empty CTORs
are OK when not a register type.

* g++.dg/torture/pr11911.C: New testcase.

(cherry picked from commit 3bd61c1dfaa2d7153eb4be82f423533ea937d0f9)

Diff:
---
 gcc/gimplify.cc|  2 +-
 gcc/testsuite/g++.dg/torture/pr11911.C | 21 +
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 9c22139bd990..99e30a09f238 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -552,7 +552,7 @@ is_gimple_mem_rhs_or_call (tree t)
   else
 return (is_gimple_val (t)
|| is_gimple_lvalue (t)
-   || TREE_CLOBBER_P (t)
+   || (TREE_CODE (t) == CONSTRUCTOR && CONSTRUCTOR_NELTS (t) == 0)
|| TREE_CODE (t) == CALL_EXPR);
 }
 
diff --git a/gcc/testsuite/g++.dg/torture/pr11911.C 
b/gcc/testsuite/g++.dg/torture/pr11911.C
new file mode 100644
index ..7dc836ff9b53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr11911.C
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-require-effective-target c++17 }
+
+struct b {
+  int a;
+};
+struct c {
+  b d{};
+  c() = default;
+  c(c &) = delete;
+};
+struct e {
+  c a{};
+  e() {}
+};
+inline e f() { return {}; }
+struct g {
+  e cx;
+  g() : cx{f()} {}
+};
+void h() { g i; }


[gcc r13-9685] Fix ICE with -fdump-tree-moref

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:1067dd74239aa3efd3489cf8c6216fb9787031ca

commit r13-9685-g1067dd74239aa3efd3489cf8c6216fb9787031ca
Author: Jan Hubicka 
Date:   Mon Jul 29 10:48:34 2024 +0200

Fix ICE with -fdump-tree-moref

gcc/ChangeLog:

PR ipa/116055
* ipa-modref.cc (analyze_function): Do not ICE when flags regress.

(cherry picked from commit 98baaa17561ca299eefc98f469f4326e551604c9)

Diff:
---
 gcc/ipa-modref.cc | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index d633c8331956..0fa381488e7e 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -3295,7 +3295,8 @@ analyze_function (bool ipa)
fprintf (dump_file, "  Flags for param %i improved:",
 (int)i);
  else
-   gcc_unreachable ();
+   fprintf (dump_file, "  Flags for param %i changed:",
+(int)i);
  dump_eaf_flags (dump_file, old_flags, false);
  fprintf (dump_file, " -> ");
  dump_eaf_flags (dump_file, new_flags, true);
@@ -3311,7 +3312,7 @@ analyze_function (bool ipa)
  || (summary->retslot_flags & EAF_UNUSED))
fprintf (dump_file, "  Flags for retslot improved:");
  else
-   gcc_unreachable ();
+   fprintf (dump_file, "  Flags for retslot changed:");
  dump_eaf_flags (dump_file, past_retslot_flags, false);
  fprintf (dump_file, " -> ");
  dump_eaf_flags (dump_file, summary->retslot_flags, true);
@@ -3326,7 +3327,7 @@ analyze_function (bool ipa)
  || (summary->static_chain_flags & EAF_UNUSED))
fprintf (dump_file, "  Flags for static chain improved:");
  else
-   gcc_unreachable ();
+   fprintf (dump_file, "  Flags for static chain changed:");
  dump_eaf_flags (dump_file, past_static_chain_flags, false);
  fprintf (dump_file, " -> ");
  dump_eaf_flags (dump_file, summary->static_chain_flags, true);


[gcc r13-9686] PR tree-optimization/113673: Avoid load merging when potentially trapping.

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:d034c8d5c31811b0c12a4c1ffad89f8f8b086053

commit r13-9686-gd034c8d5c31811b0c12a4c1ffad89f8f8b086053
Author: Roger Sayle 
Date:   Mon Jun 24 15:34:03 2024 +0100

PR tree-optimization/113673: Avoid load merging when potentially trapping.

This patch fixes PR tree-optimization/113673, a P2 ice-on-valid regression
caused by load merging of (ptr[0]<<8)+ptr[1] when -ftrapv has been
specified.  When the operator is | or ^ this is safe, but for addition
of signed integer types, a trap may be generated/required, so merging this
idiom into a single non-trapping instruction is inappropriate, confusing
the compiler by transforming a basic block with an exception edge into one
without.

This revision implements Richard Biener's feedback to add an early check
for stmt_can_throw_internal (cfun, stmt) to prevent transforming in the
presence of any statement that could trap, not just overflow on addition.
The one other tweak included in this patch is to mark the local function
find_bswap_or_nop_load as static ensuring that it isn't called from outside
this file, and guaranteeing that it is dominated by stmt_can_throw_internal
checking.

2024-06-24  Roger Sayle  
Richard Biener  

gcc/ChangeLog
PR tree-optimization/113673
* gimple-ssa-store-merging.cc (find_bswap_or_nop_load): Make static.
(find_bswap_or_nop_1): Avoid transformations (load merging) when
stmt_can_throw_internal indicates that a statement can trap.

gcc/testsuite/ChangeLog
PR tree-optimization/113673
* g++.dg/pr113673.C: New test case.

(cherry picked from commit d8b05aef77443e1d3d8f3f5d2c56ac49a503fee3)

Diff:
---
 gcc/gimple-ssa-store-merging.cc |  6 --
 gcc/testsuite/g++.dg/pr113673.C | 14 ++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/gcc/gimple-ssa-store-merging.cc b/gcc/gimple-ssa-store-merging.cc
index 4898f48ec523..decccef25dae 100644
--- a/gcc/gimple-ssa-store-merging.cc
+++ b/gcc/gimple-ssa-store-merging.cc
@@ -363,7 +363,7 @@ init_symbolic_number (struct symbolic_number *n, tree src)
the answer. If so, REF is that memory source and the base of the memory area
accessed and the offset of the access from that base are recorded in N.  */
 
-bool
+static bool
 find_bswap_or_nop_load (gimple *stmt, tree ref, struct symbolic_number *n)
 {
   /* Leaf node is an array or component ref. Memorize its base and
@@ -610,7 +610,9 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number 
*n, int limit)
   gimple *rhs1_stmt, *rhs2_stmt, *source_stmt1;
   enum gimple_rhs_class rhs_class;
 
-  if (!limit || !is_gimple_assign (stmt))
+  if (!limit
+  || !is_gimple_assign (stmt)
+  || stmt_can_throw_internal (cfun, stmt))
 return NULL;
 
   rhs1 = gimple_assign_rhs1 (stmt);
diff --git a/gcc/testsuite/g++.dg/pr113673.C b/gcc/testsuite/g++.dg/pr113673.C
new file mode 100644
index ..11489777f5b9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr113673.C
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fnon-call-exceptions -ftrapv" } */
+
+struct s { ~s(); };
+void
+h (unsigned char *data, int c)
+{
+  s a1;
+  while (c)
+{
+  int m = *data++ << 8;
+  m += *data++;
+}
+}


[gcc r14-11808] cselib: For CALL_INSNs to const/pure fns invalidate memory below sp [PR117239]

2025-05-26 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:cfd7c674139097d12546d034f7869e272457aa56

commit r14-11808-gcfd7c674139097d12546d034f7869e272457aa56
Author: Jakub Jelinek 
Date:   Wed Feb 5 13:16:17 2025 +0100

cselib: For CALL_INSNs to const/pure fns invalidate memory below sp 
[PR117239]

The following testcase is miscompiled on x86_64 during postreload.
After reload (with IPA-RA figuring out the calls don't modify any
registers but %rax for return value) postreload sees
(insn 14 12 15 2 (set (mem:DI (plus:DI (reg/f:DI 7 sp)
(const_int 16 [0x10])) [0  S8 A64])
(reg:DI 1 dx [orig:105 q+16 ] [105])) "pr117239.c":18:7 95 
{*movdi_internal}
 (nil))
(call_insn/i 15 14 16 2 (set (reg:SI 0 ax)
(call (mem:QI (symbol_ref:DI ("baz") [flags 0x3]  ) [0 baz S1 A8])
(const_int 24 [0x18]))) "pr117239.c":18:7 1476 {*call_value}
 (expr_list:REG_CALL_DECL (symbol_ref:DI ("baz") [flags 0x3]  
)
(expr_list:REG_EH_REGION (const_int 0 [0])
(nil)))
(nil))
(insn 16 15 18 2 (parallel [
(set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int 24 [0x18])))
(clobber (reg:CC 17 flags))
]) "pr117239.c":18:7 285 {*adddi_1}
 (expr_list:REG_ARGS_SIZE (const_int 0 [0])
(nil)))
...
(call_insn/i 19 18 21 2 (set (reg:SI 0 ax)
(call (mem:QI (symbol_ref:DI ("foo") [flags 0x3]  ) [0 foo S1 A8])
(const_int 0 [0]))) "pr117239.c":19:3 1476 {*call_value}
 (expr_list:REG_CALL_DECL (symbol_ref:DI ("foo") [flags 0x3]  
)
(expr_list:REG_EH_REGION (const_int 0 [0])
(nil)))
(nil))
(insn 21 19 26 2 (parallel [
(set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int -24 [0xffe8])))
(clobber (reg:CC 17 flags))
]) "pr117239.c":19:3 discrim 1 285 {*adddi_1}
 (expr_list:REG_ARGS_SIZE (const_int 24 [0x18])
(nil)))
(insn 26 21 24 2 (set (mem:DI (plus:DI (reg/f:DI 7 sp)
(const_int 16 [0x10])) [0  S8 A64])
(reg:DI 1 dx [orig:105 q+16 ] [105])) "pr117239.c":19:3 discrim 1 
95 {*movdi_internal}
 (nil))
i.e.
movq%rdx, 16(%rsp)
callbaz
addq$24, %rsp
...
callfoo
subq$24, %rsp
movq%rdx, 16(%rsp)
Now, postreload uses cselib and cselib remembered that %rdx value has been
stored into 16(%rsp).  Both baz and foo are pure calls.  If they weren't,
when processing those CALL_INSNs cselib would invalidate all MEMs
  if (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
  || !(RTL_CONST_OR_PURE_CALL_P (insn)))
cselib_invalidate_mem (callmem);
where callmem is (mem:BLK (scratch)).  But they are pure, so instead the
code just invalidates the argument slots from CALL_INSN_FUNCTION_USAGE.
The calls actually clobber more than that, even const/pure calls clobber
all memory below the stack pointer.  And that is something that hasn't been
invalidated.  In this failing testcase, the call to baz is not a big deal,
we don't have anything remembered in memory below %rsp at that call.
But then we increment %rsp by 24, so the %rsp+16 is now 8 bytes below stack
and do the call to foo.  And that call now actually, not just in theory,
clobbers the memory below the stack pointer (in particular overwrites it
with the return value).  But cselib does not invalidate.  Then %rsp
is decremented again (in preparation for another call, to bar) and cselib
is processing store of %rdx (which IPA-RA says has not been modified by
either baz or foo calls) to %rsp + 16, and it sees the memory already has
that value, so the store is useless, let's remove it.
But it is not, the call to foo has changed it, so it needs to be stored
again.

The following patch adds targetted invalidation of memory below stack
pointer (or on SPARC memory below stack pointer + 2047 when stack bias is
used, or on PA memory above stack pointer instead).
It does so only in !ACCUMULATE_OUTGOING_ARGS or cfun->calls_alloca 
functions,
because in other functions the stack pointer should be constant from
the end of prologue till start of epilogue and so nothing should be stored
within the function below the stack pointer.

Now, memory below stack pointer is special, except for functions using
alloca/VLAs I believe no addressable memory should be there, it should be
purely outgoing function argument area, if we take address of some automatic
variable, it should live all the time above the outgoing function argument
area.  So on top of just trying to flush memory below stack pointer
(represented by %rsp - PTRDIFF_MAX wit

[gcc r13-9679] tree-optimization/119778 - properly mark abnormal edge sources during inlining

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:b98de795c7f57ad15155ed1223c25c094ff27d16

commit r13-9679-gb98de795c7f57ad15155ed1223c25c094ff27d16
Author: Richard Biener 
Date:   Mon Apr 14 11:42:18 2025 +0200

tree-optimization/119778 - properly mark abnormal edge sources during 
inlining

When inlining a call that abnormally transfers control-flow we make
all inlined calls that can possibly transfer abnormal control-flow
do so as well.  But we failed to mark the calls as altering
control-flow.  This results in inconsistent behavior later and
possibly wrong-code (we'd eventually prune those edges).

PR tree-optimization/119778
* tree-inline.cc (copy_edges_for_bb): Mark calls that are
source of abnormal edges as altering control-flow.

* g++.dg/torture/pr119778.C: New testcase.

(cherry picked from commit a48f934211434cac1be951c207ee76e4b4340fac)

Diff:
---
 gcc/testsuite/g++.dg/torture/pr119778.C | 20 
 gcc/tree-inline.cc  |  7 +--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/g++.dg/torture/pr119778.C 
b/gcc/testsuite/g++.dg/torture/pr119778.C
new file mode 100644
index ..494805619282
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr119778.C
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-additional-options "-Wall" }
+
+struct jmp_buf { long l[16]; };
+extern "C" int setjmp (jmp_buf *);
+struct S {
+  void foo () { bar (); }
+  virtual char bar () { return 0; }
+};
+void baz ();
+jmp_buf *a;
+
+void
+qux (bool x, S *y)
+{
+  if (x)
+setjmp (a);
+  y->foo ();
+  baz ();
+}
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index 73d5a9fadef3..c17b3432d1b0 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -2679,8 +2679,11 @@ copy_edges_for_bb (basic_block bb, profile_count num, 
profile_count den,
   && gimple_call_arg (copy_stmt, 0) == boolean_true_node)
nonlocal_goto = false;
  else
-   make_single_succ_edge (copy_stmt_bb, abnormal_goto_dest,
-  EDGE_ABNORMAL);
+   {
+ make_single_succ_edge (copy_stmt_bb, abnormal_goto_dest,
+EDGE_ABNORMAL);
+ gimple_call_set_ctrl_altering (copy_stmt, true);
+   }
}
 
   if ((can_throw || nonlocal_goto)


[gcc r13-9681] tree-optimization/119057 - bogus double reduction detection

2025-05-26 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:876083c5e7a8863ce87d8da9e3a43927aee7e02b

commit r13-9681-g876083c5e7a8863ce87d8da9e3a43927aee7e02b
Author: Richard Biener 
Date:   Mon Mar 3 13:21:53 2025 +0100

tree-optimization/119057 - bogus double reduction detection

We are detecting a cycle as double reduction where the inner loop
cycle has extra out-of-loop uses.  This clashes at least with
assumptions from the SLP discovery code which says the cycle
isn't reachable from another SLP instance.  It also was not intended
to support this case, in fact with GCC 14 we seem to generate wrong
code here.

PR tree-optimization/119057
* tree-vect-loop.cc (check_reduction_path): Add argument
specifying whether we're analyzing the inner loop of a
double reduction.  Do not allow extra uses outside of the
double reduction cycle in this case.
(vect_is_simple_reduction): Adjust.

* gcc.dg/vect/pr119057.c: New testcase.

(cherry picked from commit 758de6263dfc7ba8701965fa468691ac23cb7eb5)

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr119057.c | 19 +++
 gcc/tree-vect-loop.cc| 12 +++-
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr119057.c 
b/gcc/testsuite/gcc.dg/vect/pr119057.c
new file mode 100644
index ..582bb8ff86c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr119057.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-tree-vrp -fno-tree-forwprop" } */
+
+int a, b, c, d;
+unsigned e;
+static void f(void)
+{
+  unsigned h;
+  for (d = 0; d < 2; d++)
+b |= e;
+  h = b;
+  c |= h;
+}
+int main()
+{
+  for (; a; a++)
+f();
+  return 0;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 7a319e7f98ef..9672dc7f8a35 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -3552,7 +3552,8 @@ needs_fold_left_reduction_p (tree type, code_helper code)
 static bool
 check_reduction_path (dump_user_location_t loc, loop_p loop, gphi *phi,
  tree loop_arg, code_helper *code,
- vec > &path)
+ vec > &path,
+ bool inner_loop_of_double_reduc)
 {
   auto_bitmap visited;
   tree lookfor = PHI_RESULT (phi);
@@ -3682,7 +3683,8 @@ pop:
  break;
}
   /* Check there's only a single stmt the op is used on.  For the
-not value-changing tail and the last stmt allow out-of-loop uses.
+not value-changing tail and the last stmt allow out-of-loop uses,
+but not when this is the inner loop of a double reduction.
 ???  We could relax this and handle arbitrary live stmts by
 forcing a scalar epilogue for example.  */
   imm_use_iterator imm_iter;
@@ -3691,7 +3693,7 @@ pop:
   unsigned cnt = 0;
   FOR_EACH_IMM_USE_STMT (op_use_stmt, imm_iter, op.ops[opi])
if (!is_gimple_debug (op_use_stmt)
-   && (*code != ERROR_MARK
+   && ((*code != ERROR_MARK || inner_loop_of_double_reduc)
|| flow_bb_inside_loop_p (loop, gimple_bb (op_use_stmt
  FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
cnt++;
@@ -3710,7 +3712,7 @@ check_reduction_path (dump_user_location_t loc, loop_p 
loop, gphi *phi,
 {
   auto_vec > path;
   code_helper code_;
-  return (check_reduction_path (loc, loop, phi, loop_arg, &code_, path)
+  return (check_reduction_path (loc, loop, phi, loop_arg, &code_, path, false)
  && code_ == code);
 }
 
@@ -3914,7 +3916,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, 
stmt_vec_info phi_info,
   auto_vec > path;
   code_helper code;
   if (check_reduction_path (vect_location, loop, phi, latch_def, &code,
-   path))
+   path, inner_loop_of_double_reduc))
 {
   STMT_VINFO_REDUC_CODE (phi_info) = code;
   if (code == COND_EXPR && !nested_in_vect_loop)


[gcc r16-878] libstdc++: Implement C++26 std::indirect [PR119152]

2025-05-26 Thread Tomasz Kaminski via Libstdc++-cvs
https://gcc.gnu.org/g:caf804b1795575d7714c62dd45b649831598055e

commit r16-878-gcaf804b1795575d7714c62dd45b649831598055e
Author: Jonathan Wakely 
Date:   Thu Mar 21 23:07:56 2024 +

libstdc++: Implement C++26 std::indirect [PR119152]

This patch implements C++26 std::indirect as specified
in P3019 with amendment to move assignment from LWG 4251.

PR libstdc++/119152

libstdc++-v3/ChangeLog:

* doc/doxygen/stdheader.cc: Added indirect.h file.
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/bits/indirect.h: New file.
* include/bits/version.def (indirect): Define.
* include/bits/version.h: Regenerate.
* include/std/memory: Include new header.
* testsuite/std/memory/indirect/copy.cc
* testsuite/std/memory/indirect/copy_alloc.cc
* testsuite/std/memory/indirect/ctor.cc
* testsuite/std/memory/indirect/incomplete.cc
* testsuite/std/memory/indirect/invalid_neg.cc
* testsuite/std/memory/indirect/move.cc
* testsuite/std/memory/indirect/move_alloc.cc
* testsuite/std/memory/indirect/relops.cc

Co-authored-by: Tomasz Kamiński 
Signed-off-by: Tomasz Kamiński 

Diff:
---
 libstdc++-v3/doc/doxygen/stdheader.cc  |   1 +
 libstdc++-v3/include/Makefile.am   |   1 +
 libstdc++-v3/include/Makefile.in   |   1 +
 libstdc++-v3/include/bits/indirect.h   | 459 +
 libstdc++-v3/include/bits/version.def  |   9 +
 libstdc++-v3/include/bits/version.h|  10 +
 libstdc++-v3/include/std/memory|   5 +
 libstdc++-v3/testsuite/std/memory/indirect/copy.cc | 121 ++
 .../testsuite/std/memory/indirect/copy_alloc.cc| 228 ++
 libstdc++-v3/testsuite/std/memory/indirect/ctor.cc | 203 +
 .../testsuite/std/memory/indirect/incomplete.cc|  38 ++
 .../testsuite/std/memory/indirect/invalid_neg.cc   |  28 ++
 libstdc++-v3/testsuite/std/memory/indirect/move.cc | 144 +++
 .../testsuite/std/memory/indirect/move_alloc.cc| 296 +
 .../testsuite/std/memory/indirect/relops.cc|  82 
 15 files changed, 1626 insertions(+)

diff --git a/libstdc++-v3/doc/doxygen/stdheader.cc 
b/libstdc++-v3/doc/doxygen/stdheader.cc
index 938b2b04a262..cb5d17a4f1f7 100644
--- a/libstdc++-v3/doc/doxygen/stdheader.cc
+++ b/libstdc++-v3/doc/doxygen/stdheader.cc
@@ -106,6 +106,7 @@ void init_map()
 headers["uses_allocator.h"] = "memory";
 headers["uses_allocator_args.h"]= "memory";
 headers["out_ptr.h"]= "memory";
+headers["indirect.h"]   = "memory";
 headers["memory_resource.h"]= "memory_resource";
 headers["unique_lock.h"]= "mutex";
 headers["sat_arith.h"]  = "numeric";
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index baf0290d6559..cc402f0648f4 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -211,6 +211,7 @@ bits_headers = \
${bits_srcdir}/gslice_array.h \
${bits_srcdir}/hashtable.h \
${bits_srcdir}/hashtable_policy.h \
+   ${bits_srcdir}/indirect.h \
${bits_srcdir}/indirect_array.h \
${bits_srcdir}/ios_base.h \
${bits_srcdir}/istream.tcc \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index e4e1079d8bdb..a6e602327b6e 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -564,6 +564,7 @@ bits_freestanding = \
 @GLIBCXX_HOSTED_TRUE@  ${bits_srcdir}/gslice_array.h \
 @GLIBCXX_HOSTED_TRUE@  ${bits_srcdir}/hashtable.h \
 @GLIBCXX_HOSTED_TRUE@  ${bits_srcdir}/hashtable_policy.h \
+@GLIBCXX_HOSTED_TRUE@  ${bits_srcdir}/indirect.h \
 @GLIBCXX_HOSTED_TRUE@  ${bits_srcdir}/indirect_array.h \
 @GLIBCXX_HOSTED_TRUE@  ${bits_srcdir}/ios_base.h \
 @GLIBCXX_HOSTED_TRUE@  ${bits_srcdir}/istream.tcc \
diff --git a/libstdc++-v3/include/bits/indirect.h 
b/libstdc++-v3/include/bits/indirect.h
new file mode 100644
index ..85908e219b77
--- /dev/null
+++ b/libstdc++-v3/include/bits/indirect.h
@@ -0,0 +1,459 @@
+// Vocabulary Types for Composite Class Design -*- C++ -*-
+
+// Copyright The GNU Toolchain Authors.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Un

[gcc r16-875] [AUTOFDO][AARCH64] Add support for profilebootstrap

2025-05-26 Thread Kugan Vivekanandarajah via Gcc-cvs
https://gcc.gnu.org/g:86dc974cf30f926a014438a5fccdc9d41e26282b

commit r16-875-g86dc974cf30f926a014438a5fccdc9d41e26282b
Author: Kugan Vivekanandarajah 
Date:   Mon May 26 11:41:59 2025 +1000

[AUTOFDO][AARCH64] Add support for profilebootstrap

Add support for autoprofiledbootstrap in aarch64.
This is similar to what is done for i386. Added
gcc/config/aarch64/gcc-auto-profile for aarch64 profile
creation.

How to run:
configure --with-build-config=bootstrap-lto
make autoprofiledbootstrap

ChangeLog:

* Makefile.def: AUTO_PROFILE based on cpu_type.
* Makefile.in: Likewise.
* configure: Regenerate.
* configure.ac: Set autofdo_target.

gcc/ChangeLog:

* config/aarch64/gcc-auto-profile: New file.

Signed-off-by: Kugan Vivekanandarajah 

Diff:
---
 Makefile.def|  2 +-
 Makefile.in | 69 +++--
 configure   |  4 +++
 configure.ac|  3 ++
 gcc/config/aarch64/gcc-auto-profile | 53 
 5 files changed, 96 insertions(+), 35 deletions(-)

diff --git a/Makefile.def b/Makefile.def
index 3f980bce8c05..b0382713609a 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -758,7 +758,7 @@ bootstrap_stage = {
bootstrap_target=profiledbootstrap ; };
 bootstrap_stage = {
id=autoprofile ; prev=1 ;
-autoprofile="$$s/gcc/config/i386/$(AUTO_PROFILE)" ; };
+autoprofile="$$s/gcc/config/@cpu_typet@/$(AUTO_PROFILE)" ; };
 bootstrap_stage = {
id=autofeedback ; prev=autoprofile ;
bootstrap_target=autoprofiledbootstrap ;
diff --git a/Makefile.in b/Makefile.in
index b1ed67d3d4f1..931507c32703 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -38,6 +38,7 @@ build_alias=@build_noncanonical@
 build_vendor=@build_vendor@
 build_os=@build_os@
 build=@build@
+cpu_type=@cpu_type@
 host_alias=@host_noncanonical@
 host_vendor=@host_vendor@
 host_os=@host_os@
@@ -4271,7 +4272,7 @@ all-stageautoprofile-bfd: configure-stageautoprofile-bfd
$(HOST_EXPORTS) \
$(POSTSTAGE1_HOST_EXPORTS)  \
cd $(HOST_SUBDIR)/bfd && \
-   $$s/gcc/config/i386/$(AUTO_PROFILE) \
+   $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \
$(MAKE) $(BASE_FLAGS_TO_PASS) \
CFLAGS="$(STAGEautoprofile_CFLAGS)" \
GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \
@@ -5411,7 +5412,7 @@ all-stageautoprofile-opcodes: 
configure-stageautoprofile-opcodes
$(HOST_EXPORTS) \
$(POSTSTAGE1_HOST_EXPORTS)  \
cd $(HOST_SUBDIR)/opcodes && \
-   $$s/gcc/config/i386/$(AUTO_PROFILE) \
+   $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \
$(MAKE) $(BASE_FLAGS_TO_PASS) \
CFLAGS="$(STAGEautoprofile_CFLAGS)" \
GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \
@@ -6551,7 +6552,7 @@ all-stageautoprofile-binutils: 
configure-stageautoprofile-binutils
$(HOST_EXPORTS) \
$(POSTSTAGE1_HOST_EXPORTS)  \
cd $(HOST_SUBDIR)/binutils && \
-   $$s/gcc/config/i386/$(AUTO_PROFILE) \
+   $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \
$(MAKE) $(BASE_FLAGS_TO_PASS) \
CFLAGS="$(STAGEautoprofile_CFLAGS)" \
GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \
@@ -10037,7 +10038,7 @@ all-stageautoprofile-fixincludes: 
configure-stageautoprofile-fixincludes
$(HOST_EXPORTS) \
$(POSTSTAGE1_HOST_EXPORTS)  \
cd $(HOST_SUBDIR)/fixincludes && \
-   $$s/gcc/config/i386/$(AUTO_PROFILE) \
+   $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \
$(MAKE) $(BASE_FLAGS_TO_PASS) \
CFLAGS="$(STAGEautoprofile_CFLAGS)" \
GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \
@@ -11617,7 +11618,7 @@ all-stageautoprofile-gas: configure-stageautoprofile-gas
$(HOST_EXPORTS) \
$(POSTSTAGE1_HOST_EXPORTS)  \
cd $(HOST_SUBDIR)/gas && \
-   $$s/gcc/config/i386/$(AUTO_PROFILE) \
+   $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \
$(MAKE) $(BASE_FLAGS_TO_PASS) \
CFLAGS="$(STAGEautoprofile_CFLAGS)" \
GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \
@@ -12766,7 +12767,7 @@ all-stageautoprofile-gcc: configure-stageautoprofile-gcc
$(HOST_EXPORTS) \
$(POSTSTAGE1_HOST_EXPORTS)  \
cd $(HOST_SUBDIR)/gcc && \
-   $$s/gcc/config/i386/$(AUTO_PROFILE) \
+   $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \
$(MAKE) $(BASE_FLAGS_TO_PASS) \
CFLAGS="$(STAGEautoprofile_CFLAGS)" \
GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \
@@ -13915,7 +13916,7 @@ all-stageautoprofile-gmp: configure-stageautoprofile-gmp
$(HOST_EXPORTS) \
$(POSTSTAGE1_HOST_EXPORTS)  \
cd $(HOST_SUBDIR)/gmp && \
-   $$s/gcc/confi

[gcc r16-880] c++: add -fdump-lang-tinst

2025-05-26 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:f59ff19bc3d37f4dd159db541ed4f07efb10fcc8

commit r16-880-gf59ff19bc3d37f4dd159db541ed4f07efb10fcc8
Author: Jason Merrill 
Date:   Fri Apr 18 09:50:04 2025 -0400

c++: add -fdump-lang-tinst

This patch adds a dump with a trace of template instantiations, indented
based on the depth of recursive instantiation. -lineno adds the location
that triggered the instantiation, -details adds non-instantiation
sbustitutions.

The instantiate_pending_templates change is to avoid a bunch of entries for
reopening tinst scopes that we then don't instantiate anything with; it also
seems a bit cleaner this way.

gcc/cp/ChangeLog:

* cp-tree.h: Declare tinst_dump_id.
* cp-objcp-common.cc (cp_register_dumps): Set it.
* pt.cc (push_tinst_level_loc): Dump it.
(reopen_tinst_level): Here too.
(tinst_complete_p): New.
(instantiate_pending_templates): Don't reopen_tinst_level for
already-complete instantiations.

gcc/ChangeLog:

* doc/invoke.texi: Move C++ -fdump-lang to C++ section.
Add -fdump-lang-tinst.

Diff:
---
 gcc/doc/invoke.texi   |  72 --
 gcc/cp/cp-tree.h  |   1 +
 gcc/cp/cp-objcp-common.cc |   2 +
 gcc/cp/pt.cc  | 111 +++---
 4 files changed, 145 insertions(+), 41 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index fe47ce564873..e3bc833c59bd 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -3297,6 +3297,50 @@ Enable support for the C++ coroutines extension 
(experimental).
 Permit the C++ front end to note all candidates during overload resolution
 failure, including when a deleted function is selected.
 
+@item -fdump-lang-
+@itemx -fdump-lang-@var{switch}
+@itemx -fdump-lang-@var{switch}-@var{options}
+@itemx -fdump-lang-@var{switch}-@var{options}=@var{filename}
+Control the dumping of C++-specific information.  The @var{options}
+and @var{filename} portions behave as described in the
+@option{-fdump-tree} option.  The following @var{switch} values are
+accepted:
+
+@table @samp
+@item all
+Enable all of the below.
+
+@opindex fdump-lang-class
+@item class
+Dump class hierarchy information.  Virtual table information is emitted
+unless '@option{slim}' is specified.
+
+@opindex fdump-lang-module
+@item module
+Dump module information.  Options @option{lineno} (locations),
+@option{graph} (reachability), @option{blocks} (clusters),
+@option{uid} (serialization), @option{alias} (mergeable),
+@option{asmname} (Elrond), @option{eh} (mapper) & @option{vops}
+(macros) may provide additional information.
+
+@opindex fdump-lang-raw
+@item raw
+Dump the raw internal tree data.
+
+@opindex fdump-lang-tinst
+@item tinst
+Dump the sequence of template instantiations, indented to show the
+depth of recursion.  The @option{lineno} option adds the source
+location where the instantiation was triggered, and the
+@option{details} option also dumps pre-instantiation substitutions
+such as those performed during template argument deduction.
+
+Lines in the .tinst dump start with @samp{I} for an instantiation,
+@samp{S} for another substitution, and @samp{R[IS]} for the reopened
+context of a deferred instantiation.
+
+@end table
+
 @opindex fno-elide-constructors
 @opindex felide-constructors
 @item -fno-elide-constructors
@@ -20891,30 +20935,10 @@ Dump language-specific information.  The file name is 
made by appending
 @itemx -fdump-lang-@var{switch}-@var{options}=@var{filename}
 Control the dumping of language-specific information.  The @var{options}
 and @var{filename} portions behave as described in the
-@option{-fdump-tree} option.  The following @var{switch} values are
-accepted:
-
-@table @samp
-@item all
-
-Enable all language-specific dumps.
-
-@item class
-Dump class hierarchy information.  Virtual table information is emitted
-unless '@option{slim}' is specified.  This option is applicable to C++ only.
-
-@item module
-Dump module information.  Options @option{lineno} (locations),
-@option{graph} (reachability), @option{blocks} (clusters),
-@option{uid} (serialization), @option{alias} (mergeable),
-@option{asmname} (Elrond), @option{eh} (mapper) & @option{vops}
-(macros) may provide additional information.  This option is
-applicable to C++ only.
-
-@item raw
-Dump the raw internal tree data.  This option is applicable to C++ only.
-
-@end table
+@option{-fdump-tree} option.  @option{-fdump-tree-all} enables all
+language-specific dumps; other options vary with the language.  For
+instance, see @xref{C++ Dialect Options} for the @option{-fdump-lang}
+flags supported by the C++ front-end.
 
 @opindex fdump-passes
 @item -fdump-passes
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 7433b8962199..19c0b452d868 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6822,6 +6822,7 @@ extern int class_dump_i

[gcc r16-879] c++: add cxx_dump_pretty_printer

2025-05-26 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:d424245c7abb2871b977ddc5c1e73b827a78ad07

commit r16-879-gd424245c7abb2871b977ddc5c1e73b827a78ad07
Author: Jason Merrill 
Date:   Thu Apr 17 16:29:49 2025 -0400

c++: add cxx_dump_pretty_printer

A class to simplify implementation of -fdump-lang-foo with support for
pp_printf using %D and such.

gcc/cp/ChangeLog:

* cp-tree.h (class cxx_dump_pretty_printer): New.
* error.cc (cxx_dump_pretty_printer): Ctor/dtor definitions.

Diff:
---
 gcc/cp/cp-tree.h | 23 +++
 gcc/cp/error.cc  | 27 +++
 2 files changed, 50 insertions(+)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 175ab2874903..7433b8962199 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7322,6 +7322,29 @@ extern void cp_check_const_attributes (tree);
 extern void maybe_propagate_warmth_attributes (tree, tree);
 
 /* in error.cc */
+/* A class for pretty-printing to -flang-dump-XXX files.  Used like
+
+   if (cxx_dump_pretty_printer pp {foo_dump_id})
+ {
+   pp_printf (&pp, ...);
+ }
+
+   If the dump is enabled, the pretty printer will open the dump file and
+   attach to it, and flush and close the file on destruction.  */
+
+class cxx_dump_pretty_printer: public pretty_printer
+{
+  int phase;
+  FILE *outf;
+  dump_flags_t flags;
+
+public:
+  cxx_dump_pretty_printer (int phase);
+  operator bool() { return outf != nullptr; }
+  bool has_flag (dump_flags_t f) { return (flags & f); }
+  ~cxx_dump_pretty_printer ();
+};
+
 extern const char *type_as_string  (tree, int);
 extern const char *type_as_string_translate(tree, int);
 extern const char *decl_as_string  (tree, int);
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 305064d476c4..d52dad3db293 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -193,6 +193,33 @@ class cxx_format_postprocessor : public 
format_postprocessor
   deferred_printed_type m_type_b;
 };
 
+/* Constructor and destructor for cxx_dump_pretty_printer, defined here to
+   avoid needing to move cxx_format_postprocessor into the header as well.  */
+
+cxx_dump_pretty_printer::
+cxx_dump_pretty_printer (int phase)
+  : phase (phase)
+{
+  outf = dump_begin (phase, &flags);
+  if (outf)
+{
+  pp_format_decoder (this) = cp_printer;
+  /* This gets deleted in ~pretty_printer.  */
+  pp_format_postprocessor (this) = new cxx_format_postprocessor ();
+  set_output_stream (outf);
+}
+}
+
+cxx_dump_pretty_printer::
+~cxx_dump_pretty_printer ()
+{
+  if (outf)
+{
+  pp_flush (this);
+  dump_end (phase, outf);
+}
+}
+
 /* Return the in-scope template that's currently being parsed, or
NULL_TREE otherwise.  */


[gcc r13-9687] c++: format attribute redeclaration [PR116954]

2025-05-26 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:bde3ca83ffe99088718198ea643bed7c4b22bbf1

commit r13-9687-gbde3ca83ffe99088718198ea643bed7c4b22bbf1
Author: Jason Merrill 
Date:   Wed Apr 16 11:15:14 2025 -0400

c++: format attribute redeclaration [PR116954]

Here when merging the two decls, remove_contract_attributes loses
ATTR_IS_DEPENDENT on the format attribute, so apply_late_template_attributes
just returns, so the attribute doesn't get propagated to the type where the
warning looks for it.

Fixed by using copy_node instead of tree_cons to preserve flags.

PR c++/116954

gcc/cp/ChangeLog:

* contracts.cc (remove_contract_attributes): Preserve flags
on the attribute list.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Wformat-3.C: New test.

(cherry picked from commit b0d7d644f3c25af9bf60c948ab26aa7b09a68787)

Diff:
---
 gcc/cp/contracts.cc   |  9 -
 gcc/testsuite/g++.dg/warn/Wformat-3.C | 19 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc
index 18482e5c4c85..d3ac71570a3b 100644
--- a/gcc/cp/contracts.cc
+++ b/gcc/cp/contracts.cc
@@ -869,10 +869,17 @@ cp_contract_assertion_p (const_tree attr)
 void
 remove_contract_attributes (tree fndecl)
 {
+  if (!flag_contracts)
+return;
+
   tree list = NULL_TREE;
   for (tree p = DECL_ATTRIBUTES (fndecl); p; p = TREE_CHAIN (p))
 if (!cxx_contract_attribute_p (p))
-  list = tree_cons (TREE_PURPOSE (p), TREE_VALUE (p), list);
+  {
+   tree nl = copy_node (p);
+   TREE_CHAIN (nl) = list;
+   list = nl;
+  }
   DECL_ATTRIBUTES (fndecl) = nreverse (list);
 }
 
diff --git a/gcc/testsuite/g++.dg/warn/Wformat-3.C 
b/gcc/testsuite/g++.dg/warn/Wformat-3.C
new file mode 100644
index ..e308530761c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wformat-3.C
@@ -0,0 +1,19 @@
+// PR c++/116954
+// { dg-additional-options -Wformat }
+
+#ifndef WORKS
+template
+int fn(char (&buf)[N], const char fmt[], ...)
+  __attribute__ ((__format__ (__printf__, 2, 3)));
+#endif
+
+template
+__attribute__ ((__format__ (__printf__, 2, 3)))
+int fn(char (&)[N], const char [], ...)
+{ return 0; }
+
+int main()
+{
+  char buf[20];
+  return fn(buf, "%s", 42); /* { dg-warning "Wformat" } */
+}