[gcc r14-11271] Fortran: F2008 passing of internal procs to a proc pointer [PR117434]

2025-02-03 Thread Jerry DeLisle via Gcc-cvs
https://gcc.gnu.org/g:65ecfbabb018896b600065c77f969475a43d529d

commit r14-11271-g65ecfbabb018896b600065c77f969475a43d529d
Author: Paul Thomas 
Date:   Wed Nov 6 07:17:25 2024 +

Fortran: F2008 passing of internal procs to a proc pointer [PR117434]

2024-11-06  Paul Thomas  

gcc/fortran
PR fortran/117434
* interface.cc (gfc_compare_actual_formal): Skip 'Expected a
procedure pointer error' if the formal argument typespec has an
interface and the type of the actual arg is BT_PROCEDURE.

gcc/testsuite/
PR fortran/117434
* gfortran.dg/proc_ptr_54.f90: New test. This is temporarily
compile-only until one one seven four five five is fixed.
* gfortran.dg/proc_ptr_55.f90: New test.
* gfortran.dg/proc_ptr_56.f90: New test.

(cherry picked from commit 4dbf4c0fdb188e1c348688de91e010f696cd59fc)

Diff:
---
 gcc/fortran/interface.cc  |  9 ++-
 gcc/testsuite/gfortran.dg/proc_ptr_54.f90 | 95 +++
 gcc/testsuite/gfortran.dg/proc_ptr_55.f90 | 87 
 gcc/testsuite/gfortran.dg/proc_ptr_56.f90 | 45 +++
 4 files changed, 234 insertions(+), 2 deletions(-)

diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index bf151dae7439..c4f3a3b03fbe 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -3495,12 +3495,17 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, 
gfc_formal_arglist *formal,
 
  skip_size_check:
 
