[gcc r15-3637] c++: Fix g++.dg/ext/sve-sizeless-1.C regression

2024-09-14 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:bec1f2ce4ad3fe56906d6429b542a290e574b3eb

commit r15-3637-gbec1f2ce4ad3fe56906d6429b542a290e574b3eb
Author: Jonathan Wakely 
Date:   Fri Sep 13 08:18:53 2024 +0100

c++: Fix g++.dg/ext/sve-sizeless-1.C regression

This aarch64-*-* test needs an update for the diagnostic I changed in
r15-3614-g9fe57e4879de93.

gcc/testsuite/ChangeLog:

* g++.dg/ext/sve-sizeless-1.C: Adjust dg-error string.

Diff:
---
 gcc/testsuite/g++.dg/ext/sve-sizeless-1.C | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C 
b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
index 9f05ca5a855a..adee37a0551e 100644
--- a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
+++ b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
@@ -301,7 +301,7 @@ statements (int n)
 
   // Other built-ins
 
-  __builtin_launder (sve_sc1); // { dg-error {non-pointer argument to 
'__builtin_launder'} }
+  __builtin_launder (sve_sc1); // { dg-error {not a pointer to object type} }
   __builtin_memcpy (&sve_sc1, &sve_sc2, 2);
 
   // Lambdas


[gcc r15-3638] testsuite: adjust pragma-diag-17.c diagnostics

2024-09-14 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:49cb7150f0e93e8332f4b78753675b255a5c58f2

commit r15-3638-g49cb7150f0e93e8332f4b78753675b255a5c58f2
Author: Jason Merrill 
Date:   Fri Sep 13 15:52:02 2024 +0200

testsuite: adjust pragma-diag-17.c diagnostics

The Linaro CI runs of this testcase pointed out that I need to check for DFP
support, as well.

gcc/testsuite/ChangeLog:

* c-c++-common/pragma-diag-17.c: Handle !dfp targets.

Diff:
---
 gcc/testsuite/c-c++-common/pragma-diag-17.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/c-c++-common/pragma-diag-17.c 
b/gcc/testsuite/c-c++-common/pragma-diag-17.c
index a38841bc48d2..a44ce90f98b1 100644
--- a/gcc/testsuite/c-c++-common/pragma-diag-17.c
+++ b/gcc/testsuite/c-c++-common/pragma-diag-17.c
@@ -12,7 +12,7 @@ void f()
   0b0100; /* { dg-error "binary constant" "" { target { ! c++14 } } } 
*/
 #pragma GCC diagnostic ignored "-Wpedantic"
   2.0j;
-  1.0dd;
+  1.0dd; /* { dg-error "decimal floating-point" "" { target { ! dfp } } } */
   1.0d;
 
 #ifdef __cplusplus


[gcc r15-3640] libstdc++: Tweak localized formatting for floating-point types

2024-09-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:99b8be43d7c548db127ee4f4d0918c55edc68b3f

commit r15-3640-g99b8be43d7c548db127ee4f4d0918c55edc68b3f
Author: Jonathan Wakely 
Date:   Mon Apr 29 18:16:29 2024 +0100

libstdc++: Tweak localized formatting for floating-point types

libstdc++-v3/ChangeLog:

* include/std/format (__formatter_fp::_M_localize): Add comments
and micro-optimize string copy.

Diff:
---
 libstdc++-v3/include/std/format | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 52243eb54792..e963d7f79b33 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -1886,25 +1886,28 @@ namespace __format
if (__grp.empty() && __point == __dot)
  return __lstr; // Locale uses '.' and no grouping.
 
-   size_t __d = __str.find(__dot);
-   size_t __e = min(__d, __str.find(__exp));
+   size_t __d = __str.find(__dot); // Index of radix character (if any).
+   size_t __e = min(__d, __str.find(__exp)); // First of radix or exponent
if (__e == __str.npos)
  __e = __str.size();