-  /* Satisfy F03:12.4.1.3 by ensuring that a procedure pointer actual
- argument is provided for a procedure pointer formal argument.  */
+  /* Satisfy either: F03:12.4.1.3 by ensuring that a procedure pointer
+actual argument is provided for a procedure pointer formal argument;
+or: F08:12.5.2.9 (F18:15.5.2.10) by ensuring that the effective
+argument shall be an external, internal, module, or dummy procedure.
+The interfaces are checked elsewhere.  */
   if (f->sym->attr.proc_pointer
  && !((a->expr->expr_type == EXPR_VARIABLE
&& (a->expr->symtree->n.sym->attr.proc_pointer
|| gfc_is_proc_ptr_comp (a->expr)))
+  || (a->expr->ts.type == BT_PROCEDURE
+  && f->sym->ts.interface)
   || (a->expr->expr_type == EXPR_FUNCTION
   && is_procptr_result (a->expr
{
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_54.f90 
b/gcc/testsuite/gfortran.dg/proc_ptr_54.f90
new file mode 100644
index ..e03ecb507400
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_54.f90
@@ -0,0 +1,95 @@
+! { dg-do compile }
+!
+! Test the fix for pr117434, in which the F2008 addition of being permitted to
+! pass an external, internal or module procedure to a dummy procedure pointer
+! gave the error "Expected a procedure pointer for argument ‘’ at 
(1).
+!
+! This testcase checks for correct results.
+!
+! Contributed by Damian Rouson  
+!
+module julienne_test_description_m
+  implicit none
+
+  abstract interface
+logical function test_function_i(arg)
+  integer, intent(in) :: arg
+end function
+  end interface
+
+  type test_description_t
+procedure(test_function_i), pointer, nopass :: test_function_
+  end type
+
+
+contains
+
+  type(test_description_t) function new_test_description(test_function)
+procedure(test_function_i), intent(in), pointer :: test_function
+new_test_description%test_function_ => test_function
+  end function
+
+end module
+
+module test_mod
+
+contains
+
+  logical function mod_test(arg)
+integer, intent(in) :: arg
+if (arg == 1) then
+  mod_test = .true.
+else
+  mod_test = .false.
+endif
+  end function
+
+end
+
+logical function ext_test(arg)
+  integer, intent(in) :: arg
+  if (arg == 2) then
+ext_test = .true.
+  else
+ext_test = .false.
+  endif
+end function
+
+  use julienne_test_description_m
+  use test_mod
+  implicit none
+  type(test_description_t) test_description
+
+  interface
+logical function ext_test(arg)
+  integer, intent(in) :: arg
+end function
+  end interface
+
+  test_description = new_test_description(test)
+  if (test_description%test_function_(1) &
+  .or. test_description%test_function_(2) &
+  .or. .not.test_description%test_function_(3)) stop 1
+
+  test_description = new_test_description(mod_test)
+  if (test_description%test_function_(2) &
+  .or. test_description%test_function_(3) &
+  .or. .not.test_description%test_function_(1)) stop 2
+
+  test_description = new_test_description(ext_test)
+  if (test_description%test_function_(1) &
+  .or. test_description%test_function_(3) &
+  .or. .not.test_description%test_function_(2)) stop 3
+
+contains
+
+  logical function test(arg)
+integer, intent(in) :: arg
+if (arg == 3) then
+  test = .true.
+else
+ 

[gcc r15-7337] c++: coroutines and range for [PR118491]

2025-02-03 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:ec716ad3f4bdccb6a2780161e74e3168efa68121

commit r15-7337-gec716ad3f4bdccb6a2780161e74e3168efa68121
Author: Jason Merrill 
Date:   Fri Jan 31 12:31:43 2025 -0500

c++: coroutines and range for [PR118491]

The implementation of extended range-for temporaries in r15-3840 confused
coroutines, because await_statement_walker and the like get confused by the
EXPR_STMT into thinking that the whole for-loop is a single expression
statement and try to process it accordingly.  Fixing this seems to be a
simple matter of dropping the EXPR_STMT.

PR c++/116914
PR c++/117231
PR c++/118470
PR c++/118491

gcc/cp/ChangeLog:

* semantics.cc (finish_for_stmt): Don't wrap the result of
pop_stmt_list in EXPR_STMT.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/coro-range-for1.C: New test.

Diff:
---
 gcc/cp/semantics.cc   |  1 -
 gcc/testsuite/g++.dg/coroutines/coro-range-for1.C | 38 +++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index ad9864c3a91a..73b49174de43 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -1709,7 +1709,6 @@ finish_for_stmt (tree for_stmt)
 {
   tree stmt = pop_stmt_list (FOR_INIT_STMT (for_stmt));
   FOR_INIT_STMT (for_stmt) = NULL_TREE;
-  stmt = build_stmt (EXPR_LOCATION (for_stmt), EXPR_STMT, stmt);
   stmt = maybe_cleanup_point_expr_void (stmt);
   add_stmt (stmt);
 }
diff --git a/gcc/testsuite/g++.dg/coroutines/coro-range-for1.C 
b/gcc/testsuite/g++.dg/coroutines/coro-range-for1.C
new file mode 100644
index ..eaf4d19e62cb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/coro-range-for1.C
@@ -0,0 +1,38 @@
+// PR c++/118491
+// { dg-do compile { target c++20 } }
+
+#include 
+
+struct task {
+  struct promise_type {
+task get_return_object() { return {}; }
+std::suspend_always initial_suspend() { return {}; }
+std::suspend_always final_suspend() noexcept { return {}; }
+std::suspend_always yield_value(double value) { return {}; }
+void unhandled_exception() { throw; }
+  };
+};
+
+task do_task() {
+  const int arr[]{1, 2, 3};
+
+  // No ICE if classic loop and not range-based one.
+  // for (auto i = 0; i < 10; ++i) {
+
+  // No ICE if these are moved out of the loop.
+  // auto x = std::suspend_always{};
+  // co_await x;
+
+  for (auto _ : arr) {
+auto bar = std::suspend_always{};
+co_await bar;
+
+// Alternatively:
+// auto bar = 42.;
+// co_yield bar;
+
+// No ICE if r-values:
+// co_await std::suspend_always{};
+// co_yield 42.;
+  }
+}


[gcc r15-7338] c++/coroutines: Fix awaiter var creation [PR116506]

2025-02-03 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:4c743798b1d4530b327dad7c606c610f3811fdbf

commit r15-7338-g4c743798b1d4530b327dad7c606c610f3811fdbf
Author: Iain Sandoe 
Date:   Thu Oct 31 08:40:08 2024 +

c++/coroutines: Fix awaiter var creation [PR116506]

Awaiters always need to have a coroutine state frame copy since
they persist across potential supensions.  It simplifies the later
analysis considerably to assign these early which we do when
building co_await expressions.

The cleanups in r15-3146-g47dbd69b1, unfortunately elided some of
processing used to cater for cases where the var created from an
xvalue, or is a pointer/reference type.

Corrected thus.

PR c++/116506
PR c++/116880

gcc/cp/ChangeLog:

* coroutines.cc (build_co_await): Ensure that xvalues are
materialised.  Handle references/pointer values in awaiter
access expressions.
(is_stable_lvalue): New.
* decl.cc (cxx_maybe_build_cleanup): Handle null arg.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr116506.C: New test.
* g++.dg/coroutines/pr116880.C: New test.

Signed-off-by: Iain Sandoe 
Co-authored-by: Jason Merrill 

Diff:
---
 gcc/cp/coroutines.cc   | 59 +-
 gcc/cp/decl.cc |  2 +-
 gcc/testsuite/g++.dg/coroutines/pr116506.C | 53 +++
 gcc/testsuite/g++.dg/coroutines/pr116880.C | 36 ++
 4 files changed, 139 insertions(+), 11 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 1dee3d25b9b4..d3c7ff3bd72d 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1188,6 +1188,28 @@ build_template_co_await_expr (location_t kw, tree type, 
tree expr, tree kind)
   return aw_expr;
 }
 
+/* Is EXPR an lvalue that will refer to the same object after a resume?
+
+   This is close to asking tree_invariant_p of its address, but that doesn't
+   distinguish temporaries from other variables.  */
+
+static bool
+is_stable_lvalue (tree expr)
+{
+  if (TREE_SIDE_EFFECTS (expr))
+return false;
+
+  for (; handled_component_p (expr);
+   expr = TREE_OPERAND (expr, 0))
+{
+  if (TREE_CODE (expr) == ARRAY_REF
+ && !TREE_CONSTANT (TREE_OPERAND (expr, 1)))
+   return false;
+}
+
+  return (TREE_CODE (expr) == PARM_DECL
+ || (VAR_P (expr) && !is_local_temp (expr)));
+}
 
 /*  This performs [expr.await] bullet 3.3 and validates the interface obtained.
 It is also used to build the initial and final suspend points.
@@ -1250,7 +1272,7 @@ build_co_await (location_t loc, tree a, 
suspend_point_kind suspend_kind,
   if (o_type && !VOID_TYPE_P (o_type))
 o_type = complete_type_or_else (o_type, o);
 
-  if (!o_type)
+  if (!o_type || o_type == error_mark_node)
 return error_mark_node;
 
   if (TREE_CODE (o_type) != RECORD_TYPE)
@@ -1282,14 +1304,30 @@ build_co_await (location_t loc, tree a, 
suspend_point_kind suspend_kind,
   if (!glvalue_p (o))
 o = get_target_expr (o, tf_warning_or_error);
 
+  /* [expr.await]/3.4 e is an lvalue referring to the result of evaluating the
+ (possibly-converted) o.
+
+ So, either reuse an existing stable lvalue such as a variable or
+ COMPONENT_REF thereof, or create a new a coroutine state frame variable
+ for the awaiter, since it must persist across suspension.  */
+  tree e_var = NULL_TREE;
   tree e_proxy = o;
-  if (glvalue_p (o))
+  if (is_stable_lvalue (o))
 o = NULL_TREE; /* Use the existing entity.  */
-  else /* We need to materialise it.  */
+  else /* We need a non-temp var.  */
 {
-  e_proxy = get_awaitable_var (suspend_kind, o_type);
-  o = cp_build_init_expr (loc, e_proxy, o);
-  e_proxy = convert_from_reference (e_proxy);
+  tree p_type = TREE_TYPE (o);
+  tree o_a = o;
+  if (glvalue_p (o))
+   {
+ /* Build a reference variable for a non-stable lvalue o.  */
+ p_type = cp_build_reference_type (p_type, xvalue_p (o));
+ o_a = build_address (o);
+ o_a = cp_fold_convert (p_type, o_a);
+   }
+  e_var = get_awaitable_var (suspend_kind, p_type);
+  o = cp_build_init_expr (loc, e_var, o_a);
+  e_proxy = convert_from_reference (e_var);
 }
 
   /* I suppose we could check that this is contextually convertible to bool.  
*/
@@ -1355,7 +1393,7 @@ build_co_await (location_t loc, tree a, 
suspend_point_kind suspend_kind,
return error_mark_node;
   if (coro_diagnose_throwing_fn (awrs_func))
return error_mark_node;
-  if (tree dummy = cxx_maybe_build_cleanup (e_proxy, tf_none))
+  if (tree dummy = cxx_maybe_build_cleanup (e_var, tf_none))
{
  if (CONVERT_EXPR_P (dummy))
dummy = TREE_OPERAND (dummy, 0);
@@ -1366,7 +1404,8 @@ build_co_await (location_t loc, tree a, 
suspend_point_kind suspend_kind,
 }

[gcc r15-7339] c++: find A pack from B in ...B> [PR118265]

2025-02-03 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:26d3424ca5d9f47d7e0b6fcaf0fae48435a73442

commit r15-7339-g26d3424ca5d9f47d7e0b6fcaf0fae48435a73442
Author: A J Ryan Solutions Ltd 
Date:   Sun Feb 2 22:26:32 2025 +

c++: find A pack from B in ...B> [PR118265]

For non-type parameter packs when unifying the arguments in
unify_pack_expansion it iterates over the associated packs of a param so
that when it recursively unifies the param with the arguments it knows
which targs have been populated with parameter pack arguments that it can
then collect up. This change adds a tree walk so that in the example above
it reaches ...A and adds it to the associated packs for ...B and therefore
knows it will have been set in targs in unify_pack_expansion and processes
it as per other pack arguments.

PR c++/118265

gcc/cp/ChangeLog:

* pt.cc (find_parameter_packs_r) :
Walk into the type of a parameter pack.

Signed-off-by: Adam J Ryan 

Diff:
---
 gcc/cp/pt.cc   |  5 +
 gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C | 18 ++
 2 files changed, 23 insertions(+)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 77583dd6bb52..39232b5e67fd 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -4010,6 +4010,11 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, 
void* data)
&find_parameter_packs_r, ppd, ppd->visited);
   return NULL_TREE;
 
+case TEMPLATE_PARM_INDEX:
+  if (parameter_pack_p)
+   WALK_SUBTREE (TREE_TYPE (t));
+  return NULL_TREE;
+
 case DECL_EXPR:
   {
tree decl = DECL_EXPR_DECL (t);
diff --git a/gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C 
b/gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C
new file mode 100644
index ..ad2af623b139
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C
@@ -0,0 +1,18 @@
+// { dg-do compile { target c++17 } }
+struct Class1
+{
+void apply_bool(bool){}
+void apply_char(char){}
+};
+
+template struct Class2;
+template struct Class2
+{
+void apply(){}
+};
+
+int main()
+{
+Class2<&Class1::apply_bool, &Class1::apply_char> class2;
+class2.apply ();
+}


[gcc r15-7336] Fortran: different character lengths in array constructor [PR93289]

2025-02-03 Thread Harald Anlauf via Gcc-cvs
https://gcc.gnu.org/g:f3a41e6cb5d70f0c94cc8273a118b8542fb5c2fa

commit r15-7336-gf3a41e6cb5d70f0c94cc8273a118b8542fb5c2fa
Author: Harald Anlauf 
Date:   Sat Feb 1 19:14:21 2025 +0100

Fortran: different character lengths in array constructor [PR93289]

PR fortran/93289

gcc/fortran/ChangeLog:

* decl.cc (gfc_set_constant_character_len): Downgrade different
string lengths in character array constructor to legacy extension.

gcc/testsuite/ChangeLog:

* gfortran.dg/unlimited_polymorphic_1.f03: Pad element in character
array constructor to correct length.
* gfortran.dg/char_array_constructor_5.f90: New test.

Diff:
---
 gcc/fortran/decl.cc  | 20 ++--
 .../gfortran.dg/char_array_constructor_5.f90 | 13 +
 .../gfortran.dg/unlimited_polymorphic_1.f03  |  2 +-
 3 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index 7954a845bc09..5a46658651aa 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -1889,12 +1889,20 @@ gfc_set_constant_character_len (gfc_charlen_t len, 
gfc_expr *expr,
 
   /* Apply the standard by 'hand' otherwise it gets cleared for
 initializers.  */
-  if (check_len != -1 && slen != check_len
-  && !(gfc_option.allow_std & GFC_STD_GNU))
-   gfc_error_now ("The CHARACTER elements of the array constructor "
-  "at %L must have the same length (%ld/%ld)",
-  &expr->where, (long) slen,
-  (long) check_len);
+  if (check_len != -1 && slen != check_len)
+   {
+ if (!(gfc_option.allow_std & GFC_STD_GNU))
+   gfc_error_now ("The CHARACTER elements of the array constructor "
+  "at %L must have the same length (%ld/%ld)",
+  &expr->where, (long) slen,
+  (long) check_len);
+ else
+   gfc_notify_std (GFC_STD_LEGACY,
+   "The CHARACTER elements of the array constructor "
+   "at %L must have the same length (%ld/%ld)",
+   &expr->where, (long) slen,
+   (long) check_len);
+   }
 
   s[len] = '\0';
   free (expr->value.character.string);
diff --git a/gcc/testsuite/gfortran.dg/char_array_constructor_5.f90 
b/gcc/testsuite/gfortran.dg/char_array_constructor_5.f90
new file mode 100644
index ..0cbe6b1468d1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/char_array_constructor_5.f90
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! { dg-additional-options "-std=gnu" }
+!
+! PR fortran/93289
+!
+! Contributed by Tobias Burnus
+
+character(len=*), parameter ::  str = "abj", str2 = "1234"
+print *, [character(5) :: str, "ab", "hjf333"]
+print *, [character(5) :: str, str2]
+print *, [str, "ab", "hjf333"]  ! { dg-warning "must have the same length" }
+print *, [str, str2]! { dg-warning "must have the same length" }
+end
diff --git a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_1.f03 
b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_1.f03
index 8634031ad818..51483ed03325 100644
--- a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_1.f03
+++ b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_1.f03
@@ -155,7 +155,7 @@ END MODULE
   call foo([a(8),a(9)], res)
   if (trim (res) .ne. "type(a) array   8   9") STOP 1
 
-  call foo([sun, " & rain"], res)
+  call foo([sun, " & rain "], res)
   if (trim (res) .ne. "char( 8, 2)sunshine & rain") STOP 1
 
   call foo([sun//" never happens", " & rain always happens"], res)


[gcc(refs/users/meissner/heads/work192-bugs)] Revert changes

2025-02-03 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:454b94025b0862ce88be98ae3c8b0cbe4566eaaa

commit 454b94025b0862ce88be98ae3c8b0cbe4566eaaa
Author: Michael Meissner 
Date:   Mon Feb 3 16:40:38 2025 -0500

Revert changes

Diff:
---
 gcc/config/rs6000/rs6000-protos.h   |  6 +---
 gcc/config/rs6000/rs6000.cc | 28 ++-
 gcc/config/rs6000/rs6000.h  | 10 ++-
 gcc/config/rs6000/rs6000.md | 24 ++--
 gcc/testsuite/gcc.target/powerpc/pr118541.c | 43 -
 5 files changed, 20 insertions(+), 91 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-protos.h 
b/gcc/config/rs6000/rs6000-protos.h
index 112332660d3b..4619142d197b 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -114,12 +114,8 @@ extern const char *rs6000_sibcall_template (rtx *, 
unsigned int);
 extern const char *rs6000_indirect_call_template (rtx *, unsigned int);
 extern const char *rs6000_indirect_sibcall_template (rtx *, unsigned int);
 extern const char *rs6000_pltseq_template (rtx *, int);
-
-#define REVERSE_COND_ORDERED_OKfalse
-#define REVERSE_COND_NO_ORDEREDtrue
-
 extern enum rtx_code rs6000_reverse_condition (machine_mode,
-  enum rtx_code, bool);
+  enum rtx_code);
 extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx);
 extern rtx rs6000_emit_fp_cror (rtx_code, machine_mode, rtx);
 extern void rs6000_emit_sCOND (machine_mode, rtx[]);
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 4c61be683621..f9f9a0b931db 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -15360,24 +15360,15 @@ rs6000_print_patchable_function_entry (FILE *file,
 }
 
 enum rtx_code
-rs6000_reverse_condition (machine_mode mode,
- enum rtx_code code,
- bool no_ordered)
+rs6000_reverse_condition (machine_mode mode, enum rtx_code code)
 {
   /* Reversal of FP compares takes care -- an ordered compare
- becomes an unordered compare and vice versa.
-
- However, this is not safe for ordered comparisons (i.e. for isgreater,
- etc.)  starting with the power9 because ifcvt.cc will want to create a fp
- cmove, and the x{s,v}cmp{eq,gt,ge}{dp,qp} instructions will trap if one of
- the arguments is a signalling NaN.  */
-
-  if (mode == CCFPmode && HONOR_NANS (mode)
-  && (code == UNLT || code == UNLE || code == UNGT || code == UNGE
+ becomes an unordered compare and vice versa.  */
+  if (mode == CCFPmode
+  && (!flag_finite_math_only
+ || code == UNLT || code == UNLE || code == UNGT || code == UNGE
  || code == UNEQ || code == LTGT))
-return (no_ordered
-   ? UNKNOWN
-   : reverse_condition_maybe_unordered (code));
+return reverse_condition_maybe_unordered (code);
   else
 return reverse_condition (code);
 }
@@ -15989,14 +15980,11 @@ rs6000_emit_sCOND (machine_mode mode, rtx operands[])
   rtx not_result = gen_reg_rtx (CCEQmode);
   rtx not_op, rev_cond_rtx;
   machine_mode cc_mode;
-  enum rtx_code rev;
 
   cc_mode = GET_MODE (XEXP (condition_rtx, 0));
 
-  rev = rs6000_reverse_condition (cc_mode, cond_code,
- REVERSE_COND_ORDERED_OK);
-  rev_cond_rtx = gen_rtx_fmt_ee (rev, SImode, XEXP (condition_rtx, 0),
-const0_rtx);
+  rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, 
cond_code),
+SImode, XEXP (condition_rtx, 0), 
const0_rtx);
   not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
   emit_insn (gen_rtx_SET (not_result, not_op));
   condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index c595d7138bcd..ec08c96d0f67 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1812,17 +1812,11 @@ extern scalar_int_mode rs6000_pmode;
 
 /* Can the condition code MODE be safely reversed?  This is safe in
all cases on this port, because at present it doesn't use the
-   trapping FP comparisons (fcmpo).
-
-   However, this is not safe for ordered comparisons (i.e. for isgreater, etc.)
-   starting with the power9 because ifcvt.cc will want to create a fp cmove,
-   and the x{s,v}cmp{eq,gt,ge}{dp,qp} instructions will trap if one of the
-   arguments is a signalling NaN.  */
+   trapping FP comparisons (fcmpo).  */
 #define REVERSIBLE_CC_MODE(MODE) 1
 
 /* Given a condition code and a mode, return the inverse condition.  */
-#define REVERSE_CONDITION(CODE, MODE) \
-  rs6000_reverse_condition (MODE, CODE, REVERSE_COND_NO_ORDERED)
+#define REVERSE_CONDITION(CODE, MODE) rs6000_reverse_condition (MODE, CODE)
 
 
 /* Target cpu costs.  */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md

[gcc r15-7342] c++: Improve contracts support in modules [PR108205]

2025-02-03 Thread Nathaniel Shead via Gcc-cvs
https://gcc.gnu.org/g:d3627c78be116ef1941f6819d57c237e71c39444

commit r15-7342-gd3627c78be116ef1941f6819d57c237e71c39444
Author: Nathaniel Shead 
Date:   Sat Feb 1 22:55:22 2025 +1100

c++: Improve contracts support in modules [PR108205]

Modules makes some assumptions about types that currently aren't
fulfilled by the types created in contracts logic.  This patch ensures
that exporting inline functions using contracts works again with
modules.

PR c++/108205

gcc/cp/ChangeLog:

* contracts.cc (get_pseudo_contract_violation_type): Give names
to generated FIELD_DECLs.
(declare_handle_contract_violation): Mark contract_violation
type as external linkage.
(build_contract_handler_call): Ensure any builtin declarations
created here aren't treated as attached to the current module.

gcc/testsuite/ChangeLog:

* g++.dg/modules/contracts-5_a.C: New test.
* g++.dg/modules/contracts-5_b.C: New test.

Signed-off-by: Nathaniel Shead 

Diff:
---
 gcc/cp/contracts.cc  | 27 ++-
 gcc/testsuite/g++.dg/modules/contracts-5_a.C |  8 
 gcc/testsuite/g++.dg/modules/contracts-5_b.C | 20 
 3 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc
index 5782ec8bf295..f2b126c8d6be 100644
--- a/gcc/cp/contracts.cc
+++ b/gcc/cp/contracts.cc
@@ -1633,19 +1633,22 @@ get_pseudo_contract_violation_type ()
   signed char _M_continue;
 If this changes, also update the initializer in
 build_contract_violation.  */
-  const tree types[] = { const_string_type_node,
-const_string_type_node,
-const_string_type_node,
-const_string_type_node,
-const_string_type_node,
-uint_least32_type_node,
-signed_char_type_node };
+  struct field_info { tree type; const char* name; };
+  const field_info info[] = {
+   { const_string_type_node, "_M_file" },
+   { const_string_type_node, "_M_function" },
+   { const_string_type_node, "_M_comment" },
+   { const_string_type_node, "_M_level" },
+   { const_string_type_node, "_M_role" },
+   { uint_least32_type_node, "_M_line" },
+   { signed_char_type_node, "_M_continue" }
+  };
   tree fields = NULL_TREE;
-  for (tree type : types)
+  for (const field_info& i : info)
{
  /* finish_builtin_struct wants fieldss chained in reverse.  */
  tree next = build_decl (BUILTINS_LOCATION, FIELD_DECL,
- NULL_TREE, type);
+ get_identifier (i.name), i.type);
  DECL_CHAIN (next) = fields;
  fields = next;
}
@@ -1737,6 +1740,7 @@ declare_handle_contract_violation ()
   create_implicit_typedef (viol_name, violation);
   DECL_SOURCE_LOCATION (TYPE_NAME (violation)) = BUILTINS_LOCATION;
   DECL_CONTEXT (TYPE_NAME (violation)) = current_namespace;
+  TREE_PUBLIC (TYPE_NAME (violation)) = true;
   pushdecl_namespace_level (TYPE_NAME (violation), /*hidden*/true);
   pop_namespace ();
   pop_nested_namespace (std_node);
@@ -1761,6 +1765,11 @@ static void
 build_contract_handler_call (tree contract,
 contract_continuation cmode)
 {
+  /* We may need to declare new types, ensure they are not considered
+ attached to a named module.  */
+  auto module_kind_override = make_temp_override
+(module_kind, module_kind & ~(MK_PURVIEW | MK_ATTACH | MK_EXPORTING));
+
   tree violation = build_contract_violation (contract, cmode);
   tree violation_fn = declare_handle_contract_violation ();
   tree call = build_call_n (violation_fn, 1, build_address (violation));
diff --git a/gcc/testsuite/g++.dg/modules/contracts-5_a.C 
b/gcc/testsuite/g++.dg/modules/contracts-5_a.C
new file mode 100644
index ..2ff6701ff3f1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-5_a.C
@@ -0,0 +1,8 @@
+// PR c++/108205
+// Test that the implicitly declared handle_contract_violation function is
+// properly matched with a later declaration in an importing TU.
+// { dg-additional-options "-fmodules -fcontracts 
-fcontract-continuation-mode=on" }
+// { dg-module-cmi test }
+
+export module test;
+export inline void foo(int x) noexcept [[ pre: x != 0 ]] {}
diff --git a/gcc/testsuite/g++.dg/modules/contracts-5_b.C 
b/gcc/testsuite/g++.dg/modules/contracts-5_b.C
new file mode 100644
index ..0e794b8ae453
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/contracts-5_b.C
@@ -0,0 +1,20 @@
+// PR c++/108205
+// { dg-module-do run }
+// { dg-additional-options "-fmodules -fcontracts 
-fcontract-continuation-mode=on" }
+
+#include 
+import test;
+
+b

[gcc r15-7341] c++: Modularise start_cleanup_fn [PR98893]

2025-02-03 Thread Nathaniel Shead via Gcc-cvs
https://gcc.gnu.org/g:736e8eef6c0df860f9b0469f9f7cfb8c121a70a7

commit r15-7341-g736e8eef6c0df860f9b0469f9f7cfb8c121a70a7
Author: Nathaniel Shead 
Date:   Sat Feb 1 21:21:37 2025 +1100

c++: Modularise start_cleanup_fn [PR98893]

'start_cleanup_fn' is not currently viable in modules, due to generating
functions relying on the 'start_cleanup_cnt' counter which is reset to 0
with each new TU.  This means that cleanup functions declared in a TU
will conflict with any imported cleanup functions.

This patch mitigates the problem by using the mangled name of the decl
we're destroying as part of the name of the function.  This should avoid
clashes unless the decls would have clashed anyway.

PR c++/98893

gcc/cp/ChangeLog:

* decl.cc (start_cleanup_fn): Make name from the mangled name of
the passed-in decl.
(register_dtor_fn): Pass decl to start_cleanup_fn.

gcc/testsuite/ChangeLog:

* g++.dg/modules/pr98893_a.H: New test.
* g++.dg/modules/pr98893_b.C: New test.

Signed-off-by: Nathaniel Shead 

Diff:
---
 gcc/cp/decl.cc   | 18 +-
 gcc/testsuite/g++.dg/modules/pr98893_a.H |  9 +
 gcc/testsuite/g++.dg/modules/pr98893_b.C | 10 ++
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index b5b8459fa5be..b7af33b32317 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -96,7 +96,7 @@ static void record_key_method_defined (tree);
 static tree create_array_type_for_decl (tree, tree, tree, location_t);
 static tree get_atexit_node (void);
 static tree get_dso_handle_node (void);
-static tree start_cleanup_fn (bool);
+static tree start_cleanup_fn (tree, bool);
 static void end_cleanup_fn (void);
 static tree cp_make_fname_decl (location_t, tree, int);
 static void initialize_predefined_identifiers (void);
@@ -10373,23 +10373,23 @@ get_dso_handle_node (void)
 }
 
 /* Begin a new function with internal linkage whose job will be simply
-   to destroy some particular variable.  OB_PARM is true if object pointer
+   to destroy some particular DECL.  OB_PARM is true if object pointer
is passed to the cleanup function, otherwise no argument is passed.  */
 
-static GTY(()) int start_cleanup_cnt;
-
 static tree
-start_cleanup_fn (bool ob_parm)
+start_cleanup_fn (tree decl, bool ob_parm)
 {
-  char name[32];
-
   push_to_top_level ();
 
   /* No need to mangle this.  */
   push_lang_context (lang_name_c);
 
   /* Build the name of the function.  */
-  sprintf (name, "__tcf_%d", start_cleanup_cnt++);
+  gcc_checking_assert (HAS_DECL_ASSEMBLER_NAME_P (decl));
+  const char *dname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+  dname = targetm.strip_name_encoding (dname);
+  char *name = ACONCAT (("__tcf", dname, NULL));
+
   tree fntype = TREE_TYPE (ob_parm ? get_cxa_atexit_fn_ptr_type ()
   : get_atexit_fn_ptr_type ());
   /* Build the function declaration.  */
@@ -10482,7 +10482,7 @@ register_dtor_fn (tree decl)
   build_cleanup (decl);
 
   /* Now start the function.  */
-  cleanup = start_cleanup_fn (ob_parm);
+  cleanup = start_cleanup_fn (decl, ob_parm);
 
   /* Now, recompute the cleanup.  It may contain SAVE_EXPRs that refer
 to the original function, rather than the anonymous one.  That
diff --git a/gcc/testsuite/g++.dg/modules/pr98893_a.H 
b/gcc/testsuite/g++.dg/modules/pr98893_a.H
new file mode 100644
index ..062ab6d9cccb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr98893_a.H
@@ -0,0 +1,9 @@
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+struct S {
+  ~S() {}
+};
+inline void foo() {
+  static S a[1];
+}
diff --git a/gcc/testsuite/g++.dg/modules/pr98893_b.C 
b/gcc/testsuite/g++.dg/modules/pr98893_b.C
new file mode 100644
index ..9065589bdfbf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr98893_b.C
@@ -0,0 +1,10 @@
+// { dg-additional-options "-fmodules" }
+
+import "pr98893_a.H";
+static S b[1];
+int main() {
+  foo();
+}
+
+// { dg-final { scan-assembler {__tcf_ZZ3foovE1a:} } }
+// { dg-final { scan-assembler {__tcf_ZL1b:} } }


[gcc(refs/users/meissner/heads/work192-bugs)] Fix PR 118541, do not generate unordered fp cmoves for IEEE compares.

2025-02-03 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:2d4feb1bcd07b67cc4c93024ea7be18ef69b809a

commit 2d4feb1bcd07b67cc4c93024ea7be18ef69b809a
Author: Michael Meissner 
Date:   Mon Feb 3 18:14:56 2025 -0500

Fix PR 118541, do not generate unordered fp cmoves for IEEE compares.

In bug PR target/118541 on power9, power10, and power11 systems, for the
function:

extern double __ieee754_acos (double);

double
__acospi (double x)
{
  double ret = __ieee754_acos (x) / 3.14;
  return __builtin_isgreater (ret, 1.0) ? 1.0 : ret;
}

GCC currently generates the following code:

Power9  Power10 and Power11
==  ===
bl __ieee754_acos   bl __ieee754_acos@notoc
nop plfd 0,.LC0@pcrel
addis 9,2,.LC2@toc@ha   xxspltidp 12,1065353216
addi 1,1,32 addi 1,1,32
lfd 0,.LC2@toc@l(9) ld 0,16(1)
addis 9,2,.LC0@toc@ha   fdiv 0,1,0
ld 0,16(1)  mtlr 0
lfd 12,.LC0@toc@l(9)xscmpgtdp 1,0,12
fdiv 0,1,0  xxsel 1,0,12,1
mtlr 0  blr
xscmpgtdp 1,0,12
xxsel 1,0,12,1
blr

This is because ifcvt.c optimizes the conditional floating point move to 
use the
XSCMPGTDP instruction.

However, the XSCMPGTDP instruction will generate an interrupt if one of the
arguments is a signalling NaN and signalling NaNs can generate an interrupt.
The IEEE comparison functions (isgreater, etc.) require that the comparison 
not
raise an interrupt.

The following patch changes the PowerPC back end so that ifcvt.c will not 
change
the if/then test and move into a conditional move if the comparison is one 
of
the comparisons that do not raise an error with signalling NaNs and -Ofast 
is
not used.  If a normal comparison is used or -Ofast is used, GCC will 
continue
to generate XSCMPGTDP and XXSEL.

For the following code:

double
ordered_compare (double a, double b, double c, double d)
{
  return __builtin_isgreater (a, b) ? c : d;
}

/* Verify normal > does generate xscmpgtdp.  */

double
normal_compare (double a, double b, double c, double d)
{
  return a > b ? c : d;
}

with the following patch, GCC generates the following for power9, power10, 
and
power11:

ordered_compare:
fcmpu 0,1,2
fmr 1,4
bnglr 0
fmr 1,3
blr

normal_compare:
xscmpgtdp 1,1,2
xxsel 1,4,3,1
blr

I have built bootstrap compilers on big endian power9 systems and little 
endian
power9/power10 systems and there were no regressions.  Can I check this 
patch
into the GCC trunk, and after a waiting period, can I check this into the 
active
older branches?

2025-02-03  Michael Meissner  

gcc/

PR target/118541
* config/rs6000/rs6000-protos.h (REVERSE_COND_ORDERED_OK): New 
macro.
(REVERSE_COND_NO_ORDERED): Likewise.
(rs6000_reverse_condition): Add argument.
* config/rs6000/rs6000.cc (rs6000_reverse_condition): Do not allow
ordered comparisons to be reversed for floating point cmoves.
(rs6000_emit_sCOND): Adjust rs6000_reverse_condition call.
* config/rs6000/rs6000.h (REVERSE_CONDITION): Likewise.
* config/rs6000/rs6000.md (reverse_branch_comparison): Name insn.
Adjust rs6000_reverse_condition call.

gcc/testsuite/

PR target/118541
* gcc.target/powerpc/pr118541.c: New test.

Diff:
---
 gcc/config/rs6000/rs6000-protos.h   |  6 +++-
 gcc/config/rs6000/rs6000.cc | 35 +--
 gcc/config/rs6000/rs6000.h  | 10 +--
 gcc/config/rs6000/rs6000.md | 24 ++--
 gcc/testsuite/gcc.target/powerpc/pr118541.c | 43 +
 5 files changed, 97 insertions(+), 21 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-protos.h 
b/gcc/config/rs6000/rs6000-protos.h
index 4619142d197b..112332660d3b 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -114,8 +114,12 @@ extern const char *rs6000_sibcall_template (rtx *, 
unsigned int);
 extern const char *rs6000_indirect_call_template (rtx *, unsigned int);
 extern const char *rs6000_indirect_sibcall_template (rtx *, unsigned int);
 extern const char *r

[gcc(refs/users/meissner/heads/work192-bugs)] Update ChangeLog.*

2025-02-03 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:fa4d95d164f071e0c0e752a5d446a714dcf22636

commit fa4d95d164f071e0c0e752a5d446a714dcf22636
Author: Michael Meissner 
Date:   Mon Feb 3 18:16:57 2025 -0500

Update ChangeLog.*

Diff:
---
 gcc/ChangeLog.bugs | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/ChangeLog.bugs b/gcc/ChangeLog.bugs
index 25d92dc2245a..f4df387fdb86 100644
--- a/gcc/ChangeLog.bugs
+++ b/gcc/ChangeLog.bugs
@@ -1,4 +1,4 @@
- Branch work192-bugs, patch #210 
+ Branch work192-bugs, patch #211 
 
 Fix PR 118541, do not generate unordered fp cmoves for IEEE compares.
 
@@ -82,7 +82,7 @@ power9/power10 systems and there were no regressions.  Can I 
check this patch
 into the GCC trunk, and after a waiting period, can I check this into the 
active
 older branches?
 
-2025-01-31  Michael Meissner  
+2025-02-03  Michael Meissner  
 
 gcc/
 
@@ -102,6 +102,8 @@ gcc/testsuite/
PR target/118541
* gcc.target/powerpc/pr118541.c: New test.
 
+ Branch work192-bugs, patch #210 was reverted 

+
  Branch work192-bugs, patch #202 
 
 PR target/108958 -- use mtvsrdd to zero extend GPR DImode to VSX TImode


[gcc r15-7335] i386: Fix and improve TARGET_INDIRECT_BRANCH_REGISTER handling some more

2025-02-03 Thread Uros Bizjak via Gcc-cvs
https://gcc.gnu.org/g:214224c4973bfb76f73a7efff29c5823eef31194

commit r15-7335-g214224c4973bfb76f73a7efff29c5823eef31194
Author: Uros Bizjak 
Date:   Mon Feb 3 21:01:51 2025 +0100

i386: Fix and improve TARGET_INDIRECT_BRANCH_REGISTER handling some more

gcc/ChangeLog:

* config/i386/i386.md (*sibcall_pop_memory):
Disable for TARGET_INDIRECT_BRANCH_REGISTER
* config/i386/predicates.md (call_insn_operand): Enable when
"satisfies_constraint_Bw (op)" is true, instead of open-coding
constraint here.
(sibcall_insn_operand): Ditto with "satisfies_constraint_Bs (op)"

Diff:
---
 gcc/config/i386/i386.md   | 23 ---
 gcc/config/i386/predicates.md | 12 ++--
 2 files changed, 10 insertions(+), 25 deletions(-)

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index d6ae3ee378aa..27cd6c117b4e 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -20149,8 +20149,7 @@
 (match_operand:SI 1 "GOT32_symbol_operand"
 (match_operand 2))]
   "!TARGET_MACHO
-  && !TARGET_64BIT
-  && !TARGET_INDIRECT_BRANCH_REGISTER
+  && !TARGET_64BIT && !TARGET_INDIRECT_BRANCH_REGISTER
   && SIBLING_CALL_P (insn)"
 {
   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
@@ -20179,8 +20178,7 @@
(match_operand:W 1 "memory_operand"))
(call (mem:QI (match_dup 0))
 (match_operand 3))]
-  "!TARGET_X32
-   && !TARGET_INDIRECT_BRANCH_REGISTER
+  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER
&& SIBLING_CALL_P (peep2_next_insn (1))
&& !reg_mentioned_p (operands[0],
CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
@@ -20194,8 +20192,7 @@
(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(call (mem:QI (match_dup 0))
 (match_operand 3))]
-  "!TARGET_X32
-   && !TARGET_INDIRECT_BRANCH_REGISTER
+  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER
&& SIBLING_CALL_P (peep2_next_insn (2))
&& !reg_mentioned_p (operands[0],
CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
@@ -20244,7 +20241,7 @@
(plus:SI (reg:SI SP_REG)
 (match_operand:SI 2 "immediate_operand" "i")))
(unspec [(const_int 0)] UNSPEC_PEEPSIB)]
-  "!TARGET_64BIT"
+  "!TARGET_64BIT && !TARGET_INDIRECT_BRANCH_REGISTER"
   "* return ix86_output_call_insn (insn, operands[0]);"
   [(set_attr "type" "call")])
 
@@ -20292,8 +20289,7 @@
   [(set (match_operand:W 0 "register_operand")
 (match_operand:W 1 "memory_operand"))
(set (pc) (match_dup 0))]
-  "!TARGET_X32
-   && !TARGET_INDIRECT_BRANCH_REGISTER
+  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER
&& peep2_reg_dead_p (2, operands[0])"
   [(set (pc) (match_dup 1))])
 
@@ -20355,8 +20351,7 @@
  (match_operand:SI 2 "GOT32_symbol_operand"
 (match_operand 3)))]
   "!TARGET_MACHO