-   const size_t __r = __str.size() - __e;
+   const size_t __r = __str.size() - __e; // Length of remainder.
auto __overwrite = [&](_CharT* __p, size_t) {
+ // Apply grouping to the digits before the radix or exponent.
  auto __end = std::__add_grouping(__p, __np.thousands_sep(),
   __grp.data(), __grp.size(),
   __str.data(), __str.data() + __e);
- if (__r)
+ if (__r) // If there's a fractional part or exponent
{
  if (__d != __str.npos)
{
- *__end = __point;
+ *__end = __point; // Add the locale's radix character.
  ++__end;
  ++__e;
}
- if (__r > 1)
-   __end += __str.copy(__end, __str.npos, __e);
+ const size_t __rlen = __str.size() - __e;
+ // Append fractional digits and/or exponent:
+ char_traits<_CharT>::copy(__end, __str.data() + __e, __rlen);
+ __end += __rlen;
}
  return (__end - __p);
};


[gcc r15-3639] libstdc++: Refactor loops in std::__platform_semaphore

2024-09-14 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:01670a4095791733e0389acead832e3da757c9d7

commit r15-3639-g01670a4095791733e0389acead832e3da757c9d7
Author: Jonathan Wakely 
Date:   Mon Sep 2 12:29:04 2024 +0100

libstdc++: Refactor loops in std::__platform_semaphore

Refactor the loops to all use the same form, and to not need explicit
'break' or 'continue' jumps. This also avoids a -Wunused-variable
warning with -Wsystem-headers.

Also fix a bug for absolute timeouts specified with a time that isn't
implicitly convertible to __clock_t::time_point, e.g. one with a higher
resolution such as picoseconds. Use chrono::ceil to round up to the next
time point representable by the clock.

libstdc++-v3/ChangeLog:

* include/bits/semaphore_base.h (__platform_semaphore): Refactor
loops to all use similar forms.
(__platform_semaphore::_M_try_acquire_until): Use chrono::ceil
to explicitly convert to __clock_t::time_point.
* testsuite/30_threads/semaphore/try_acquire_for.cc: Check that
using a very high resolution timeout compiles.
* testsuite/30_threads/semaphore/platform_try_acquire_for.cc:
New test.

Diff:
---
 libstdc++-v3/include/bits/semaphore_base.h | 58 --
 .../semaphore/platform_try_acquire_for.cc  |  7 +++
 .../30_threads/semaphore/try_acquire_for.cc| 13 +
 3 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/libstdc++-v3/include/bits/semaphore_base.h 
b/libstdc++-v3/include/bits/semaphore_base.h
index 44a68645e477..2b19c9c6c6ac 100644
--- a/libstdc++-v3/include/bits/semaphore_base.h
+++ b/libstdc++-v3/include/bits/semaphore_base.h
@@ -73,52 +73,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_ALWAYS_INLINE void
 _M_acquire() noexcept
 {
-  for (;;)
-   {
- auto __err = sem_wait(&_M_semaphore);
- if (__err && (errno == EINTR))
-   continue;
- else if (__err)
-   std::__terminate();
- else
-   break;
-   }
+  while (sem_wait(&_M_semaphore))
+   if (errno != EINTR)
+ std::__terminate();
 }
 
 _GLIBCXX_ALWAYS_INLINE bool
 _M_try_acquire() noexcept
 {
-  for (;;)
+  while (sem_trywait(&_M_semaphore))
{
- auto __err = sem_trywait(&_M_semaphore);
- if (__err && (errno == EINTR))
-   continue;
- else if (__err && (errno == EAGAIN))
+ if (errno == EAGAIN) // already locked
return false;
- else if (__err)
+ else if (errno != EINTR)
std::__terminate();
- else
-   break;
+ // else got EINTR so retry
}
   return true;
 }
 
 _GLIBCXX_ALWAYS_INLINE void
-_M_release(std::ptrdiff_t __update) noexcept
+_M_release(ptrdiff_t __update) noexcept
 {
   for(; __update != 0; --__update)
-   {
-  auto __err = sem_post(&_M_semaphore);
-  if (__err)
-std::__terminate();
-   }
+   if (sem_post(&_M_semaphore))
+ std::__terminate();
 }
 
 bool
 _M_try_acquire_until_impl(const chrono::time_point<__clock_t>& __atime)
   noexcept
 {
-
   auto __s = chrono::time_point_cast(__atime);
   auto __ns = chrono::duration_cast(__atime - __s);
 
@@ -128,19 +113,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_cast(__ns.count())
   };
 
-  for (;;)
+  while (sem_timedwait(&_M_semaphore, &__ts))
{
- if (auto __err = sem_timedwait(&_M_semaphore, &__ts))
-   {
- if (errno == EINTR)
-   continue;
- else if (errno == ETIMEDOUT || errno == EINVAL)
-   return false;
- else
-   std::__terminate();
-   }
- else
-   break;
+ if (errno == ETIMEDOUT)
+   return false;
+ else if (errno != EINTR)
+   std::__terminate();
}
   return true;
 }
@@ -152,10 +130,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
if constexpr (std::is_same_v<__clock_t, _Clock>)
  {
-   return _M_try_acquire_until_impl(__atime);
+   using _Dur = __clock_t::duration;
+   return _M_try_acquire_until_impl(chrono::ceil<_Dur>(__atime));
  }
else
  {
+   // TODO: if _Clock is monotonic_clock we could use
+   // sem_clockwait with CLOCK_MONOTONIC.
+
const typename _Clock::time_point __c_entry = _Clock::now();
const auto __s_entry = __clock_t::now();
const auto __delta = __atime - __c_entry;
diff --git 
a/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc 
b/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc
new file mode 100644
index ..bf6cd142bf01
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.

[gcc r15-3641] AVR: Use rtx code copysign.

2024-09-14 Thread Georg-Johann Lay via Gcc-cvs
https://gcc.gnu.org/g:a900349485cc4753084527bf0234f173967979b0

commit r15-3641-ga900349485cc4753084527bf0234f173967979b0
Author: Georg-Johann Lay 
Date:   Sat Sep 14 10:12:54 2024 +0200

AVR: Use rtx code copysign.

gcc/
* config/avr/avr.md (UNSPEC_COPYSIGN): Remove define_enum.
(copysignsf3): Use copysign instead of UNSPEC_COPYSIGN.
Allow const_double for operand 2.

Diff:
---
 gcc/config/avr/avr.md | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 429f537b7d4f..2abf3c38d836 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -87,7 +87,6 @@
UNSPEC_FMUL
UNSPEC_FMULS
UNSPEC_FMULSU
-   UNSPEC_COPYSIGN
UNSPEC_INSERT_BITS
UNSPEC_ROUND
])
@@ -9272,12 +9271,18 @@
 ;; Copysign
 
 (define_insn "copysignsf3"
-  [(set (match_operand:SF 0 "register_operand" "=r")
-(unspec:SF [(match_operand:SF 1 "register_operand"  "0")
-(match_operand:SF 2 "register_operand"  "r")]
-   UNSPEC_COPYSIGN))]
+  [(set (match_operand:SF 0 "register_operand"  "=r")
+(copysign:SF (match_operand:SF 1 "register_operand"  "0")
+ (match_operand:SF 2 "nonmemory_operand" "rF")))]
   ""
-  "bst %D2,7\;bld %D0,7"
+  {
+if (const_double_operand (operands[2], SFmode))
+  {
+rtx xmsb = simplify_gen_subreg (QImode, operands[2], SFmode, 3);
+return INTVAL (xmsb) < 0 ? "set\;bld %D0,7" : "clt\;bld %D0,7";
+  }
+return "bst %D2,7\;bld %D0,7";
+  }
   [(set_attr "length" "2")])
 
 ;; Swap Bytes (change byte-endianness)


[gcc r15-3642] c++: Don't mix timevar_start and auto_cond_timevar for TV_NAME_LOOKUP [PR116681]

2024-09-14 Thread Simon Martin via Gcc-cvs
https://gcc.gnu.org/g:005f7176e0f457a1e1a7398ddcb4a4972da28c62

commit r15-3642-g005f7176e0f457a1e1a7398ddcb4a4972da28c62
Author: Simon Martin 
Date:   Fri Sep 13 16:40:22 2024 +0200

c++: Don't mix timevar_start and auto_cond_timevar for TV_NAME_LOOKUP 
[PR116681]

We currently ICE upon the following testcase when using -ftime-report