-   && !TARGET_64BIT
-   && !TARGET_INDIRECT_BRANCH_REGISTER
+   && !TARGET_64BIT && !TARGET_INDIRECT_BRANCH_REGISTER
&& SIBLING_CALL_P (insn)"
 {
   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
@@ -20388,8 +20383,7 @@
(set (match_operand 2)
(call (mem:QI (match_dup 0))
 (match_operand 3)))]
-  "!TARGET_X32
-   && !TARGET_INDIRECT_BRANCH_REGISTER
+  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER
&& SIBLING_CALL_P (peep2_next_insn (1))
&& !reg_mentioned_p (operands[0],
CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
@@ -20405,8 +20399,7 @@
(set (match_operand 2)
(call (mem:QI (match_dup 0))
  (match_operand 3)))]
-  "!TARGET_X32
-   && !TARGET_INDIRECT_BRANCH_REGISTER
+  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER
&& SIBLING_CALL_P (peep2_next_insn (2))
&& !reg_mentioned_p (operands[0],
CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 9a9101ed374b..8631588f78e0 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -781,22 +781,14 @@
   (ior (match_test "constant_call_address_operand
 (op, mode == VOIDmode ? mode : Pmode)")
(match_operand 0 "call_register_operand")
-   (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
-   (ior (and (not (match_test "TARGET_X32"))
- (match_operand 0 "memory_operand"))
-(and (match_test "TARGET_X32 && Pmode == DImode")
- (match_operand 0 "GOT_memory_operand"))
+   (match_test "satisfies_constraint_Bw (op)")))
 
 ;; Similarly, but for tail calls, in which we cannot allow memory references.
 (define_special_predicate "sibcall_insn_operand"
   (ior (match_test "constant_call_address_operand
 (op, mode == VOIDmode ? mode : Pmode)")
(match_operand 0 "register_no_elim_operand")
-   (and (not (match_test "

[gcc(refs/users/meissner/heads/work192-bugs)] Revert changes

2025-02-03 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:a162aa99aa973cf356d981cb033c7895bd708e89

commit a162aa99aa973cf356d981cb033c7895bd708e89
Author: Michael Meissner 
Date:   Mon Feb 3 21:08:59 2025 -0500

Revert changes

Diff:
---
 gcc/config/rs6000/rs6000-protos.h   |  6 +---
 gcc/config/rs6000/rs6000.cc | 35 ++-
 gcc/config/rs6000/rs6000.h  | 10 ++-
 gcc/config/rs6000/rs6000.md | 24 ++--
 gcc/testsuite/gcc.target/powerpc/pr118541.c | 43 -
 5 files changed, 21 insertions(+), 97 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-protos.h 
b/gcc/config/rs6000/rs6000-protos.h
index 112332660d3b..4619142d197b 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -114,12 +114,8 @@ extern const char *rs6000_sibcall_template (rtx *, 
unsigned int);
 extern const char *rs6000_indirect_call_template (rtx *, unsigned int);
 extern const char *rs6000_indirect_sibcall_template (rtx *, unsigned int);
 extern const char *rs6000_pltseq_template (rtx *, int);
-
-#define REVERSE_COND_ORDERED_OKfalse
-#define REVERSE_COND_NO_ORDEREDtrue
-
 extern enum rtx_code rs6000_reverse_condition (machine_mode,
-  enum rtx_code, bool);
+  enum rtx_code);
 extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx);
 extern rtx rs6000_emit_fp_cror (rtx_code, machine_mode, rtx);
 extern void rs6000_emit_sCOND (machine_mode, rtx[]);
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 4c71e4ffe8c8..f9f9a0b931db 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -15360,29 +15360,15 @@ rs6000_print_patchable_function_entry (FILE *file,
 }
 
 enum rtx_code
-rs6000_reverse_condition (machine_mode cc_mode,
- enum rtx_code code,
- bool no_ordered)
+rs6000_reverse_condition (machine_mode mode, enum rtx_code code)
 {
   /* Reversal of FP compares takes care -- an ordered compare
- becomes an unordered compare and vice versa.
-
- However, this is not safe for ordered comparisons (i.e. for isgreater,
- etc.)  starting with the power9 because ifcvt.cc will want to create a fp
- cmove, and the x{s,v}cmp{eq,gt,ge}{dp,qp} instructions will trap if one of
- the arguments is a signalling NaN.  */
-
-  if (cc_mode == CCFPmode)
-{
-  if (no_ordered
- && HONOR_NANS (DFmode)
- && (code == UNLT || code == UNLE || code == UNGT || code == UNGE
- || code == UNEQ || code == LTGT))
-   return UNKNOWN;
-
-  return reverse_condition_maybe_unordered (code);
-}
-
+ becomes an unordered compare and vice versa.  */
+  if (mode == CCFPmode
+  && (!flag_finite_math_only
+ || code == UNLT || code == UNLE || code == UNGT || code == UNGE
+ || code == UNEQ || code == LTGT))
+return reverse_condition_maybe_unordered (code);
   else
 return reverse_condition (code);
 }
@@ -15994,14 +15980,11 @@ rs6000_emit_sCOND (machine_mode mode, rtx operands[])
   rtx not_result = gen_reg_rtx (CCEQmode);
   rtx not_op, rev_cond_rtx;
   machine_mode cc_mode;
-  enum rtx_code rev;
 
   cc_mode = GET_MODE (XEXP (condition_rtx, 0));
 
-  rev = rs6000_reverse_condition (cc_mode, cond_code,
- REVERSE_COND_ORDERED_OK);
-  rev_cond_rtx = gen_rtx_fmt_ee (rev, SImode, XEXP (condition_rtx, 0),
-const0_rtx);
+  rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, 
cond_code),
+SImode, XEXP (condition_rtx, 0), 
const0_rtx);
   not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
   emit_insn (gen_rtx_SET (not_result, not_op));
   condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index c595d7138bcd..ec08c96d0f67 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1812,17 +1812,11 @@ extern scalar_int_mode rs6000_pmode;
 
 /* Can the condition code MODE be safely reversed?  This is safe in
all cases on this port, because at present it doesn't use the
-   trapping FP comparisons (fcmpo).
-
-   However, this is not safe for ordered comparisons (i.e. for isgreater, etc.)
-   starting with the power9 because ifcvt.cc will want to create a fp cmove,
-   and the x{s,v}cmp{eq,gt,ge}{dp,qp} instructions will trap if one of the
-   arguments is a signalling NaN.  */
+   trapping FP comparisons (fcmpo).  */
 #define REVERSIBLE_CC_MODE(MODE) 1
 
 /* Given a condition code and a mode, return the inverse condition.  */
-#define REVERSE_CONDITION(CODE, MODE) \
-  rs6000_reverse_condition (MODE, CODE, REVERSE_COND_NO_ORDERED)
+#define REVERSE_CONDITION(CODE, MODE) rs6000_reverse_condition (MODE, CODE)
 
 
 /* Ta

[gcc(refs/users/meissner/heads/work192-bugs)] Fix PR 118541, do not generate unordered fp cmoves for IEEE compares.

2025-02-03 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:b398f0f1c79233185353fd1ba0ab1014bb702093

commit b398f0f1c79233185353fd1ba0ab1014bb702093
Author: Michael Meissner 
Date:   Mon Feb 3 21:12:28 2025 -0500

Fix PR 118541, do not generate unordered fp cmoves for IEEE compares.

In bug PR target/118541 on power9, power10, and power11 systems, for the
function:

extern double __ieee754_acos (double);

double
__acospi (double x)
{
  double ret = __ieee754_acos (x) / 3.14;
  return __builtin_isgreater (ret, 1.0) ? 1.0 : ret;
}

GCC currently generates the following code:

Power9  Power10 and Power11
==  ===
bl __ieee754_acos   bl __ieee754_acos@notoc
nop plfd 0,.LC0@pcrel
addis 9,2,.LC2@toc@ha   xxspltidp 12,1065353216
addi 1,1,32 addi 1,1,32
lfd 0,.LC2@toc@l(9) ld 0,16(1)
addis 9,2,.LC0@toc@ha   fdiv 0,1,0
ld 0,16(1)  mtlr 0
lfd 12,.LC0@toc@l(9)xscmpgtdp 1,0,12
fdiv 0,1,0  xxsel 1,0,12,1
mtlr 0  blr
xscmpgtdp 1,0,12
xxsel 1,0,12,1
blr

This is because ifcvt.c optimizes the conditional floating point move to 
use the
XSCMPGTDP instruction.

However, the XSCMPGTDP instruction will generate an interrupt if one of the
arguments is a signalling NaN and signalling NaNs can generate an interrupt.
The IEEE comparison functions (isgreater, etc.) require that the comparison 
not
raise an interrupt.

The following patch changes the PowerPC back end so that ifcvt.c will not 
change
the if/then test and move into a conditional move if the comparison is one 
of
the comparisons that do not raise an error with signalling NaNs and -Ofast 
is
not used.  If a normal comparison is used or -Ofast is used, GCC will 
continue
to generate XSCMPGTDP and XXSEL.

For the following code:

double
ordered_compare (double a, double b, double c, double d)
{
  return __builtin_isgreater (a, b) ? c : d;
}

/* Verify normal > does generate xscmpgtdp.  */

double
normal_compare (double a, double b, double c, double d)
{
  return a > b ? c : d;
}

with the following patch, GCC generates the following for power9, power10, 
and
power11:

ordered_compare:
fcmpu 0,1,2
fmr 1,4
bnglr 0
fmr 1,3
blr

normal_compare:
xscmpgtdp 1,1,2
xxsel 1,4,3,1
blr

I have built bootstrap compilers on big endian power9 systems and little 
endian
power9/power10 systems and there were no regressions.  Can I check this 
patch
into the GCC trunk, and after a waiting period, can I check this into the 
active
older branches?

2025-02-03  Michael Meissner  

gcc/

PR target/118541
* config/rs6000/rs6000-protos.h (REVERSE_COND_ORDERED_OK): New 
macro.
(REVERSE_COND_NO_ORDERED): Likewise.
(rs6000_reverse_condition): Add argument.
* config/rs6000/rs6000.cc (rs6000_reverse_condition): Do not allow
ordered comparisons to be reversed for floating point cmoves.
(rs6000_emit_sCOND): Adjust rs6000_reverse_condition call.
* config/rs6000/rs6000.h (REVERSE_CONDITION): Likewise.
* config/rs6000/rs6000.md (reverse_branch_comparison): Name insn.
Adjust rs6000_reverse_condition call.

gcc/testsuite/

PR target/118541
* gcc.target/powerpc/pr118541.c: New test.

Diff:
---
 gcc/config/rs6000/rs6000-protos.h   |  6 +++-
 gcc/config/rs6000/rs6000.cc | 29 +--
 gcc/config/rs6000/rs6000.h  | 10 +--
 gcc/config/rs6000/rs6000.md | 24 ++--
 gcc/testsuite/gcc.target/powerpc/pr118541.c | 43 +
 5 files changed, 92 insertions(+), 20 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-protos.h 
b/gcc/config/rs6000/rs6000-protos.h
index 4619142d197b..112332660d3b 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -114,8 +114,12 @@ extern const char *rs6000_sibcall_template (rtx *, 
unsigned int);
 extern const char *rs6000_indirect_call_template (rtx *, unsigned int);
 extern const char *rs6000_indirect_sibcall_template (rtx *, unsigned int);
 extern const char *rs600

[gcc r15-7331] tree-optimization/118717 - store commoning vs. abnormals

2025-02-03 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:fbcbbfe2bf83eb8b1347144eeca37b06be5a8bb5

commit r15-7331-gfbcbbfe2bf83eb8b1347144eeca37b06be5a8bb5
Author: Richard Biener 
Date:   Mon Feb 3 09:55:50 2025 +0100

tree-optimization/118717 - store commoning vs. abnormals

When we sink common stores in cselim or the sink pass we have to
make sure to not introduce overlapping lifetimes for abnormals
used in the ref.  The easiest is to avoid sinking stmts which
reference abnormals at all which is what the following does.

PR tree-optimization/118717
* tree-ssa-phiopt.cc (cond_if_else_store_replacement_1):
Do not common stores referencing abnormal SSA names.
* tree-ssa-sink.cc (sink_common_stores_to_bb): Likewise.

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

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr118717.c | 41 +
 gcc/tree-ssa-phiopt.cc  |  4 +++-
 gcc/tree-ssa-sink.cc|  4 +++-
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr118717.c 
b/gcc/testsuite/gcc.dg/torture/pr118717.c
new file mode 100644
index ..42dc5ec84f28
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr118717.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+
+void jj(void);
+int ff1(void) __attribute__((__returns_twice__));
+struct s2 {
+  int prev;
+};
+typedef struct s1 {
+  unsigned interrupt_flag;
+  unsigned interrupt_mask;
+  int tag;
+  int state;
+}s1;
+int ff(void);
+static inline
+int mm(s1 *ec) {
+  if (ff())
+if (ec->interrupt_flag & ~(ec)->interrupt_mask)
+  return 0;
+}
+void ll(s1 *ec) {
+  int t = 1;
+  int state;
+  if (t)
+  {
+{
+  s1 *const _ec = ec;
+  struct s2 _tag = {0};
+  if (ff1())
+   state = ec->state;
+  else
+   state = 0;
+  if (!state)
+   mm (ec);
+  _ec->tag = _tag.prev;
+}
+if (state)
+  __builtin_exit(0);
+  }
+  jj();
+}
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 64d3ba9e1607..f67f52d2d69a 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -3646,7 +3646,9 @@ cond_if_else_store_replacement_1 (basic_block then_bb, 
basic_block else_bb,
   || else_assign == NULL
   || !gimple_assign_single_p (else_assign)
   || gimple_clobber_p (else_assign)
-  || gimple_has_volatile_ops (else_assign))
+  || gimple_has_volatile_ops (else_assign)
+  || stmt_references_abnormal_ssa_name (then_assign)
+  || stmt_references_abnormal_ssa_name (else_assign))
 return false;
 
   lhs = gimple_assign_lhs (then_assign);
diff --git a/gcc/tree-ssa-sink.cc b/gcc/tree-ssa-sink.cc
index e79762b9848b..959e0d5c6bea 100644
--- a/gcc/tree-ssa-sink.cc
+++ b/gcc/tree-ssa-sink.cc
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 #include "tree-eh.h"
 #include "tree-ssa-live.h"
+#include "tree-dfa.h"
 
 /* TODO:
1. Sinking store only using scalar promotion (IE without moving the RHS):
@@ -516,7 +517,8 @@ sink_common_stores_to_bb (basic_block bb)
  gimple *def = SSA_NAME_DEF_STMT (arg);
  if (! is_gimple_assign (def)
  || stmt_can_throw_internal (cfun, def)
- || (gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL))
+ || (gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL)
+ || stmt_references_abnormal_ssa_name (def))
{
  /* ???  We could handle some cascading with the def being
 another PHI.  We'd have to insert multiple PHIs for


[gcc r15-7332] c++/79786 - bougs invocation of DATA_ABI_ALIGNMENT macro

2025-02-03 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:6ec19825b4e72611cdbd4749feed67b61392aa81

commit r15-7332-g6ec19825b4e72611cdbd4749feed67b61392aa81
Author: Richard Biener 
Date:   Mon Feb 3 11:27:20 2025 +0100

c++/79786 - bougs invocation of DATA_ABI_ALIGNMENT macro

The first argument is supposed to be a type, not a decl.

PR c++/79786
gcc/cp/
* rtti.cc (emit_tinfo_decl): Fix DATA_ABI_ALIGNMENT invocation.

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

diff --git a/gcc/cp/rtti.cc b/gcc/cp/rtti.cc
index 2dfc2e3d7c53..dcf84f17163b 100644
--- a/gcc/cp/rtti.cc
+++ b/gcc/cp/rtti.cc
@@ -1741,7 +1741,8 @@ emit_tinfo_decl (tree decl)
   /* Avoid targets optionally bumping up the alignment to improve
 vector instruction accesses, tinfo are never accessed this way.  */
 #ifdef DATA_ABI_ALIGNMENT
-  SET_DECL_ALIGN (decl, DATA_ABI_ALIGNMENT (decl, TYPE_ALIGN (TREE_TYPE 
(decl;
+  SET_DECL_ALIGN (decl, DATA_ABI_ALIGNMENT (TREE_TYPE (decl),
+   TYPE_ALIGN (TREE_TYPE (decl;
   DECL_USER_ALIGN (decl) = true;
 #endif
   return true;


[gcc r15-7334] aarch64: Fix dupq_* testsuite failures

2025-02-03 Thread Richard Sandiford via Gcc-cvs
https://gcc.gnu.org/g:606527f3d9e35164fc8139e5e2c53e66ff850b1a

commit r15-7334-g606527f3d9e35164fc8139e5e2c53e66ff850b1a
Author: Richard Sandiford 
Date:   Mon Feb 3 17:35:06 2025 +

aarch64: Fix dupq_* testsuite failures

This patch fixes the dupq_* testsuite failures.  The tests were
introduced with r15-3669-ga92f54f580c3 (which was a nice improvement)
and Pengxuan originally had a follow-on patch to recognise INDEX
constants during vec_init.

I'd originally wanted to solve this a different way, using wildcards
when building a vector and letting vector_builder::finalize find the
best way of filling them in.  I no longer think that's the best
approach though.  Stepped constants are likely to be more expensive
than unstepped constants, so we should first try finding an unstepped
constant that is valid, even if it has a longer representation than
the stepped version.

This patch therefore uses a variant of Pengxuan's idea.

While there, I noticed that the (old) code for finding an unstepped
constant only tried varying one bit at a time.  So for index 0 in a
16-element constant, the code would try picking a constant from index 8,
4, 2, and then 1.  But since the goal is to create "fewer, larger,
repeating parts", it would be better to iterate over a bit-reversed
increment, so that after trying an XOR with 0 and 8, we try adding 4
to each previous attempt, then 2 to each previous attempt, and so on.
In the previous example this would give 8, 4, 12, 2, 10, 6, 14, ...

The test shows an example of this for 8 shorts.

gcc/
* config/aarch64/aarch64.cc (aarch64_choose_vector_init_constant):
New function, split out from...
(aarch64_expand_vector_init_fallback): ...here.  Use a bit-
reversed increment to find a constant index.  Add support for
stepped constants.

gcc/testsuite/
* gcc.target/aarch64/sve/acle/general/dupq_12.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64.cc  | 110 +++--
 .../gcc.target/aarch64/sve/acle/general/dupq_12.c  |  13 +++
 2 files changed, 95 insertions(+), 28 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index be99137b052d..16754fa9e7bd 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -24036,6 +24036,85 @@ aarch64_simd_make_constant (rtx vals)
 return NULL_RTX;
 }
 
+/* VALS is a PARALLEL rtx that contains element values for a vector of
+   mode MODE.  Return a constant that contains all the CONST_INT and
+   CONST_DOUBLE elements of VALS, using any convenient values for the
+   other elements.  */
+
+static rtx
+aarch64_choose_vector_init_constant (machine_mode mode, rtx vals)
+{
+  unsigned int n_elts = XVECLEN (vals, 0);
+
+  /* We really don't care what goes into the parts we will overwrite, but we're
+ more likely to be able to load the constant efficiently if it has fewer,
+ larger, repeating parts (see aarch64_simd_valid_imm).  */
+  rtvec copy = shallow_copy_rtvec (XVEC (vals, 0));
+  for (unsigned int i = 0; i < n_elts; ++i)
+{
+  rtx x = RTVEC_ELT (copy, i);
+  if (CONST_INT_P (x) || CONST_DOUBLE_P (x))
+   continue;
+  /* This is effectively a bit-reversed increment, e.g.: 8, 4, 12,
+2, 10, 6, 12, ... for n_elts == 16.  The early break makes the
+outer "i" loop O(n_elts * log(n_elts)).  */
+  unsigned int j = 0;
+  for (;;)
+   {
+ for (unsigned int bit = n_elts / 2; bit > 0; bit /= 2)
+   {
+ j ^= bit;
+ if (j & bit)
+   break;
+   }
+ rtx test = XVECEXP (vals, 0, i ^ j);
+ if (CONST_INT_P (test) || CONST_DOUBLE_P (test))
+   {
+ RTVEC_ELT (copy, i) = test;
+ break;
+   }
+ gcc_assert (j != 0);
+   }
+}
+
+  rtx c = gen_rtx_CONST_VECTOR (mode, copy);
+  if (aarch64_simd_valid_mov_imm (c))
+return c;
+
+  /* Try generating a stepped sequence.  */
+  if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
+for (unsigned int i = 0; i < n_elts; ++i)
+  if (CONST_INT_P (XVECEXP (vals, 0, i)))
+   {
+ auto base = UINTVAL (XVECEXP (vals, 0, i));
+ for (unsigned int j = i + 1; j < n_elts; ++j)
+   if (CONST_INT_P (XVECEXP (vals, 0, j)))
+ {
+   /* It doesn't matter whether this division is exact.
+  All that matters is whether the constant we produce
+  is valid.  */
+   HOST_WIDE_INT diff = UINTVAL (XVECEXP (vals, 0, j)) - base;
+   unsigned HOST_WIDE_INT step = diff / int (j - i);
+   rtx_vector_builder builder (mode, n_elts, 1);
+   for (unsigned int k = 0; k < n_elts; ++k)
+ {
+   rtx x = XVECEXP (vals, 0, k);
+ 

[gcc/devel/omp/gcc-14] OpenMP/Fortran: Add missing pop_state in parse_omp_dispatch [PR118714]

2025-02-03 Thread Paul-Antoine Arras via Gcc-cvs
https://gcc.gnu.org/g:da1ae9430415ccdbcc0095cab218d3af68ce735f

commit da1ae9430415ccdbcc0095cab218d3af68ce735f
Author: Paul-Antoine Arras 
Date:   Fri Jan 31 11:41:47 2025 +0100

OpenMP/Fortran: Add missing pop_state in parse_omp_dispatch [PR118714]

When the ST_NONE case is taken, the function returns immediately. Not 
calling
pop_state causes a dangling pointer.

PR fortran/118714

gcc/fortran/ChangeLog:

* parse.cc (parse_omp_dispatch): Add missing pop_state.

(cherry picked from commit af51fe9593ec0e9373f8a453bab2129a48193a44)

Diff:
---
 gcc/fortran/parse.cc | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index 2af580784c9d..409ce9c3e397 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -6408,7 +6408,10 @@ parse_omp_dispatch (void)
 
   st = next_statement ();
   if (st == ST_NONE)
-return st;
+{
+  pop_state ();
+  return st;
+}
   if (st == ST_CALL || st == ST_ASSIGNMENT)
 accept_statement (st);
   else


[gcc r15-7333] hppa: Revise various millicode insn patterns to use match_operand

2025-02-03 Thread John David Anglin via Gcc-cvs
https://gcc.gnu.org/g:88bb18ccd87d43abe401a1228cc337e4b46be88d

commit r15-7333-g88bb18ccd87d43abe401a1228cc337e4b46be88d
Author: John David Anglin 
Date:   Mon Feb 3 11:35:38 2025 -0500

hppa: Revise various millicode insn patterns to use match_operand

LRA does not correctly support hard-register input operands that
are clobbered.  This is needed to support millicode calls on hppa.
The operand setup is sometimes deleted.

This problem can be avoided by hiding hard-register input operands
using match_operand.  This also potentially allows for constraints
that specify the operand is both read and written.

2025-02-03  John David Anglin  

gcc/ChangeLog:

PR rtl-optimization/117248
* config/pa/predicates.md (r25_operand): New predicate.
(r26_operand): Likewise.
* config/pa/pa.md: Use match_operand for r25 and r26 hard
register operands in mult, div, udiv, mod and umod millicode
patterns.

Diff:
---
 gcc/config/pa/pa.md | 56 +
 gcc/config/pa/predicates.md | 16 +
 2 files changed, 52 insertions(+), 20 deletions(-)

diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index df1b61e871f1..23129940e644 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -5632,8 +5632,10 @@
(set_attr "length" "4")])
 
 (define_insn ""
-  [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
-   (clobber (match_operand:SI 0 "register_operand" "=a"))
+  [(set (reg:SI 29)
+   (mult:SI (match_operand:SI 1 "r26_operand" "")
+(match_operand:SI 0 "r25_operand" "")))
+   (clobber (match_operand:SI 2 "register_operand" "=a"))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
@@ -5645,8 +5647,10 @@
  (symbol_ref "pa_attr_length_millicode_call (insn)")))])
 
 (define_insn ""
-  [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
-   (clobber (match_operand:SI 0 "register_operand" "=a"))
+  [(set (reg:SI 29)
+   (mult:SI (match_operand:SI 1 "r26_operand" "")
+(match_operand:SI 0 "r25_operand" "")))
+   (clobber (match_operand:SI 2 "register_operand" "=a"))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 2))]
@@ -5753,8 +5757,9 @@
 
 (define_insn ""
   [(set (reg:SI 29)
-   (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
-   (clobber (match_operand:SI 1 "register_operand" "=a"))
+   (div:SI (match_operand:SI 1 "r26_operand" "")
+   (match_operand:SI 0 "div_operand" "")))
+   (clobber (match_operand:SI 2 "register_operand" "=a"))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
@@ -5768,8 +5773,9 @@
 
 (define_insn ""
   [(set (reg:SI 29)
-   (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
-   (clobber (match_operand:SI 1 "register_operand" "=a"))
+   (div:SI (match_operand:SI 1 "r26_operand" "")
+   (match_operand:SI 0 "div_operand" "")))
+   (clobber (match_operand:SI 2 "register_operand" "=a"))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 2))]
@@ -5800,8 +5806,9 @@
 
 (define_insn ""
   [(set (reg:SI 29)
-   (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
-   (clobber (match_operand:SI 1 "register_operand" "=a"))
+   (udiv:SI (match_operand:SI 1 "r26_operand" "")
+(match_operand:SI 0 "div_operand" "")))
+   (clobber (match_operand:SI 2 "register_operand" "=a"))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
@@ -5815,8 +5822,9 @@
 
 (define_insn ""
   [(set (reg:SI 29)
-   (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
-   (clobber (match_operand:SI 1 "register_operand" "=a"))
+   (udiv:SI (match_operand:SI 1 "r26_operand" "")
+(match_operand:SI 0 "div_operand" "")))
+   (clobber (match_operand:SI 2 "register_operand" "=a"))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 2))]
@@ -5844,8 +5852,10 @@
 }")
 
 (define_insn ""
-  [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
-   (clobber (match_operand:SI 0 "register_operand" "=a"))
+  [(set (reg:SI 29)
+   (mod:SI (match_operand:SI 1 "r26_operand" "")
+   (match_operand:SI 0 "r25_operand" "")))
+   (clobber (match_operand:SI 2 "register_operand" "=a"))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
@@ -5858,8 +5868,10 @@
  (symbol_ref "pa_attr_length_millicode_call (insn)")))])
 
 (define_insn ""
-  [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
-   (clobber (match_operand:SI 0 "register_operand" "=a"))
+  [(set (reg:SI 29)
+   (mod:SI (match_operand:SI 1 "r26_operand" "")
+   (match_operand:SI 0 "r25_operand" "")))
+   (clobber (match_operand:SI 2 "register_operand" "=a"))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 2))]
@

[gcc r15-7343] lto/113207 - fix free_lang_data_in_type

2025-02-03 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:a55e14b239181381204c615335929b3316d75370

commit r15-7343-ga55e14b239181381204c615335929b3316d75370
Author: Richard Biener 
Date:   Mon Feb 3 14:27:01 2025 +0100

lto/113207 - fix free_lang_data_in_type

When we process function types we strip volatile and const qualifiers
after building a simplified type variant (which preserves those).
The qualified type handling of both isn't really compatible, so avoid
bad interaction by swapping this, first dropping const/volatile
qualifiers and then building the simplified type thereof.

PR lto/113207
* ipa-free-lang-data.cc (free_lang_data_in_type): First drop
const/volatile qualifiers from function argument types,
then build a simplified type.

* gcc.dg/pr113207.c: New testcase.

Diff:
---
 gcc/ipa-free-lang-data.cc   |  3 +--
 gcc/testsuite/gcc.dg/pr113207.c | 10 ++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/gcc/ipa-free-lang-data.cc b/gcc/ipa-free-lang-data.cc
index cb26e262f45b..0b666cb225f3 100644
--- a/gcc/ipa-free-lang-data.cc
+++ b/gcc/ipa-free-lang-data.cc
@@ -436,9 +436,7 @@ free_lang_data_in_type (tree type, class free_lang_data_d 
*fld)
 different front ends.  */
   for (tree p = TYPE_ARG_TYPES (type); p; p = TREE_CHAIN (p))
{
- TREE_VALUE (p) = fld_simplified_type (TREE_VALUE (p), fld);
  tree arg_type = TREE_VALUE (p);
-
  if (TYPE_READONLY (arg_type) || TYPE_VOLATILE (arg_type))
{
  int quals = TYPE_QUALS (arg_type)
@@ -448,6 +446,7 @@ free_lang_data_in_type (tree type, class free_lang_data_d 
*fld)
  if (!fld->pset.add (TREE_VALUE (p)))
free_lang_data_in_type (TREE_VALUE (p), fld);
}
+ TREE_VALUE (p) = fld_simplified_type (TREE_VALUE (p), fld);
  /* C++ FE uses TREE_PURPOSE to store initial values.  */
  TREE_PURPOSE (p) = NULL;
}
diff --git a/gcc/testsuite/gcc.dg/pr113207.c b/gcc/testsuite/gcc.dg/pr113207.c
new file mode 100644
index ..81f53d8fcc2f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr113207.c
@@ -0,0 +1,10 @@
+/* { dg-compile } */
+/* { dg-require-effective-target lto } */
+/* { dg-options "-flto -fchecking" }  */
+
+typedef struct cl_lispunion *cl_object;
+struct cl_lispunion {};
+cl_object cl_error() __attribute__((noreturn));
+volatile cl_object cl_coerce_value0;
+void cl_coerce() { cl_error(); }
+void L66safe_canonical_type(cl_object volatile);


[gcc r15-7344] rtl-optimization/117611 - ICE in simplify_shift_const_1

2025-02-03 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:5b46c01c50662a1c730e6658ea4307d4f80da578

commit r15-7344-g5b46c01c50662a1c730e6658ea4307d4f80da578
Author: Richard Biener 
Date:   Mon Feb 3 15:27:30 2025 +0100

rtl-optimization/117611 - ICE in simplify_shift_const_1

The following checks we have a scalar int shift mode before
enforcing it.  As AVR shows the mode can be a signed _Accum mode
as well.

PR rtl-optimization/117611
* combine.cc (simplify_shift_const_1): Bail if not
scalar int mode.

* gcc.dg/fixed-point/pr117611.c: New testcase.

Diff:
---
 gcc/combine.cc  | 6 --
 gcc/testsuite/gcc.dg/fixed-point/pr117611.c | 7 +++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/gcc/combine.cc b/gcc/combine.cc
index 90828108ba4c..3beeb514b817 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -10635,8 +10635,10 @@ simplify_shift_const_1 (enum rtx_code code, 
machine_mode result_mode,
 outer_op, outer_const);
}
 
-  scalar_int_mode shift_unit_mode
-   = as_a  (GET_MODE_INNER (shift_mode));
+  scalar_int_mode shift_unit_mode;
+  if (!is_a  (GET_MODE_INNER (shift_mode),
+  &shift_unit_mode))
+   return NULL_RTX;
 
   /* Handle cases where the count is greater than the size of the mode
 minus 1.  For ASHIFT, use the size minus one as the count (this can
diff --git a/gcc/testsuite/gcc.dg/fixed-point/pr117611.c 
b/gcc/testsuite/gcc.dg/fixed-point/pr117611.c
new file mode 100644
index ..c76093f12d19
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fixed-point/pr117611.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+_Accum acc1 (_Accum x)
+{
+return x << 16;
+}