=== cut here ===
template < int> using __conditional_t = int;
template < typename _Iter >
concept random_access_iterator = requires { new _Iter; };
template < typename _Iterator >
struct reverse_iterator {
  using iterator_concept =
__conditional_t< random_access_iterator< _Iterator>>;
};
void RemoveBottom() {
  int iter;
  for (reverse_iterator< int > iter;;)
  ;
}
=== cut here ===

The problem is that qualified_namespace_lookup does a plain start() of
the TV_NAME_LOOKUP timer (that asserts that the timer is not already
started). However this timer has already been cond_start()'d in the call
stack - by pushdecl - so the assert fails.

This patch simply ensures that we always conditionally start this timer
(which is done in all other places that use it).

PR c++/116681

gcc/cp/ChangeLog:

* name-lookup.cc (qualified_namespace_lookup): Use an
auto_cond_timer instead of using timevar_start and timevar_stop.

gcc/testsuite/ChangeLog:

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

Diff:
---
 gcc/cp/name-lookup.cc  |  3 +--
 gcc/testsuite/g++.dg/cpp2a/concepts-pr116681.C | 20 
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index bfe17b7cb2fc..c7a693e02d59 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -7421,10 +7421,9 @@ tree lookup_qualified_name (tree t, const char *p, 
LOOK_want w, bool c)
 static bool
 qualified_namespace_lookup (tree scope, name_lookup *lookup)
 {
-  timevar_start (TV_NAME_LOOKUP);
+  auto_cond_timevar tv (TV_NAME_LOOKUP);
   query_oracle (lookup->name);
   bool found = lookup->search_qualified (ORIGINAL_NAMESPACE (scope));
-  timevar_stop (TV_NAME_LOOKUP);
   return found;
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr116681.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-pr116681.C
new file mode 100644
index ..f1b47797f1ed
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr116681.C
@@ -0,0 +1,20 @@
+// PR c++/116681
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-ftime-report" }
+// { dg-allow-blank-lines-in-output 1 }
+// { dg-prune-output "Time variable" }
+// { dg-prune-output "k" }
+// { dg-prune-output "\[0-9\]+%" }
+
+template < int> using __conditional_t = int;
+template < typename _Iter >
+concept random_access_iterator = requires { new _Iter; };
+template < typename _Iterator > struct reverse_iterator {
+  using iterator_concept = __conditional_t< random_access_iterator< _Iterator 
>>;
+};
+void RemoveBottom()
+{
+  int iter;
+  for (reverse_iterator< int > iter;;)
+  ;
+}


[gcc r15-3643] c++: avoid init_priority warning in system header

2024-09-14 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:8b5e54712a1efd1bf0c08a3d9523ab0c265e344a

commit r15-3643-g8b5e54712a1efd1bf0c08a3d9523ab0c265e344a
Author: Jason Merrill 
Date:   Sat Sep 14 11:46:22 2024 +0200

c++: avoid init_priority warning in system header

We don't want a warning about a reserved init_priority in a system header
even with -Wsystem-headers.

gcc/cp/ChangeLog:

* tree.cc (handle_init_priority_attribute): Check
in_system_header_at.

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

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 99088da9cee0..f43febed124c 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -5196,7 +5196,8 @@ handle_init_priority_attribute (tree* node,
 
   /* Check for init_priorities that are reserved for
  language and runtime support implementations.*/
-  if (pri <= MAX_RESERVED_INIT_PRIORITY)
+  if (pri <= MAX_RESERVED_INIT_PRIORITY
+  && !in_system_header_at (input_location))
 {
   warning
(0, "requested % %i is reserved for internal use",


[gcc r15-3644] testsuite; Fix execute/pr52286.c for 16bit

2024-09-14 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:1dd6dd18783c3a7411b494f8b9d911cea784a270

commit r15-3644-g1dd6dd18783c3a7411b494f8b9d911cea784a270
Author: Andrew Pinski 
Date:   Sat Sep 14 12:55:07 2024 -0700

testsuite; Fix execute/pr52286.c for 16bit

The code path which was added for 16bit had a broken inline-asm which would
only assign maybe half of the registers for the `long` type to 0.

Adding L to the input operand of the inline-asm fixes the issue by now 
assigning
the full 32bit value of the input register that would match up with the 
output register.

Fixes r0-115223-gb0408f13d4b317 which added the 16bit code path to fix the 
testcase for 16bit.

Pushed as obvious.

PR testsuite/116716

gcc/testsuite/ChangeLog:

* gcc.c-torture/execute/pr52286.c: Fix inline-asm for 16bit case.

Diff:
---
 gcc/testsuite/gcc.c-torture/execute/pr52286.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.c-torture/execute/pr52286.c 
b/gcc/testsuite/gcc.c-torture/execute/pr52286.c
index bb56295ab529..4fd5d6ac813d 100644
--- a/gcc/testsuite/gcc.c-torture/execute/pr52286.c
+++ b/gcc/testsuite/gcc.c-torture/execute/pr52286.c
@@ -11,7 +11,7 @@ main ()
   b = (~a | 1) & -2038094497;
 #else
   long a, b;
-  asm ("" : "=r" (a) : "0" (0));
+  asm ("" : "=r" (a) : "0" (0L));
   b = (~a | 1) & -2038094497L;
 #endif
   if (b >= 0)


[gcc r15-3646] Mark the copy/move constructor/operator= of auto_bitmap as delete

2024-09-14 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:d2f10fc934c3a425cf31979b1cf41fdc0f57c6d6

commit r15-3646-gd2f10fc934c3a425cf31979b1cf41fdc0f57c6d6
Author: Andrew Pinski 
Date:   Fri Sep 13 20:17:15 2024 -0700

Mark the copy/move constructor/operator= of auto_bitmap as delete

Since we are written in C++11, these should be marked as delete rather
than just private.

Bootstrapped and tested on x86_64-linux-gnu.

gcc/ChangeLog:

* bitmap.h (class auto_bitmap): Mark copy/move constructor/operator=
as deleted.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/bitmap.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/bitmap.h b/gcc/bitmap.h
index 4cad1b4d6c6a..451edcfc5907 100644
--- a/gcc/bitmap.h
+++ b/gcc/bitmap.h
@@ -959,10 +959,10 @@ class auto_bitmap
 
  private:
   // Prevent making a copy that references our bitmap.
-  auto_bitmap (const auto_bitmap &);
-  auto_bitmap &operator = (const auto_bitmap &);
-  auto_bitmap (auto_bitmap &&);
-  auto_bitmap &operator = (auto_bitmap &&);
+  auto_bitmap (const auto_bitmap &) = delete;
+  auto_bitmap &operator = (const auto_bitmap &) = delete;
+  auto_bitmap (auto_bitmap &&) = delete;
+  auto_bitmap &operator = (auto_bitmap &&) = delete;
 
   bitmap_head m_bits;
 };


[gcc r15-3647] vect: release defs of removed statement

2024-09-14 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:0b3133572edbd2b382e160ac78d7caf321f7f05b

commit r15-3647-g0b3133572edbd2b382e160ac78d7caf321f7f05b
Author: Andrew Pinski 
Date:   Fri Sep 13 20:27:32 2024 -0700

vect: release defs of removed statement

While trying to add use of simple_dce_from_worklist
to the vectorizer so we don't need to run a full blown
DCE pass after the vectorizer, there was a crash noticed
due to a ssa name which has a stmt without a bb. This was
due to not calling release_defs after the call to gsi_remove.

Note the code to remove zero use statements should be able to
remove once the use of simple_dce_from_worklist has been added.
But in the meantime, fixing this bug will also improve memory
usage and a few other things which look through all ssa names.

gcc/ChangeLog:

* tree-vect-loop.cc (optimize_mask_stores): Call release_defs
after the call to gsi_remove with last argument of true.

Signed-off-by: Andrew Pinski 

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

diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index cc15492f6a01..62c7f90779fa 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -12803,6 +12803,7 @@ optimize_mask_stores (class loop *loop)
  if (has_zero_uses (lhs))
{
  gsi_remove (&gsi_from, true);
+ release_defs (stmt1);
  continue;
}
}


[gcc r15-3648] phi-opt: Improve heuristics for factoring out with constant (again) [PR116699]

2024-09-14 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:6e4244e8ceac939fe8a24470b4ff31c82e8bff21

commit r15-3648-g6e4244e8ceac939fe8a24470b4ff31c82e8bff21
Author: Andrew Pinski 
Date:   Fri Sep 13 10:47:29 2024 -0700

phi-opt: Improve heuristics for factoring out with constant (again) 
[PR116699]

The heuristics for factoring out with a constant checks that the assignment 
statement
is the last statement of the basic block but sometimes there is a predicate 
or a nop statement
after the assignment. Rejecting this case does not make sense since both 
predicates and nop
statements are removed and don't contribute any instructions. So we should 
skip over them
when checking if the assignment statement was the last statement in the 
basic block.

phi-opt-factor-1.c's f0 is such an example where it should catch it at 
phiopt1 (before predicates are removed)
and should happen in a similar way as f1 (which uses a temporary variable 
rather than return).

Bootstrapped and tested on x86_64-linux-gnu.

PR tree-optimization/116699

gcc/ChangeLog:

* tree-ssa-phiopt.cc (factor_out_conditional_operation): Skip over 
nop/predicates
for seeing the assignment is the last statement.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/phi-opt-factor-1.c: New test.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-factor-1.c | 26 
 gcc/tree-ssa-phiopt.cc   |  6 ++
 2 files changed, 32 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-factor-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-factor-1.c
new file mode 100644
index ..12b846b9337f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-factor-1.c
@@ -0,0 +1,26 @@
+/* { dg-options "-O2 -fdump-tree-phiopt" } */
+
+/* PR tree-optimization/116699
+   Make sure the return PREDICT has no factor in deciding
+   if we factor out the conversion. */
+
+short f0(int a, int b, int c)
+{
+  int t1 = 4;
+  if (c < t1)  return (c > -1 ? c : -1);
+  return t1;
+}
+
+
+short f1(int a, int b, int c)
+{
+  int t1 = 4;
+  short t = t1;
+  if (c < t1)  t = (c > -1 ? c : -1);
+  return t;
+}
+
+/* Both f1 and f0  should be optimized at phiopt1 to the same thing. */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR " 2 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR " 2  "phiopt1" } } */
+/* { dg-final { scan-tree-dump-not "if " "phiopt1" } } */
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index e5413e405722..7b12692237e5 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -360,6 +360,12 @@ factor_out_conditional_operation (edge e0, edge e1, gphi 
*phi,
}
  gsi = gsi_for_stmt (arg0_def_stmt);
  gsi_next_nondebug (&gsi);
+ /* Skip past nops and predicates. */
+ while (!gsi_end_p (gsi)
+ && (gimple_code (gsi_stmt (gsi)) == GIMPLE_NOP
+ || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
+   gsi_next_nondebug (&gsi);
+ /* Reject if the statement was not at the end of the block. */
  if (!gsi_end_p (gsi))
return NULL;
}


[gcc r15-3649] c++, coroutines: Fix handling of bool await_suspend() [PR115905].

2024-09-14 Thread Iain D Sandoe via Gcc-cvs
https://gcc.gnu.org/g:368ba7aed46d57d093c0180baae4dc0e0ba468b6

commit r15-3649-g368ba7aed46d57d093c0180baae4dc0e0ba468b6
Author: Iain Sandoe 
Date:   Fri Sep 6 20:59:43 2024 +0100

c++, coroutines: Fix handling of bool await_suspend() [PR115905].

As noted in the PR the action of the existing implementation was to
treat a false value from await_suspend () as equivalent to "do not
suspend".  Actually it needs to be the equivalent of "resume" - and
we need to restart the dispatcher - since the await_suspend() body
could have already resumed the coroutine.
See also https://github.com/cplusplus/CWG/issues/601 (NAD) for more
discussion.

Since we need to amend the await expansion and the actor build, take
the opportunity to clean up and modernise the code there.  Note that
we need to make the jump back to the dispatcher without any scope
exit cleanups (so we have to use the .CO_SUSPN IFN to do this).

PR c++/115905

gcc/cp/ChangeLog:

* coroutines.cc (struct coro_aw_data): Add a member for the
restart dispatch label.
(expand_one_await_expression): Rework to modernise and to
handle the boolean await_suspend() case.
(build_actor_fn): Rework the dispatcher and allow for a jump
back to the dispatcher.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/torture/pr115905.C: New test.

Signed-off-by: Iain Sandoe 

Diff:
---
 gcc/cp/coroutines.cc   | 215 +++--
 gcc/testsuite/g++.dg/coroutines/torture/pr115905.C |  64 ++
 2 files changed, 174 insertions(+), 105 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index d6acf09326f9..002d575f3324 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1780,6 +1780,7 @@ struct coro_aw_data
   tree cleanup;/* This is where to go once we complete local destroy.  */
   tree cororet;/* This is where to go if we suspend.  */
   tree corocont;   /* This is where to go if we continue.  */
+  tree dispatch;   /* This is where we go if we restart the dispatch.  */
   tree conthand;   /* This is the handle for a continuation.  */
   unsigned index;  /* This is our current resume index.  */
 };
@@ -1824,42 +1825,44 @@ co_await_find_in_subtree (tree *stmt, int *, void *d)
in either.  */
 
 static tree *
-expand_one_await_expression (tree *stmt, tree *await_expr, void *d)
+expand_one_await_expression (tree *expr, tree *await_expr, void *d)
 {
   coro_aw_data *data = (coro_aw_data *) d;
 
-  tree saved_statement = *stmt;
+  tree saved_statement = *expr;
   tree saved_co_await = *await_expr;
 
   tree actor = data->actor_fn;
-  location_t loc = EXPR_LOCATION (*stmt);
+  location_t loc = EXPR_LOCATION (*expr);
   tree var = TREE_OPERAND (saved_co_await, 1);  /* frame slot. */
-  tree expr = TREE_OPERAND (saved_co_await, 2); /* initializer.  */
+  tree init_expr = TREE_OPERAND (saved_co_await, 2); /* initializer.  */
   tree awaiter_calls = TREE_OPERAND (saved_co_await, 3);
 
   tree source = TREE_OPERAND (saved_co_await, 4);
   bool is_final = (source
   && TREE_INT_CST_LOW (source) == (int) FINAL_SUSPEND_POINT);
-  bool needs_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var));
+
+  /* Build labels for the destinations of the control flow when we are resuming
+ or destroying.  */
   int resume_point = data->index;
-  size_t bufsize = sizeof ("destroy.") + 10;
-  char *buf = (char *) alloca (bufsize);
-  snprintf (buf, bufsize, "destroy.%d", resume_point);
+  char *buf = xasprintf ("destroy.%d", resume_point);
   tree destroy_label = create_named_label_with_ctx (loc, buf, actor);
-  snprintf (buf, bufsize, "resume.%d", resume_point);
+  free (buf);
+  buf = xasprintf ("resume.%d", resume_point);
   tree resume_label = create_named_label_with_ctx (loc, buf, actor);
-  tree empty_list = build_empty_stmt (loc);
+  free (buf);
 
-  tree stmt_list = NULL;
-  tree r;
+  /* This will contain our expanded expression and replace the original
+ expression.  */
+  tree stmt_list = push_stmt_list ();
   tree *await_init = NULL;
 
-  if (!expr)
+  bool needs_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var));
+  if (!init_expr)
 needs_dtor = false; /* No need, the var's lifetime is managed elsewhere.  
*/
   else
 {
-  r = coro_build_cvt_void_expr_stmt (expr, loc);
-  append_to_statement_list_force (r, &stmt_list);
+  finish_expr_stmt (init_expr);
   /* We have an initializer, which might itself contain await exprs.  */
   await_init = tsi_stmt_ptr (tsi_last (stmt_list));
 }
@@ -1870,18 +1873,15 @@ expand_one_await_expression (tree *stmt, tree 
*await_expr, void *d)
   if (TREE_CODE (TREE_TYPE (ready_cond)) != BOOLEAN_TYPE)
 ready_cond = cp_convert (boolean_type_node, ready_cond,
 tf_warning_or_error);
+  tree susp_if = begin_if_stmt ();