[gcc r16-534] testsuite: Fix RISC-V arch-52.c format issue.

2025-05-11 Thread Jiawei Chen via Gcc-cvs
https://gcc.gnu.org/g:63d26b0e1f11043552404d2ba6448ec74840fa48

commit r16-534-g63d26b0e1f11043552404d2ba6448ec74840fa48
Author: Jiawei 
Date:   Mon May 12 13:23:50 2025 +0800

testsuite: Fix RISC-V arch-52.c format issue.

Fix incorrect regular expression.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/arch-52.c: Fix regular expression.

Diff:
---
 gcc/testsuite/gcc.target/riscv/arch-52.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/riscv/arch-52.c 
b/gcc/testsuite/gcc.target/riscv/arch-52.c
index da6aea8fd94d..6133370b68ae 100644
--- a/gcc/testsuite/gcc.target/riscv/arch-52.c
+++ b/gcc/testsuite/gcc.target/riscv/arch-52.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-march=rva22u64v -mabi=lp64" } */
-/* { dg-warning "*Should use \"_\" to contact Profiles with other extensions" 
} */
+/* { dg-warning "Should use \"_\" to contact Profiles with other extensions" 
"" { target *-*-* } 0 } */
 int
 foo ()
 {}


[gcc r16-535] x86: Remove df_insn_rescan after emit_insn_*

2025-05-11 Thread H.J. Lu via Gcc-cvs
https://gcc.gnu.org/g:9506c28a557bcea34af13478f05d2d9fc3727072

commit r16-535-g9506c28a557bcea34af13478f05d2d9fc3727072
Author: H.J. Lu 
Date:   Mon May 12 10:02:24 2025 +0800

x86: Remove df_insn_rescan after emit_insn_*

Since df_insn_rescan has been called by emit_insn_*, there is no need
to call it after calling emit_insn_*.  Remove its unnecessary usages.

PR target/120228
* config/i386/i386-features.cc (ix86_place_single_vector_set):
Remove df_insn_rescan after emit_insn_*.
(remove_partial_avx_dependency): Likewise.
(replace_vector_const): Likewise.

Signed-off-by: H.J. Lu 

Diff:
---
 gcc/config/i386/i386-features.cc | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
index 13e6c2a8abd1..cc8313bd292f 100644
--- a/gcc/config/i386/i386-features.cc
+++ b/gcc/config/i386/i386-features.cc
@@ -3095,13 +3095,10 @@ ix86_place_single_vector_set (rtx dest, rtx src, bitmap 
bbs)
   insn = NEXT_INSN (insn);
 }
 
-  rtx_insn *set_insn;
   if (insn == BB_HEAD (bb))
-set_insn = emit_insn_before (set, insn);
+emit_insn_before (set, insn);
   else
-set_insn = emit_insn_after (set,
-   insn ? PREV_INSN (insn) : BB_END (bb));
-  df_insn_rescan (set_insn);
+emit_insn_after (set, insn ? PREV_INSN (insn) : BB_END (bb));
 }
 
 /* At entry of the nearest common dominator for basic blocks with
@@ -3225,7 +3222,6 @@ remove_partial_avx_dependency (void)
  /* Generate an XMM vector SET.  */
  set = gen_rtx_SET (vec, src);
  set_insn = emit_insn_before (set, insn);
- df_insn_rescan (set_insn);
 
  if (cfun->can_throw_non_call_exceptions)
{
@@ -3396,8 +3392,7 @@ replace_vector_const (machine_mode vector_mode, rtx 
vector_const,
  vreg = gen_reg_rtx (vmode);
  rtx vsubreg = gen_rtx_SUBREG (vmode, vector_const, 0);
  rtx pat = gen_rtx_SET (vreg, vsubreg);
- rtx_insn *vinsn = emit_insn_before (pat, insn);
- df_insn_rescan (vinsn);
+ emit_insn_before (pat, insn);
}
  replace = gen_rtx_SUBREG (mode, vreg, 0);
}


[gcc/devel/rust/master] gccrs: desugar APIT impl traits

2025-05-11 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:927d067721e91ad3d702f9b9efaf939afd319ef1

commit 927d067721e91ad3d702f9b9efaf939afd319ef1
Author: Philip Herron 
Date:   Wed Apr 30 14:37:49 2025 +0100

gccrs: desugar APIT impl traits

Argument position impl traits are simply syntatic sugar for generics. This
adds a new desugar pass to do this. So for example:

fn foo(a: impl Value, b: impl Value) -> i32

Is desugared into:

fn foo (a: T, b: U) -> i32

So it just works like any normal generic function. There are more complex 
cases such as:

fn foo(_value: impl Bar) -> i32

Which has a generic argument binding which needs to be turned into a where 
constraint:

fn foo(_value: T) -> i32
where
T: Bar,
U: Foo,

Fixes Rust-GCC#2015
Fixes Rust-GCC#1487
Fixes Rust-GCC#3454
Fixes Rust-GCC#1482

gcc/rust/ChangeLog:

* Make-lang.in: new desugar file
* ast/rust-ast.cc (ImplTraitTypeOneBound::as_string): its a 
unique_ptr now
(FormatArgs::set_outer_attrs): reformat
* ast/rust-path.h: remove has_generic_args assertion (can be empty 
because of desugar)
* ast/rust-type.h (class ImplTraitTypeOneBound): add copy ctor and 
use unique_ptr
* hir/rust-ast-lower-type.cc (ASTLoweringType::visit): update to 
use unique_ptr
* parse/rust-parse-impl.h (Parser::parse_type): reuse the existing 
unique_ptr instead
(Parser::parse_type_no_bounds): likewise
(Parser::parse_pattern): likewise
* resolve/rust-ast-resolve-type.cc (ResolveType::visit): its a 
unique_ptr now
* rust-session-manager.cc (Session::compile_crate): call desugar
* ast/rust-desugar-apit.cc: New file.
* ast/rust-desugar-apit.h: New file.

gcc/testsuite/ChangeLog:

* rust/compile/issue-2015.rs: fully supported now
* rust/compile/nr2/exclude: nr2 cant handle some of these
* rust/compile/issue-1487.rs: New test.
* rust/compile/issue-3454.rs: New test.
* rust/execute/torture/impl_desugar-2.rs: New test.
* rust/execute/torture/impl_desugar.rs: New test.
* rust/execute/torture/impl_trait1.rs: New test.
* rust/execute/torture/impl_trait2.rs: New test.
* rust/execute/torture/impl_trait3.rs: New test.
* rust/execute/torture/impl_trait4.rs: New test.
* rust/execute/torture/issue-1482.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/Make-lang.in  |   1 +
 gcc/rust/ast/rust-ast.cc   |   2 +-
 gcc/rust/ast/rust-desugar-apit.cc  | 516 +
 gcc/rust/ast/rust-desugar-apit.h   |  42 ++
 gcc/rust/ast/rust-path.h   |   6 +-
 gcc/rust/ast/rust-type.h   |  47 +-
 gcc/rust/hir/rust-ast-lower-type.cc|   2 +-
 gcc/rust/parse/rust-parse-impl.h   |  13 +-
 gcc/rust/resolve/rust-ast-resolve-type.cc  |   2 +-
 gcc/rust/rust-session-manager.cc   |   2 +
 gcc/testsuite/rust/compile/issue-1487.rs   |  15 +
 gcc/testsuite/rust/compile/issue-2015.rs   |   3 +-
 gcc/testsuite/rust/compile/issue-3454.rs   |  20 +
 gcc/testsuite/rust/compile/nr2/exclude |   3 +
 .../rust/execute/torture/impl_desugar-2.rs |  32 ++
 gcc/testsuite/rust/execute/torture/impl_desugar.rs |  32 ++
 gcc/testsuite/rust/execute/torture/impl_trait1.rs  |  31 ++
 gcc/testsuite/rust/execute/torture/impl_trait2.rs  |  31 ++
 gcc/testsuite/rust/execute/torture/impl_trait3.rs  |  46 ++
 gcc/testsuite/rust/execute/torture/impl_trait4.rs  |  31 ++
 gcc/testsuite/rust/execute/torture/issue-1482.rs   |  23 +
 21 files changed, 866 insertions(+), 34 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 5ae50d23f8f7..38235f188e64 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -242,6 +242,7 @@ GRS_OBJS = \
rust/rust-collect-lang-items.o \
rust/rust-desugar-for-loops.o \
rust/rust-desugar-question-mark.o \
+   rust/rust-desugar-apit.o \
 $(END)
 # removed object files from here
 
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 494b21a1ba56..0f1a13282e08 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -2714,7 +2714,7 @@ ImplTraitTypeOneBound::as_string () const
 {
   std::string str ("ImplTraitTypeOneBound: \n TraitBound: ");
 
-  return str + trait_bound.as_string ();
+  return str + trait_bound->as_string ();
 }
 
 std::string
diff --git a/gcc/rust/ast/rust-desugar-apit.cc 
b/gcc/rust/ast/rust-desugar-apit.cc
new file mode 100644
index ..2f31bcfe7a32
--- /dev/null
+++ b/gcc/rust/ast/rust-desugar-apit.cc
@@ -0,0 +1,

[gcc/devel/rust/master] gccrs: Emit error diagnostic for bad impl type usage

2025-05-11 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:ef44f649655dcbba63b925c06e923ed1aefd6678

commit ef44f649655dcbba63b925c06e923ed1aefd6678
Author: Philip Herron 
Date:   Mon May 5 21:07:20 2025 +0100

gccrs: Emit error diagnostic for bad impl type usage

Rust only allows impl traits to be used in the return position of
functions.

Fixes Rust-GCC#1485

gcc/rust/ChangeLog:

* hir/rust-ast-lower-implitem.cc (ASTLowerImplItem::visit): allow 
impl type
* hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): likewise
* hir/rust-ast-lower-type.cc (ASTLoweringType::ASTLoweringType): 
new flag for impl trait
(ASTLoweringType::translate): pass flag
(ASTLoweringType::visit): track impl trait tag
(ASTLoweringType::emit_impl_trait_error): new diagnostic
* hir/rust-ast-lower-type.h: add new field

gcc/testsuite/ChangeLog:

* rust/compile/impl_trait_diag.rs: New test.
* rust/compile/issue-1485.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/hir/rust-ast-lower-implitem.cc   |  3 +-
 gcc/rust/hir/rust-ast-lower-item.cc   |  3 +-
 gcc/rust/hir/rust-ast-lower-type.cc   | 57 ---
 gcc/rust/hir/rust-ast-lower-type.h| 13 +++---
 gcc/testsuite/rust/compile/impl_trait_diag.rs | 17 
 gcc/testsuite/rust/compile/issue-1485.rs  | 16 
 6 files changed, 85 insertions(+), 24 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc 
b/gcc/rust/hir/rust-ast-lower-implitem.cc
index 66488ac7892d..c06e88f2b695 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.cc
+++ b/gcc/rust/hir/rust-ast-lower-implitem.cc
@@ -138,7 +138,8 @@ ASTLowerImplItem::visit (AST::Function &function)
 
   std::unique_ptr return_type
 = function.has_return_type () ? std::unique_ptr (
-   ASTLoweringType::translate (function.get_return_type ()))
+   ASTLoweringType::translate (function.get_return_type (), false,
+   true /* impl trait is allowed here*/))
  : nullptr;
 
   Defaultness defaultness
diff --git a/gcc/rust/hir/rust-ast-lower-item.cc 
b/gcc/rust/hir/rust-ast-lower-item.cc
index 47b4b71974a4..9bb968f028f8 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -411,7 +411,8 @@ ASTLoweringItem::visit (AST::Function &function)
 
   std::unique_ptr return_type
 = function.has_return_type () ? std::unique_ptr (
-   ASTLoweringType::translate (function.get_return_type ()))
+   ASTLoweringType::translate (function.get_return_type (), false,
+   true /* impl trait is allowed here*/))
  : nullptr;
 
   std::vector function_params;
diff --git a/gcc/rust/hir/rust-ast-lower-type.cc 
b/gcc/rust/hir/rust-ast-lower-type.cc
index baffbf8b5e39..d871583253c7 100644
--- a/gcc/rust/hir/rust-ast-lower-type.cc
+++ b/gcc/rust/hir/rust-ast-lower-type.cc
@@ -209,10 +209,17 @@ ASTLowerQualifiedPathInType::visit 
(AST::QualifiedPathInType &path)
 path.get_locus ());
 }
 
+ASTLoweringType::ASTLoweringType (bool default_to_static_lifetime,
+ bool impl_trait_allowed)
+  : ASTLoweringBase (), default_to_static_lifetime 
(default_to_static_lifetime),
+impl_trait_allowed (impl_trait_allowed), translated (nullptr)
+{}
+
 HIR::Type *
-ASTLoweringType::translate (AST::Type &type, bool default_to_static_lifetime)
+ASTLoweringType::translate (AST::Type &type, bool default_to_static_lifetime,
+   bool impl_trait_allowed)
 {
-  ASTLoweringType resolver (default_to_static_lifetime);
+  ASTLoweringType resolver (default_to_static_lifetime, impl_trait_allowed);
   type.accept_vis (resolver);
 
   rust_assert (resolver.translated != nullptr);
@@ -260,7 +267,8 @@ ASTLoweringType::visit (AST::BareFunctionType &fntype)
 
   HIR::Type *param_type
= ASTLoweringType::translate (param.get_type (),
- default_to_static_lifetime);
+ default_to_static_lifetime,
+ impl_trait_allowed);
 
   HIR::MaybeNamedParam p (param.get_name (), kind,
  std::unique_ptr (param_type),
@@ -272,7 +280,8 @@ ASTLoweringType::visit (AST::BareFunctionType &fntype)
   if (fntype.has_return_type ())
 {
   return_type = ASTLoweringType::translate (fntype.get_return_type (),
-   default_to_static_lifetime);
+   default_to_static_lifetime,
+   impl_trait_allowed);
 }
 
   auto crate_num = mappings.get_current_crate ();
@@ -292,8 +301,8 @@ ASTLoweringType::visit (AST::TupleType &tuple)
   std::vector> elems;
   for (auto &e : t

[gcc/devel/rust/master] Revert "backend: Remove checks on StructFieldIdentPattern"

2025-05-11 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:8592769349a33ff1fca3777021ad6ea8dab56c7d

commit 8592769349a33ff1fca3777021ad6ea8dab56c7d
Author: Owen Avery 
Date:   Wed Apr 30 16:20:53 2025 -0400

Revert "backend: Remove checks on StructFieldIdentPattern"

This reverts commit 92323dd3bb16f21194891ce463fc865598c6980f.

Diff:
---
 gcc/rust/backend/rust-compile-pattern.cc | 32 +---
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/backend/rust-compile-pattern.cc
index 671025ae8598..94844fed2e84 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -259,16 +259,34 @@ CompilePatternCheckExpr::visit (HIR::StructPattern 
&pattern)
  }
  break;
 
-   case HIR::StructPatternField::ItemType::IDENT_PAT:
- // we only support rebinding patterns at the moment, which always
- // match - so do nothing
+ case HIR::StructPatternField::ItemType::IDENT_PAT: {
+   HIR::StructPatternFieldIdentPat &ident
+ = static_cast (*field.get ());
+
+   size_t offs = 0;
+   ok = variant->lookup_field (ident.get_identifier ().as_string (),
+   nullptr, &offs);
+   rust_assert (ok);
 
- // this needs to change once we actually check that the field
- // matches a certain value, either a literal value or a const one
+   // we may be offsetting by + 1 here since the first field in the
+   // record is always the discriminator
+   offs += adt->is_enum ();
+   tree field_expr
+ = Backend::struct_field_expression (match_scrutinee_expr, offs,
+ ident.get_locus ());
+
+   tree check_expr_sub
+ = CompilePatternCheckExpr::Compile (ident.get_pattern (),
+ field_expr, ctx);
+   check_expr = Backend::arithmetic_or_logical_expression (
+ ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+ check_expr_sub, ident.get_pattern ().get_locus ());
+ }
  break;
 
-   case HIR::StructPatternField::ItemType::IDENT:
- // ident pattern always matches - do nothing
+ case HIR::StructPatternField::ItemType::IDENT: {
+   // ident pattern always matches - do nothing
+ }
  break;
}
 }


[gcc/devel/rust/master] nr2.0: Adjust enum item visitors

2025-05-11 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:11d46d45c3b61169b4466d7bcf2cabb7e79dbb07

commit 11d46d45c3b61169b4466d7bcf2cabb7e79dbb07
Author: Owen Avery 
Date:   Fri May 2 18:37:45 2025 -0400

nr2.0: Adjust enum item visitors

gcc/rust/ChangeLog:

* ast/rust-ast-visitor.cc
(DefaultASTVisitor::visit): Make call to EnumItem visitor from
EnumItem derived class visitors non-virtual.
* ast/rust-collect-lang-items.cc
(CollectLangItems::visit): Handle visitation of classes derived
from EnumItem.
* ast/rust-collect-lang-items.h
(CollectLangItems::visit): Likewise.
* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Call DefaultResolver::visit on EnumItem
instances.

Signed-off-by: Owen Avery 

Diff:
---
 gcc/rust/ast/rust-ast-visitor.cc   |  6 +++---
 gcc/rust/ast/rust-collect-lang-items.cc| 24 ++
 gcc/rust/ast/rust-collect-lang-items.h |  3 +++
 .../resolve/rust-toplevel-name-resolver-2.0.cc |  8 
 4 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 7584d1af5bb1..105417baa636 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -922,7 +922,7 @@ DefaultASTVisitor::visit (AST::EnumItem &item)
 void
 DefaultASTVisitor::visit (AST::EnumItemTuple &item)
 {
-  visit (reinterpret_cast (item));
+  DefaultASTVisitor::visit (reinterpret_cast (item));
   for (auto &field : item.get_tuple_fields ())
 visit (field);
 }
@@ -930,7 +930,7 @@ DefaultASTVisitor::visit (AST::EnumItemTuple &item)
 void
 DefaultASTVisitor::visit (AST::EnumItemStruct &item)
 {
-  visit (reinterpret_cast (item));
+  DefaultASTVisitor::visit (reinterpret_cast (item));
   for (auto &field : item.get_struct_fields ())
 visit (field);
 }
@@ -938,7 +938,7 @@ DefaultASTVisitor::visit (AST::EnumItemStruct &item)
 void
 DefaultASTVisitor::visit (AST::EnumItemDiscriminant &item)
 {
-  visit (reinterpret_cast (item));
+  DefaultASTVisitor::visit (reinterpret_cast (item));
   visit (item.get_expr ());
 }
 
diff --git a/gcc/rust/ast/rust-collect-lang-items.cc 
b/gcc/rust/ast/rust-collect-lang-items.cc
index cd6be7fbeb9c..306c6f747e2b 100644
--- a/gcc/rust/ast/rust-collect-lang-items.cc
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -109,5 +109,29 @@ CollectLangItems::visit (AST::EnumItem &item)
   DefaultASTVisitor::visit (item);
 }
 
+void
+CollectLangItems::visit (AST::EnumItemTuple &item)
+{
+  maybe_add_lang_item (item);
+
+  DefaultASTVisitor::visit (item);
+}
+
+void
+CollectLangItems::visit (AST::EnumItemStruct &item)
+{
+  maybe_add_lang_item (item);
+
+  DefaultASTVisitor::visit (item);
+}
+
+void
+CollectLangItems::visit (AST::EnumItemDiscriminant &item)
+{
+  maybe_add_lang_item (item);
+
+  DefaultASTVisitor::visit (item);
+}
+
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-collect-lang-items.h 
b/gcc/rust/ast/rust-collect-lang-items.h
index ddb34a914ed7..ddc7b51313bd 100644
--- a/gcc/rust/ast/rust-collect-lang-items.h
+++ b/gcc/rust/ast/rust-collect-lang-items.h
@@ -50,6 +50,9 @@ public:
   void visit (AST::Function &item) override;
   void visit (AST::StructStruct &item) override;
   void visit (AST::EnumItem &item) override;
+  void visit (AST::EnumItemTuple &item) override;
+  void visit (AST::EnumItemStruct &item) override;
+  void visit (AST::EnumItemDiscriminant &item) override;
 
 private:
   template  void maybe_add_lang_item (const T &item);
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 3ec06aaf0183..d3ae797655da 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -374,24 +374,32 @@ void
 TopLevel::visit (AST::EnumItem &variant)
 {
   insert_enum_variant_or_error_out (variant.get_identifier (), variant);
+
+  DefaultResolver::visit (variant);
 }
 
 void
 TopLevel::visit (AST::EnumItemTuple &variant)
 {
   insert_enum_variant_or_error_out (variant.get_identifier (), variant);
+
+  DefaultResolver::visit (variant);
 }
 
 void
 TopLevel::visit (AST::EnumItemStruct &variant)
 {
   insert_enum_variant_or_error_out (variant.get_identifier (), variant);
+
+  DefaultResolver::visit (variant);
 }
 
 void
 TopLevel::visit (AST::EnumItemDiscriminant &variant)
 {
   insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+
+  DefaultResolver::visit (variant);
 }
 
 void


[gcc/devel/rust/master] Improve canonical path handling for impl items

2025-05-11 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:98573bd61ef95e4224bc2d050fa1f47d893f2c31

commit 98573bd61ef95e4224bc2d050fa1f47d893f2c31
Author: Owen Avery 
Date:   Fri May 2 20:28:15 2025 -0400

Improve canonical path handling for impl items

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-item.cc
(ResolveItem::visit): Use the return values of
CanonicalPath::inherent_impl_seg and
CanonicalPath::trait_impl_projection_seg more directly.
* util/rust-canonical-path.h
(CanonicalPath::trait_impl_projection_seg): Append "

Diff:
---
 gcc/rust/resolve/rust-ast-resolve-item.cc | 13 ++---
 gcc/rust/util/rust-canonical-path.h   |  8 ++--
 2 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc 
b/gcc/rust/resolve/rust-ast-resolve-item.cc
index fc226cf28c0a..c2626ea0bbbf 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -608,10 +608,7 @@ ResolveItem::visit (AST::InherentImpl &impl_block)
 }
   else
 {
-  std::string seg_buf = "";
-  CanonicalPath seg
-   = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf);
-  cpath = canonical_prefix.append (seg);
+  cpath = canonical_prefix.append (impl_type_seg);
 }
 
   // done setup paths
@@ -732,13 +729,7 @@ ResolveItem::visit (AST::TraitImpl &impl_block)
 }
   else
 {
-  std::string projection_str = canonical_projection.get ();
-  std::string seg_buf
-   = "";
-  CanonicalPath seg
-   = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf);
-  cpath = canonical_prefix.append (seg);
+  cpath = canonical_prefix.append (canonical_projection);
 }
 
   // DONE setup canonical-path
diff --git a/gcc/rust/util/rust-canonical-path.h 
b/gcc/rust/util/rust-canonical-path.h
index 15846348f9c3..33fead9c6c27 100644
--- a/gcc/rust/util/rust-canonical-path.h
+++ b/gcc/rust/util/rust-canonical-path.h
@@ -68,14 +68,18 @@ public:
   trait_impl_projection_seg (NodeId id, const CanonicalPath &trait_seg,
 const CanonicalPath &impl_type_seg)
   {
-return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + " as "
+// https://doc.rust-lang.org/reference/paths.html#canonical-paths
+// should be ""?
+return CanonicalPath::new_seg (id, "");
   }
 
   static CanonicalPath inherent_impl_seg (NodeId id,
  const CanonicalPath &impl_type_seg)
   {
-return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + ">");
+// https://doc.rust-lang.org/reference/paths.html#canonical-paths
+// should be ""?
+return CanonicalPath::new_seg (id, "");
   }
 
   std::string get () const


[gcc/devel/rust/master] gccrs: fix ICE on empty constexpr loops

2025-05-11 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:339415a5a865649972b255cc697691d493453e41

commit 339415a5a865649972b255cc697691d493453e41
Author: Tom Schollenberger 
Date:   Thu May 8 07:26:07 2025 -0400

gccrs: fix ICE on empty constexpr loops

Empty loops have no body which means this is a NULL_TREE during const
evaluation which needs a check. Fixes Rust-GCC #3618.

gcc/rust/ChangeLog:

* backend/rust-constexpr.cc (eval_constant_expression):  Check if t 
is a NULL_TREE

gcc/testsuite/ChangeLog:

* rust/compile/issue-3618.rs: Test empty loops error properly.

Signed-off-by: Tom Schollenberger 

Diff:
---
 gcc/rust/backend/rust-constexpr.cc   | 3 +++
 gcc/testsuite/rust/compile/issue-3618.rs | 1 +
 2 files changed, 4 insertions(+)

diff --git a/gcc/rust/backend/rust-constexpr.cc 
b/gcc/rust/backend/rust-constexpr.cc
index dc2d6b1066be..0ed56c71ad30 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -1901,6 +1901,9 @@ eval_constant_expression (const constexpr_ctx *ctx, tree 
t, bool lval,
 
   location_t loc = EXPR_LOCATION (t);
 
+  if (t == NULL_TREE)
+return NULL_TREE;
+
   if (CONSTANT_CLASS_P (t))
 {
   if (TREE_OVERFLOW (t))
diff --git a/gcc/testsuite/rust/compile/issue-3618.rs 
b/gcc/testsuite/rust/compile/issue-3618.rs
new file mode 100644
index ..97286135e3a5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3618.rs
@@ -0,0 +1 @@
+static _X: () = loop {}; // { dg-error "loop iteration count exceeds limit" }


[gcc r16-529] xtensa: Fix up unwanted spills of SFmode hard registers holding function arguments/returns

2025-05-11 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:6d73d75a7c04caf3457297400372f87765b9a653

commit r16-529-g6d73d75a7c04caf3457297400372f87765b9a653
Author: Takayuki 'January June' Suwa 
Date:   Sun May 11 04:51:11 2025 +0900

xtensa: Fix up unwanted spills of SFmode hard registers holding function 
arguments/returns

Until now (presumably after transition to LRA), hard registers storing
function arguments or return values ​​were spilling undesirably when
TARGET_HARD_FLOAT is enabled.

 /* example */
 float test0(float a, float b) {
   return a + b;
 }
 extern float foo(void);
 float test1(void) {
   return foo() * 3.14f;
 }

 ;; before
 test0:
entry   sp, 48
wfr f0, a2
wfr f1, a3
add.s   f0, f0, f1
s32i.n  a2, sp, 0   ;; unwanted spilling-out
s32i.n  a3, sp, 4   ;;
rfr a2, f0
retw.n
.literal .LC1, 1078523331
 test1:
entry   sp, 48
call8   foo
l32ra8, .LC1
wfr f0, a10
wfr f1, a8
mul.s   f0, f0, f1
s32i.n  a10, sp, 0  ;; unwanted spilling-out
rfr a2, f0
retw.n

Ultimately, that is because the costs of moving between integer and
floating-point hard registers are undefined and the default (large value)
is used.  This patch fixes this.

 ;; after
 test0:
entry   sp, 32
wfr f1, a2
wfr f0, a3
add.s   f0, f1, f0
rfr a2, f0
retw.n
.literal .LC1, 1078523331
 test1:
entry   sp, 32
call8   foo
l32ra8, .LC1
wfr f1, a10
wfr f0, a8
mul.s   f0, f1, f0
rfr a2, f0
retw.n

gcc/ChangeLog:

* config/xtensa/xtensa.cc (xtensa_register_move_cost):
Add appropriate move costs between AR_REGS and FP_REGS.

Diff:
---
 gcc/config/xtensa/xtensa.cc | 28 +++-
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 53db06ec6f2c..621fb0aeb461 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -4430,17 +4430,27 @@ static int
 xtensa_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
   reg_class_t from, reg_class_t to)
 {
-  if (from == to && from != BR_REGS && to != BR_REGS)
+  /* If both are equal (except for BR_REGS) or belong to AR_REGS,
+ the cost is 2 (the default value).  */
+  if ((from == to && from != BR_REGS && to != BR_REGS)
+  || (reg_class_subset_p (from, AR_REGS)
+ && reg_class_subset_p (to, AR_REGS)))
 return 2;
-  else if (reg_class_subset_p (from, AR_REGS)
-  && reg_class_subset_p (to, AR_REGS))
-return 2;
-  else if (reg_class_subset_p (from, AR_REGS) && to == ACC_REG)
-return 3;
-  else if (from == ACC_REG && reg_class_subset_p (to, AR_REGS))
+
+  /* The cost between AR_REGS and FR_REGS must be <= 8 (2x the default
+ MEMORY_MOVE_COST) to avoid unwanted spills, and > 4 (2x the above
+ case) to avoid excessive register-to-register moves.  */
+  if ((reg_class_subset_p (from, AR_REGS) && to == FP_REGS)
+  || (from == FP_REGS && reg_class_subset_p (to, AR_REGS)))
+return 5;
+
+  if ((reg_class_subset_p (from, AR_REGS) && to == ACC_REG)
+  || (from == ACC_REG && reg_class_subset_p (to, AR_REGS)))
 return 3;
-  else
-return 10;
+
+  /* Otherwise, spills to stack (because greater than 2x the default
+ MEMORY_MOVE_COST).  */
+  return 10;
 }
 
 /* Compute a (partial) cost for rtx X.  Return true if the complete


[gcc/devel/rust/master] ast: collector: visit InlineAsm node during ast dump

2025-05-11 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:dd3de3f0e5516573179b2ed412fa87e0c8bd246a

commit dd3de3f0e5516573179b2ed412fa87e0c8bd246a
Author: 0xn4utilus 
Date:   Wed May 7 22:21:10 2025 +0530

ast: collector: visit InlineAsm node during ast dump

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Implement for 
InlineAsm.
* ast/rust-ast-full-decls.h (enum class): Move InlineAsmOption enum 
inside InlineAsm.
* ast/rust-expr.h (enum class): Likewise.
(class InlineAsm): Likewise.
* expand/rust-macro-builtins-asm.cc (check_and_set): Likewise.
(parse_options): Likewise.
* expand/rust-macro-builtins-asm.h (check_and_set): Likewise.
* hir/tree/rust-hir-expr.cc (InlineAsm::InlineAsm): Likewise.
* hir/tree/rust-hir-expr.h: Likewise.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): 
Likewise.

Diff:
---
 gcc/rust/ast/rust-ast-collector.cc | 83 +-
 gcc/rust/ast/rust-ast-full-decls.h |  1 -
 gcc/rust/ast/rust-expr.h   | 59 +-
 gcc/rust/expand/rust-macro-builtins-asm.cc | 35 ---
 gcc/rust/expand/rust-macro-builtins-asm.h  |  2 +-
 gcc/rust/hir/tree/rust-hir-expr.cc |  2 +-
 gcc/rust/hir/tree/rust-hir-expr.h  |  6 +-
 gcc/rust/typecheck/rust-hir-type-check-expr.cc |  2 +-
 8 files changed, 143 insertions(+), 47 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index f0fc4caad663..004b4f3831dd 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -1518,7 +1518,88 @@ TokenCollector::visit (AsyncBlockExpr &expr)
 
 void
 TokenCollector::visit (InlineAsm &expr)
-{}
+{
+  push (Rust::Token::make_identifier (expr.get_locus (), "asm"));
+  push (Rust::Token::make (EXCLAM, expr.get_locus ()));
+  push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
+
+  for (auto &template_str : expr.get_template_strs ())
+push (Rust::Token::make_string (template_str.get_locus (),
+   std::move (template_str.symbol)));
+
+  push (Rust::Token::make (COLON, expr.get_locus ()));
+
+  for (auto &operand : expr.get_operands ())
+{
+  using RegisterType = AST::InlineAsmOperand::RegisterType;
+  switch (operand.get_register_type ())
+   {
+ case RegisterType::In: {
+   visit (operand.get_in ().expr);
+   break;
+ }
+ case RegisterType::Out: {
+   visit (operand.get_out ().expr);
+   break;
+ }
+ case RegisterType::InOut: {
+   visit (operand.get_in_out ().expr);
+   break;
+ }
+ case RegisterType::SplitInOut: {
+   auto split = operand.get_split_in_out ();
+   visit (split.in_expr);
+   visit (split.out_expr);
+   break;
+ }
+ case RegisterType::Const: {
+   visit (operand.get_const ().anon_const.expr);
+   break;
+ }
+ case RegisterType::Sym: {
+   visit (operand.get_sym ().expr);
+   break;
+ }
+ case RegisterType::Label: {
+   visit (operand.get_label ().expr);
+   break;
+ }
+   }
+  push (Rust::Token::make (COMMA, expr.get_locus ()));
+}
+  push (Rust::Token::make (COLON, expr.get_locus ()));
+
+  for (auto &clobber : expr.get_clobber_abi ())
+{
+  push (Rust::Token::make_string (expr.get_locus (),
+ std::move (clobber.symbol)));
+  push (Rust::Token::make (COMMA, expr.get_locus ()));
+}
+  push (Rust::Token::make (COLON, expr.get_locus ()));
+
+  for (auto it = expr.named_args.begin (); it != expr.named_args.end (); ++it)
+{
+  auto &arg = *it;
+  push (
+   Rust::Token::make_identifier (expr.get_locus (), arg.first.c_str ()));
+  push (Rust::Token::make (EQUAL, expr.get_locus ()));
+  push (Rust::Token::make_identifier (expr.get_locus (),
+ std::to_string (arg.second)));
+
+  push (Rust::Token::make (COMMA, expr.get_locus ()));
+}
+
+  push (Rust::Token::make (COLON, expr.get_locus ()));
+
+  for (auto &option : expr.get_options ())
+{
+  push (Rust::Token::make_identifier (
+   expr.get_locus (), InlineAsm::option_to_string (option).c_str ()));
+  push (Rust::Token::make (COMMA, expr.get_locus ()));
+}
+
+  push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
+}
 
 void
 TokenCollector::visit (LlvmInlineAsm &expr)
diff --git a/gcc/rust/ast/rust-ast-full-decls.h 
b/gcc/rust/ast/rust-ast-full-decls.h
index ae103da4401f..418edd27cbc7 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -145,7 +145,6 @@ struct MatchCase;
 class MatchExpr;
 class AwaitExpr;
 class AsyncBlockExpr;
-enum class InlineAsmOp

[gcc/devel/rust/master] gccrs: Adapt attribute lang hook and do some cleanup

2025-05-11 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:0d563507555c48d184059e9d8e4e58fec36a9e53

commit 0d563507555c48d184059e9d8e4e58fec36a9e53
Author: Marc Poulhiès 
Date:   Fri May 9 11:09:58 2025 +0200

gccrs: Adapt attribute lang hook and do some cleanup

Since r14-6076, the LANG_HOOKS_COMMON_ATTRIBUTE_TABLE should not be used and
LANG_HOOKS_ATTRIBUTE_TABLE replaces it.

Add the "cold" attribute to fix PR120018 (and the matching "hot" attribute).

Replace some gcc_assert() by explicit warnings (same as D frontend).

Add some clang-format off/on comment around code that's not correctly
formatted.

gcc/rust/ChangeLog:
PR rust/120018

* rust-attribs.cc (handle_noreturn_attribute): Reindent declaration.
(handle_leaf_attribute): Likewise.
(handle_const_attribute): Likewise.
(handle_malloc_attribute): Likewise.
(handle_pure_attribute): Likewise.
(handle_novops_attribute): Likewise.
(handle_nonnull_attribute): Likewise.
(handle_nothrow_attribute): Likewise.
(handle_type_generic_attribute): Likewise.
(handle_transaction_pure_attribute): Likewise.
(handle_returns_twice_attribute): Likewise.
(handle_fnspec_attribute): Likewise.
(handle_omp_declare_simd_attribute): Likewise.
(handle_cold_attribute): New.
(handle_hot_attribute): New.
(attribute_spec::exclusions attr_cold_hot_exclusions): New.
(grs_langhook_common_attributes): Make it static.
(grs_langhook_common_attribute_table): New.
(grs_langhook_gnu_attributes): New.
(grs_langhook_gnu_attribute_table): New.
(handle_malloc_attribute): Make it static.
(handle_fnspec_attribute): Likewise.
(handle_pure_attribute): Replace gcc_assert by explicit warning.
(handle_novops_attribute): Likewise.
(handle_nothrow_attribute): Likewise.
(handle_returns_twice_attribute): Likewise.
(handle_omp_declare_simd_attribute): Likewise and make it static.
* rust-lang.cc (grs_langhook_gnu_attribute_table): New.
(grs_langhook_common_attribute_table): Adjust type to new hook.
(LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Remove.
(LANG_HOOKS_ATTRIBUTE_TABLE): New.

Signed-off-by: Marc Poulhiès 

Diff:
---
 gcc/rust/rust-attribs.cc | 168 +++
 gcc/rust/rust-lang.cc|  13 ++--
 2 files changed, 134 insertions(+), 47 deletions(-)

diff --git a/gcc/rust/rust-attribs.cc b/gcc/rust/rust-attribs.cc
index 86d5b3dfeb9f..29f70b566048 100644
--- a/gcc/rust/rust-attribs.cc
+++ b/gcc/rust/rust-attribs.cc
@@ -38,35 +38,33 @@ along with GCC; see the file COPYING3.  If not see
  * future.
  */
 
-extern const attribute_spec grs_langhook_common_attribute_table[];
+extern const struct scoped_attribute_specs grs_langhook_gnu_attribute_table;
+extern const struct scoped_attribute_specs grs_langhook_common_attribute_table;
+
+/* clang-format off */
+/* Disable clang-format because it insists in having the return type on a
+   single line (that's for definitions) */
 
 /* Internal attribute handlers for built-in functions.  */
-static tree
-handle_noreturn_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_leaf_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_const_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_malloc_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_pure_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_novops_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_nonnull_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_nothrow_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_type_generic_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_fnspec_attribute (tree *, tree, tree, int, bool *);
-static tree
-handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *);
+static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
+static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
+static tree handle_const_attribute (tree *, tree, tree, int, bool *);
+static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
+static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
+static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
+static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
+static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
+static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
+static tree handle_transaction_pure_a

[gcc/devel/rust/master] Improve struct pattern compilation

2025-05-11 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:23f933b90bb7d5558eef4d956d2a76160beb0e12

commit 23f933b90bb7d5558eef4d956d2a76160beb0e12
Author: Owen Avery 
Date:   Wed Apr 30 21:54:53 2025 -0400

Improve struct pattern compilation

gcc/rust/ChangeLog:

* backend/rust-compile-pattern.cc
(CompilePatternCheckExpr::visit): Fix GENERIC generation in
light of enum layout changes since this code was written.
(CompilePatternBindings::handle_struct_pattern_ident_pat):
Delegate handling of child patterns to another
CompilePatternBindings::Compile call.
(CompilePatternBindings::make_struct_access): Make field name
parameter const qualified.
* backend/rust-compile-pattern.h
(CompilePatternBindings::make_struct_access): Likewise.

gcc/testsuite/ChangeLog:

* rust/execute/torture/struct-pattern-match.rs: New test.

Signed-off-by: Owen Avery 

Diff:
---
 gcc/rust/backend/rust-compile-pattern.cc   | 44 --
 gcc/rust/backend/rust-compile-pattern.h|  2 +-
 .../rust/execute/torture/struct-pattern-match.rs   | 13 +++
 3 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/backend/rust-compile-pattern.cc
index 94844fed2e84..121749ad4662 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -209,6 +209,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
 
   rust_assert (adt->number_of_variants () > 0);
   TyTy::VariantDef *variant = nullptr;
+  tree variant_accesser_expr = nullptr;
   if (adt->is_enum ())
 {
   // lookup the variant
@@ -223,9 +224,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
 
   // find expected discriminant
   // // need to access qualifier the field, if we use QUAL_UNION_TYPE this
-  // // would be DECL_QUALIFIER i think. For now this will just access the
-  // // first record field and its respective qualifier because it will
-  // // always be set because this is all a big special union
+  // // would be DECL_QUALIFIER i think.
   HIR::Expr &discrim_expr = variant->get_discriminant ();
   tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
 
@@ -234,6 +233,14 @@ CompilePatternCheckExpr::visit (HIR::StructPattern 
&pattern)
= Backend::struct_field_expression (match_scrutinee_expr, 0,
pattern.get_path ().get_locus ());
 
+  // access variant data
+  tree scrutinee_union_expr
+   = Backend::struct_field_expression (match_scrutinee_expr, 1,
+   pattern.get_path ().get_locus ());
+  variant_accesser_expr
+   = Backend::struct_field_expression (scrutinee_union_expr, variant_index,
+   pattern.get_path ().get_locus ());
+
   check_expr
= Backend::comparison_expression (ComparisonOperator::EQUAL,
  scrutinee_expr_qualifier_expr,
@@ -245,6 +252,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
   else
 {
   variant = adt->get_variants ().at (0);
+  variant_accesser_expr = match_scrutinee_expr;
   check_expr = boolean_true_node;
 }
 
@@ -268,11 +276,8 @@ CompilePatternCheckExpr::visit (HIR::StructPattern 
&pattern)
nullptr, &offs);
rust_assert (ok);
 
-   // we may be offsetting by + 1 here since the first field in the
-   // record is always the discriminator
-   offs += adt->is_enum ();
tree field_expr
- = Backend::struct_field_expression (match_scrutinee_expr, offs,
+ = Backend::struct_field_expression (variant_accesser_expr, offs,
  ident.get_locus ());
 
tree check_expr_sub
@@ -512,7 +517,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern 
&pattern)
 tree
 CompilePatternBindings::make_struct_access (TyTy::ADTType *adt,
TyTy::VariantDef *variant,
-   Identifier &ident,
+   const Identifier &ident,
int variant_index)
 {
   size_t offs = 0;
@@ -562,26 +567,9 @@ CompilePatternBindings::handle_struct_pattern_ident_pat (
 {
   auto &pattern = static_cast (pat);
 
-  switch (pattern.get_pattern ().get_pattern_type ())
-{
-  case HIR::Pattern::IDENTIFIER: {
-   auto &id
- = static_cast (pattern.get_pattern ());
-
-   CompilePatternBindings::Compile (id, match_scrutinee_expr, ctx);
-  }
-  break;
-default:
-  rust_sorry_at (pat.get_locus (),
-"cannot handle non-identifier struct patterns");
-  re

[gcc/devel/rust/master] gccrs: Prevent passing generic arguments to impl traits in argument position

2025-05-11 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:fc6b54365731c2ebfa1974058c48772e03203fdd

commit fc6b54365731c2ebfa1974058c48772e03203fdd
Author: Philip Herron 
Date:   Wed May 7 16:07:43 2025 +0100

gccrs: Prevent passing generic arguments to impl traits in argument position

When using impl traits in argument position (APIT), they are desugared into 
generics,
and supplying explicit generic arguments is not allowed. This commit adds 
the error
diagnostic E0632 for attempting to pass generic arguments to impl traits, 
completing
the implementation of the APIT feature.

gcc/rust/ChangeLog:

* ast/rust-desugar-apit.cc: track if this is a impl-trait generic
* ast/rust-item.h (class TypeParam): add field to track if from 
impl trait
* hir/rust-ast-lower-type.cc (ASTLowerGenericParam::visit): likewise
* hir/tree/rust-hir-item.cc (TypeParam::TypeParam): upate hir as 
well
(TypeParam::operator=): likewise
* hir/tree/rust-hir-item.h (class TypeParam): likewise
* typecheck/rust-tyty-subst.cc 
(SubstitutionParamMapping::get_generic_param): add error
* typecheck/rust-tyty-subst.h: add const getter for the associated 
TypeParm

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: nr2 cant handle this
* rust/compile/impl_trait_generic_arg.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/ast/rust-desugar-apit.cc  |  6 --
 gcc/rust/ast/rust-item.h   | 25 +-
 gcc/rust/hir/rust-ast-lower-type.cc|  3 ++-
 gcc/rust/hir/tree/rust-hir-item.cc |  9 +---
 gcc/rust/hir/tree/rust-hir-item.h  | 16 ++
 gcc/rust/typecheck/rust-tyty-subst.cc  | 21 --
 gcc/rust/typecheck/rust-tyty-subst.h   |  1 +
 .../rust/compile/impl_trait_generic_arg.rs | 24 +
 gcc/testsuite/rust/compile/nr2/exclude |  1 +
 9 files changed, 73 insertions(+), 33 deletions(-)

diff --git a/gcc/rust/ast/rust-desugar-apit.cc 
b/gcc/rust/ast/rust-desugar-apit.cc
index 2f31bcfe7a32..5b9486ea6714 100644
--- a/gcc/rust/ast/rust-desugar-apit.cc
+++ b/gcc/rust/ast/rust-desugar-apit.cc
@@ -203,7 +203,8 @@ public:
 
 // Create the new generic parameter
 auto generic_param = std::unique_ptr (
-  new TypeParam (ident, type.get_locus (), std::move (bounds)));
+  new TypeParam (ident, type.get_locus (), std::move (bounds), nullptr, {},
+true /*from impl trait*/));
 
 // Store the generic parameter to be added to the function signature
 implicit_generic_params.push_back (std::move (generic_param));
@@ -241,7 +242,8 @@ public:
 
 // Create the new generic parameter
 auto generic_param = std::unique_ptr (
-  new TypeParam (ident, type.get_locus (), std::move (bounds)));
+  new TypeParam (ident, type.get_locus (), std::move (bounds), nullptr, {},
+true /*from impl trait*/));
 
 // Store the generic parameter to be added to the function signature
 implicit_generic_params.push_back (std::move (generic_param));
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index f507c90dc962..2f53f8d117e4 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -51,21 +51,12 @@ class TypePath;
 // A type generic parameter (as opposed to a lifetime generic parameter)
 class TypeParam : public GenericParam
 {
-  // bool has_outer_attribute;
-  // std::unique_ptr outer_attr;
   AST::AttrVec outer_attrs;
-
   Identifier type_representation;
-
-  // bool has_type_param_bounds;
-  // TypeParamBounds type_param_bounds;
-  std::vector>
-type_param_bounds; // inlined form
-
-  // bool has_type;
+  std::vector> type_param_bounds;
   std::unique_ptr type;
-
   location_t locus;
+  bool was_impl_trait;
 
 public:
   Identifier get_type_representation () const { return type_representation; }
@@ -85,18 +76,19 @@ public:
 std::vector> type_param_bounds
 = std::vector> (),
 std::unique_ptr type = nullptr,
-AST::AttrVec outer_attrs = {})
+AST::AttrVec outer_attrs = {}, bool was_impl_trait = false)
 : GenericParam (Analysis::Mappings::get ().get_next_node_id ()),
   outer_attrs (std::move (outer_attrs)),
   type_representation (std::move (type_representation)),
   type_param_bounds (std::move (type_param_bounds)),
-  type (std::move (type)), locus (locus)
+  type (std::move (type)), locus (locus), was_impl_trait (was_impl_trait)
   {}
 
   // Copy constructor uses clone
   TypeParam (TypeParam const &other)
 : GenericParam (other.node_id), outer_attrs (other.outer_attrs),
-  type_representation (other.type_representation), locus (other.locus)
+  type_representation (other.type_representation), locus (other.locus),
+  was_impl_trai

[gcc/devel/rust/master] nr2.0: Adjust resolution of impl items

2025-05-11 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:d90770b53854d6b81e1912a205aeffdd9bfc4078

commit d90770b53854d6b81e1912a205aeffdd9bfc4078
Author: Owen Avery 
Date:   Fri Apr 25 18:06:41 2025 -0400

nr2.0: Adjust resolution of impl items

gcc/rust/ChangeLog:

* ast/rust-path.cc
(TypePath::make_debug_string): Add definition.
* ast/rust-path.h
(TypePath::make_debug_string): Add declaration.
* resolve/rust-default-resolver.cc
(DefaultResolver::visit): Adjust InherentImpl and TraitImpl
visitors to better handle associated item scope.
* resolve/rust-default-resolver.h
(DefaultResolver::maybe_insert_big_self): Add.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Adjust type path resolution errors.
* resolve/rust-rib.h
(Rib::Kind): Add Generics kind.
* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Remove InherentImpl and TraitImpl visitor
overrides.
(TopLevel::maybe_insert_big_self): Add override in order to add
a definition of 'Self'.
* resolve/rust-toplevel-name-resolver-2.0.h
(TopLevel::visit): Remove InherentImpl and TraitImpl visitor
overrides.
(TopLevel::maybe_insert_big_self): Add override.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 

Diff:
---
 gcc/rust/ast/rust-path.cc  | 21 ++
 gcc/rust/ast/rust-path.h   |  2 +
 gcc/rust/resolve/rust-default-resolver.cc  | 45 --
 gcc/rust/resolve/rust-default-resolver.h   |  2 +
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc|  7 ++--
 gcc/rust/resolve/rust-rib.h|  2 +
 .../resolve/rust-toplevel-name-resolver-2.0.cc | 29 ++
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h |  3 +-
 gcc/testsuite/rust/compile/nr2/exclude |  2 -
 9 files changed, 76 insertions(+), 37 deletions(-)

diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc
index 34fddb021a49..ef61d573ab6e 100644
--- a/gcc/rust/ast/rust-path.cc
+++ b/gcc/rust/ast/rust-path.cc
@@ -266,6 +266,27 @@ TypePath::as_simple_path () const
 locus);
 }
 
+std::string
+TypePath::make_debug_string () const
+{
+  rust_assert (!segments.empty ());
+
+  std::string output;
+
+  for (const auto &segment : segments)
+{
+  if (segment != nullptr && !segment->is_lang_item ()
+ && !segment->is_error ())
+   {
+ if (!output.empty () || has_opening_scope_resolution_op ())
+   output.append ("::");
+ output.append (segment->get_ident_segment ().as_string ());
+   }
+}
+
+  return output;
+}
+
 // hopefully definition here will prevent circular dependency issue
 TraitBound *
 TypePath::to_trait_bound (bool in_parens) const
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 31575105d98d..6f53188d9a37 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -1211,6 +1211,8 @@ public:
 
   std::string as_string () const override;
 
+  std::string make_debug_string () const;
+
   /* Converts TypePath to SimplePath if possible (i.e. no generic or function
* arguments). Otherwise returns an empty SimplePath. */
   SimplePath as_simple_path () const;
diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 1ec38bae4d7b..7d8029fe3bfd 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -72,17 +72,54 @@ DefaultResolver::visit (AST::Trait &trait)
 void
 DefaultResolver::visit (AST::InherentImpl &impl)
 {
-  auto inner_fn = [this, &impl] () { AST::DefaultASTVisitor::visit (impl); };
+  visit_outer_attrs (impl);
+  visit (impl.get_visibility ());
+  visit_inner_attrs (impl);
 
-  ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
+  auto inner_fn_inner = [this, &impl] () {
+for (auto &item : impl.get_impl_items ())
+  visit (item);
+  };
+
+  auto inner_fn_outer = [this, &impl, &inner_fn_inner] () {
+maybe_insert_big_self (impl);
+for (auto &generic : impl.get_generic_params ())
+  visit (generic);
+if (impl.has_where_clause ())
+  visit (impl.get_where_clause ());
+visit (impl.get_type ());
+
+ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_inner);
+  };
+
+  ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_outer);
 }
 
 void
 DefaultResolver::visit (AST::TraitImpl &impl)
 {
-  auto inner_fn = [this, &impl] () { AST::DefaultASTVisitor::visit (impl); };
+  visit_outer_attrs (impl);
+  visit (impl.get_visibility ());
+  visit_inner_attrs (impl);
+
+  auto inner_fn_inner = [this, &impl] () {
+for (auto &item : impl.get_impl_items ())
+ 

[gcc r16-528] cobol: Eliminate padding bytes from cbl_declarative_t. [PR119377]

2025-05-11 Thread Robert Dubner via Gcc-cvs
https://gcc.gnu.org/g:d7d24f9cc55d5cf0a70a984d4e63e8a307710d9e

commit r16-528-gd7d24f9cc55d5cf0a70a984d4e63e8a307710d9e
Author: Robert Dubner 
Date:   Sun May 11 13:43:32 2025 -0400

cobol: Eliminate padding bytes from cbl_declarative_t. [PR119377]

By changing the type of a variable in the cbl_declarative_t structure from 
"bool"
to "uint32_t", three uninitialized padding bytes were turned into 
initialized
bytes.  This eliminates the valgrind error caused by those uninitialized 
values.

This is an interim fix, which expediently eliminates the valgrind problem. 
The
underlying design flaw, which involves turning a host-side C++ structure 
into
a run-time data block, is slated for complete replacement in the next few 
weeks.

libgcobol/ChangeLog:

PR cobol/119377
* common-defs.h: (struct cbl_declaratives_t): Change "bool global" 
to
"uint32_t global".

Diff:
---
 libgcobol/common-defs.h | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/libgcobol/common-defs.h b/libgcobol/common-defs.h
index 026f377e74b2..e3471c5ccc3d 100644
--- a/libgcobol/common-defs.h
+++ b/libgcobol/common-defs.h
@@ -458,11 +458,25 @@ struct cbl_enabled_exception_t {
 struct cbl_declarative_t {
   enum { files_max = 16 };
   size_t section; // implies program
-  bool global;
+  uint32_t global;  // See the note below
   ec_type_t type;
   uint32_t nfile, files[files_max];
   cbl_file_mode_t mode;
 
+/*  The ::global member originally was "bool global".  A bool, however, 
occupies
+only one byte of storage.  The structure, in turn, is constructed on
+four-byte boundaries for members, so there were three padding bytes between
+the single byte of global and the ::type member.
+
+When used to create a "blob", where the structure was treated as a stream
+of bytes that were used to create a constructor for an array of bytes,
+valgrind noticed that those three padding bytes were not initialized, and
+generated the appropriate error message.  This made it hard to find other
+problems.
+
+Changing the declaration from "bool" to "uint32_t" seems to have eliminated
+the valgrind error without affecting overall performance.  */
+
   cbl_declarative_t( cbl_file_mode_t mode = file_mode_none_e )
 : section(0), global(false)
 , type(ec_none_e)


[gcc r16-531] i386: Fix move costs in vectorizer cost model.

2025-05-11 Thread Jan Hubicka via Gcc-cvs
https://gcc.gnu.org/g:37e61c793c1b22bdcfbf142cd6086da2745be596

commit r16-531-g37e61c793c1b22bdcfbf142cd6086da2745be596
Author: Jan Hubicka 
Date:   Sun May 11 23:49:11 2025 +0200

i386: Fix move costs in vectorizer cost model.

This patch complements the change to stv and uses COSTS_N_INSNS (...)/2
to convert move costs to COSTS_N_INSNS based costs used by vectorizer.
The patch makes pr9981 to XPASS so I removed xfail but it also makes
pr91446 fail.  This is about SLP

/* { dg-options "-O2 -march=icelake-server -ftree-slp-vectorize 
-mtune-ctrl=^sse_typeless_stores" } */

typedef struct
{
  unsigned long long width, height;
  long long x, y;
} info;

extern void bar (info *);

void
foo (unsigned long long width, unsigned long long height,
 long long x, long long y)
{
  info t;
  t.width = width;
  t.height = height;
  t.x = x;
  t.y = y;
  bar (&t);
}

/* { dg-final { scan-assembler-times "vmovdqa\[^\n\r\]*xmm\[0-9\]" 2 } } */

With fixed cost the construction cost is now too large so vectorization does
not happen.  This is the hack increasing cost to account integer->sse move 
which
I think we can handle incrementally.

gcc/ChangeLog:

* config/i386/i386.cc (ix86_widen_mult_cost): Use sse_op to cost
SSE integer addition.
(ix86_multiplication_cost): Use COSTS_N_INSNS (...)/2 to cost sse
loads.
(ix86_shift_rotate_cost): Likewise.
(ix86_vector_costs::add_stmt_cost): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr91446.c: xfail.
* gcc.target/i386/pr99881.c: remove xfail.

Diff:
---
 gcc/config/i386/i386.cc | 26 +++---
 gcc/testsuite/gcc.target/i386/pr91446.c |  2 +-
 gcc/testsuite/gcc.target/i386/pr99881.c |  2 +-
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 9c24a926a890..3d629b06094a 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -21753,7 +21753,7 @@ ix86_widen_mult_cost (const struct processor_costs 
*cost,
   /* pmuludq under sse2, pmuldq under sse4.1, for sign_extend,
 require extra 4 mul, 4 add, 4 cmp and 2 shift.  */
   if (!TARGET_SSE4_1 && !uns_p)
-   extra_cost = (cost->mulss + cost->addss + cost->sse_op) * 4
+   extra_cost = (cost->mulss + cost->sse_op + cost->sse_op) * 4
  + cost->sse_op * 2;
   /* Fallthru.  */
 case V4DImode:
@@ -21803,11 +21803,11 @@ ix86_multiplication_cost (const struct 
processor_costs *cost,
  else if (TARGET_AVX2)
nops += 2;
  else if (TARGET_XOP)
-   extra += cost->sse_load[2];
+   extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
  else
{
  nops += 1;
- extra += cost->sse_load[2];
+ extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
}
  goto do_qimode;
 
@@ -21826,13 +21826,13 @@ ix86_multiplication_cost (const struct 
processor_costs *cost,
{
  nmults += 1;
  nops += 2;
- extra += cost->sse_load[2];
+ extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
}
  else
{
  nmults += 1;
  nops += 4;
- extra += cost->sse_load[2];
+ extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
}
  goto do_qimode;
 
@@ -21845,14 +21845,16 @@ ix86_multiplication_cost (const struct 
processor_costs *cost,
{
  nmults += 1;
  nops += 4;
- extra += cost->sse_load[3] * 2;
+ /* 2 loads, so no division by 2.  */
+ extra += COSTS_N_INSNS (cost->sse_load[3]);
}
  goto do_qimode;
 
case V64QImode:
  nmults = 2;
  nops = 9;
- extra = cost->sse_load[3] * 2 + cost->sse_load[4] * 2;
+ /* 2 loads of each size, so no division by 2.  */
+ extra = COSTS_N_INSNS (cost->sse_load[3] + cost->sse_load[4]);
 
do_qimode:
  return ix86_vec_cost (mode, cost->mulss * nmults
@@ -21945,7 +21947,7 @@ ix86_shift_rotate_cost (const struct processor_costs 
*cost,
/* Use vpbroadcast.  */
extra = cost->sse_op;
  else
-   extra = cost->sse_load[2];
+   extra = COSTS_N_INSNS (cost->sse_load[2]) / 2;
 
  if (constant_op1)
{
@@ -21976,7 +21978,7 @@ ix86_shift_rotate_cost (const struct processor_costs 
*cost,
 shift with one insn set the cost to prefer paddb.  */
  if (constant_op1)
{
- extra = cost->sse_load[2];
+ extra = COSTS_N_INSNS (cost->sse_load[2]) / 2;
  return ix86_vec_cost (mode, cost->sse_op) + extr

[gcc r14-11758] tree-optimization/113197 - bougs assert in PTA

2025-05-11 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:0902cdb6069c12a027a1d0cfd1b7a0daa1a21b5c

commit r14-11758-g0902cdb6069c12a027a1d0cfd1b7a0daa1a21b5c
Author: Richard Biener 
Date:   Mon Sep 30 09:07:36 2024 +0200

tree-optimization/113197 - bougs assert in PTA

PTA asserts that EAF_NO_DIRECT_READ is not set when flags are
set consistently which doesn't make sense.  The following removes
the assert.

PR tree-optimization/113197
* tree-ssa-structalias.cc (handle_call_arg): Remove bougs
assert.

* gcc.dg/lto/pr113197_0.c: New testcase.
* gcc.dg/lto/pr113197_1.c: Likewise.

(cherry picked from commit 02f4efe3c12cf7ef54e5a71b11044c15be5c7fab)

Diff:
---
 gcc/testsuite/gcc.dg/lto/pr113197_0.c | 15 +++
 gcc/testsuite/gcc.dg/lto/pr113197_1.c |  3 +++
 gcc/tree-ssa-structalias.cc   |  1 -
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/lto/pr113197_0.c 
b/gcc/testsuite/gcc.dg/lto/pr113197_0.c
new file mode 100644
index ..293c8207dee0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr113197_0.c
@@ -0,0 +1,15 @@
+/* { dg-lto-do link } */
+/* { dg-lto-options { { -O -flto -fpie } } } */
+/* { dg-extra-ld-options { -r -nostdlib -flinker-output=nolto-rel } } */
+
+enum a { b } register_dccp();
+void c();
+void __attribute__((noreturn)) exit_error(enum a d) {
+  __builtin_va_list va;
+  __builtin_va_end(va);
+  if (d)
+c();
+  c();
+  __builtin_exit(1);
+}
+int main() { register_dccp(); }
diff --git a/gcc/testsuite/gcc.dg/lto/pr113197_1.c 
b/gcc/testsuite/gcc.dg/lto/pr113197_1.c
new file mode 100644
index ..30bf6f7e7c5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr113197_1.c
@@ -0,0 +1,3 @@
+int a;
+void exit_error();
+void register_dccp() { exit_error(a); }
diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc
index c6e3361d9e19..b6a5de1a8f6b 100644
--- a/gcc/tree-ssa-structalias.cc
+++ b/gcc/tree-ssa-structalias.cc
@@ -4117,7 +4117,6 @@ handle_call_arg (gcall *stmt, tree arg, vec 
*results, int flags,
 {
   make_transitive_closure_constraints (tem);
   callarg_transitive = true;
-  gcc_checking_assert (!(flags & EAF_NO_DIRECT_READ));
 }
 
   /* If necessary, produce varinfo for indirect accesses to ARG.  */


[gcc r14-11760] DSE: Fix ICE after allow vector type in get_stored_val

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

commit r14-11760-gbe76efab038d65209a8fcb6d5fe151047007e9f0
Author: Pan Li 
Date:   Tue Apr 30 09:42:39 2024 +0800

DSE: Fix ICE after allow vector type in get_stored_val

We allowed vector type for get_stored_val when read is less than or
equal to store in previous.  Unfortunately,  the valididate_subreg
treats the vector type's size is less than vector register as
invalid.  Then we will have ICE here.

This patch would like to fix it by filter-out the invalid type size,
and make sure the subreg is valid for both the read_mode and store_mode
before perform the real gen_lowpart.

The below test suites are passed for this patch:

* The x86 bootstrap test.
* The x86 regression test.
* The riscv rv64gcv regression test.
* The riscv rv64gc regression test.
* The aarch64 regression test.

gcc/ChangeLog:

* dse.cc (get_stored_val): Make sure read_mode/write_mode
is valid subreg before gen_lowpart.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/bug-6.c: New test.

Signed-off-by: Pan Li 
(cherry picked from commit 88b3f83238087cbe2aa2c51c6054796856f2fb94)

Diff:
---
 gcc/dse.cc  |  4 +++-
 gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c | 22 ++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/gcc/dse.cc b/gcc/dse.cc
index edc7a1dfecf7..1596da91da08 100644
--- a/gcc/dse.cc
+++ b/gcc/dse.cc
@@ -1946,7 +1946,9 @@ get_stored_val (store_info *store_info, machine_mode 
read_mode,
 copy_rtx (store_info->const_rhs));
   else if (VECTOR_MODE_P (read_mode) && VECTOR_MODE_P (store_mode)
 && known_le (GET_MODE_BITSIZE (read_mode), GET_MODE_BITSIZE (store_mode))
-&& targetm.modes_tieable_p (read_mode, store_mode))
+&& targetm.modes_tieable_p (read_mode, store_mode)
+&& validate_subreg (read_mode, store_mode, copy_rtx (store_info->rhs),
+   subreg_lowpart_offset (read_mode, store_mode)))
 read_reg = gen_lowpart (read_mode, copy_rtx (store_info->rhs));
   else
 read_reg = extract_low_bits (read_mode, store_mode,
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c
new file mode 100644
index ..5bb00b8f587e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-6.c
@@ -0,0 +1,22 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize" } */
+
+struct A { float x, y; };
+struct B { struct A u; };
+
+extern void bar (struct A *);
+
+float
+f3 (struct B *x, int y)
+{
+  struct A p = {1.0f, 2.0f};
+  struct A *q = &x[y].u;
+
+  __builtin_memcpy (&q->x, &p.x, sizeof (float));
+  __builtin_memcpy (&q->y, &p.y, sizeof (float));
+
+  bar (&p);
+
+  return x[y].u.x + x[y].u.y;
+}


[gcc r14-11759] testsuite: Require effective target pie for pr113197

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

commit r14-11759-gaef1a618e200158e5f83331ae618492d1ef3573d
Author: Dimitar Dimitrov 
Date:   Thu Oct 24 19:59:42 2024 +0300

testsuite: Require effective target pie for pr113197

The test for PR113197 explicitly enables PIE.  But targets without PIE
emit warnings when -fpie is passed (e.g. pru and avr), which causes the
test to fail.

Fix by adding an effective target requirement for PIE.

With this patch, the test now is marked as unsupported for
pru-unknown-elf.  Testing for x86_64-pc-linux-gnu passes with current
mainline, and fails if the fix from r15-4018-g02f4efe3c12cf7 is
reverted.

PR ipa/113197

gcc/testsuite/ChangeLog:

* gcc.dg/lto/pr113197_0.c: Require effective target pie.

Signed-off-by: Dimitar Dimitrov 
(cherry picked from commit bcd56224d74cdd8dc3c77097de51e97bc7b6d181)

Diff:
---
 gcc/testsuite/gcc.dg/lto/pr113197_0.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.dg/lto/pr113197_0.c 
b/gcc/testsuite/gcc.dg/lto/pr113197_0.c
index 293c8207dee0..6fd86245d30a 100644
--- a/gcc/testsuite/gcc.dg/lto/pr113197_0.c
+++ b/gcc/testsuite/gcc.dg/lto/pr113197_0.c
@@ -1,4 +1,5 @@
 /* { dg-lto-do link } */
+/* { dg-require-effective-target pie } */
 /* { dg-lto-options { { -O -flto -fpie } } } */
 /* { dg-extra-ld-options { -r -nostdlib -flinker-output=nolto-rel } } */


[gcc r13-9648] testsuite: Add testcase for already fixed PR [PR117498]

2025-05-11 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:02e9aa56a469ea6c3021a4d3052cb229cdda4e04

commit r13-9648-g02e9aa56a469ea6c3021a4d3052cb229cdda4e04
Author: Jakub Jelinek 
Date:   Fri Jan 31 12:39:34 2025 +0100

testsuite: Add testcase for already fixed PR [PR117498]

This wrong-code issue has been fixed with r15-7249.
We still emit warnings which are questionable and perhaps we'd
get better generated code if niters determined the loop has only a single
iteration without UB and we'd punt on vectorizing it (or unrolling).

2025-01-31  Jakub Jelinek  

PR middle-end/117498
* gcc.c-torture/execute/pr117498.c: New test.

(cherry picked from commit 9fc0683082067801e3790f7cfffedbf5441e0f82)

Diff:
---
 gcc/testsuite/gcc.c-torture/execute/pr117498.c | 35 ++
 1 file changed, 35 insertions(+)

diff --git a/gcc/testsuite/gcc.c-torture/execute/pr117498.c 
b/gcc/testsuite/gcc.c-torture/execute/pr117498.c
new file mode 100644
index ..085c6b6684bc
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr117498.c
@@ -0,0 +1,35 @@
+/* PR middle-end/117498 */
+
+int a, d, f;
+char g;
+volatile int c = 1;
+
+int
+foo ()
+{
+  if (c == 0)
+return -1;
+  return 1;
+}
+
+void
+bar (int h, int i, char *k, char *m)
+{
+  for (; d < i; d += 2)
+for (int j = 0; j < h; j++)
+  m[j] = k[4 * j];
+}
+
+void
+baz (long h)
+{
+  char n = 0;
+  bar (h, 4, &n, &g);
+}
+
+int
+main ()
+{
+  f = foo ();
+  baz ((unsigned char) f - 4);
+}


[gcc r14-11757] testsuite: Add testcase for already fixed PR [PR117498]

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

commit r14-11757-gcc589c2a4be9bf7242d7f17d44629fb87309a4a9
Author: Jakub Jelinek 
Date:   Fri Jan 31 12:39:34 2025 +0100

testsuite: Add testcase for already fixed PR [PR117498]

This wrong-code issue has been fixed with r15-7249.
We still emit warnings which are questionable and perhaps we'd
get better generated code if niters determined the loop has only a single
iteration without UB and we'd punt on vectorizing it (or unrolling).

2025-01-31  Jakub Jelinek  

PR middle-end/117498
* gcc.c-torture/execute/pr117498.c: New test.

(cherry picked from commit 9fc0683082067801e3790f7cfffedbf5441e0f82)

Diff:
---
 gcc/testsuite/gcc.c-torture/execute/pr117498.c | 35 ++
 1 file changed, 35 insertions(+)

diff --git a/gcc/testsuite/gcc.c-torture/execute/pr117498.c 
b/gcc/testsuite/gcc.c-torture/execute/pr117498.c
new file mode 100644
index ..085c6b6684bc
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr117498.c
@@ -0,0 +1,35 @@
+/* PR middle-end/117498 */
+
+int a, d, f;
+char g;
+volatile int c = 1;
+
+int
+foo ()
+{
+  if (c == 0)
+return -1;
+  return 1;
+}
+
+void
+bar (int h, int i, char *k, char *m)
+{
+  for (; d < i; d += 2)
+for (int j = 0; j < h; j++)
+  m[j] = k[4 * j];
+}
+
+void
+baz (long h)
+{
+  char n = 0;
+  bar (h, 4, &n, &g);
+}
+
+int
+main ()
+{
+  f = foo ();
+  baz ((unsigned char) f - 4);
+}


[gcc r15-9653] tree-optimization/120143 - ICE with failed early break store move

2025-05-11 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:94d10c0ef2dca46f1c043c81bcda67ee7e2efc67

commit r15-9653-g94d10c0ef2dca46f1c043c81bcda67ee7e2efc67
Author: Richard Biener 
Date:   Wed May 7 09:43:54 2025 +0200

tree-optimization/120143 - ICE with failed early break store move

The early break vectorization store moving was incorrectly trying
to move the pattern stmt instead of the original one which failed
to register and then confused virtual SSA form due to the update
triggered by a degenerate virtual PHI.

PR tree-optimization/120143
* tree-vect-data-refs.cc (vect_analyze_early_break_dependences):
Move/update the original stmts, not the pattern stmts which
lack virtual operands and are not in the IL.

* gcc.dg/vect/vect-early-break_135-pr120143.c: New testcase.

(cherry picked from commit da377e7ebf84a05943fb768eaeb7d682dee865fa)

Diff:
---
 .../gcc.dg/vect/vect-early-break_135-pr120143.c| 18 ++
 gcc/tree-vect-data-refs.cc |  1 -
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_135-pr120143.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_135-pr120143.c
new file mode 100644
index ..1ee30a821e2f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_135-pr120143.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-add-options vect_early_break } */
+/* { dg-additional-options "-O3 -fwhole-program" } */
+
+short a;
+extern _Bool b[][23];
+short g = 6;
+int v[4];
+int x[3];
+void c(short g, int v[], int x[]) {
+  for (;;)
+for (unsigned y = 0; y < 023; y++) {
+  b[y][y] = v[y];
+  for (_Bool aa = 0; aa < (_Bool)g; aa = x[y])
+a = a > 0;
+}
+}
+int main() { c(g, v, x); }
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index c9395e33fcdf..3ba271b9e692 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -734,7 +734,6 @@ vect_analyze_early_break_dependences (loop_vec_info 
loop_vinfo)
 
  stmt_vec_info stmt_vinfo
= vect_stmt_to_vectorize (loop_vinfo->lookup_stmt (stmt));
- stmt = STMT_VINFO_STMT (stmt_vinfo);
  auto dr_ref = STMT_VINFO_DATA_REF (stmt_vinfo);
  if (!dr_ref)
continue;


[gcc r15-9651] tree-optimization/120043 - bogus conditional store elimination

2025-05-11 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:856c493db1d5e2fa9377f4a0c438afbcaf6c7e01

commit r15-9651-g856c493db1d5e2fa9377f4a0c438afbcaf6c7e01
Author: Richard Biener 
Date:   Thu May 8 10:05:42 2025 +0200

tree-optimization/120043 - bogus conditional store elimination

The following fixes conditional store elimination to properly
check for conditional stores to readonly memory which we can
obviously not store to unconditionally.  The tree_could_trap_p
predicate used is only considering rvalues and the chosen
approach mimics that of loop store motion.

PR tree-optimization/120043
* tree-ssa-phiopt.cc (cond_store_replacement): Check
whether the store is to readonly memory.

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

(cherry picked from commit 93586e5d51188bf71f4f8fae4ee94ff631740f24)

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr120043.c | 10 ++
 gcc/tree-ssa-phiopt.cc  |  8 +++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr120043.c 
b/gcc/testsuite/gcc.dg/torture/pr120043.c
new file mode 100644
index ..ae27468d86dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr120043.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fallow-store-data-races" } */
+
+const int a;
+int *b;
+int main()
+{
+  &a != b || (*b = 1);
+  return 0;
+}
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index a194bf675e4e..7f3390be31e5 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -3559,8 +3559,14 @@ cond_store_replacement (basic_block middle_bb, 
basic_block join_bb,
   /* If LHS is an access to a local variable without address-taken
 (or when we allow data races) and known not to trap, we could
 always safely move down the store.  */
+  tree base;
   if (ref_can_have_store_data_races (lhs)
- || tree_could_trap_p (lhs))
+ || tree_could_trap_p (lhs)
+ /* tree_could_trap_p is a predicate for rvalues, so check
+for readonly memory explicitly.  */
+ || ((base = get_base_address (lhs))
+ && DECL_P (base)
+ && TREE_READONLY (base)))
return false;
 }


[gcc r15-9652] tree-optimization/120089 - force all PHIs live for early-break vect

2025-05-11 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:4017b37de2b39f4bbd7bb9524101558002a258e8

commit r15-9652-g4017b37de2b39f4bbd7bb9524101558002a258e8
Author: Richard Biener 
Date:   Mon May 5 14:29:34 2025 +0200

tree-optimization/120089 - force all PHIs live for early-break vect

The following makes sure to even mark unsupported PHIs live when
doing early-break vectorization since otherwise we fail to validate
we can vectorize those and generate wrong code based on the scalar
PHIs which would only work with a vectorization factor of one.

PR tree-optimization/120089
* tree-vect-stmts.cc (vect_stmt_relevant_p): Mark all
PHIs live when not already so and doing early-break
vectorization.
(vect_mark_stmts_to_be_vectorized): Skip virtual PHIs.
* tree-vect-slp.cc (vect_analyze_slp): Robustify handling
of early-break forced IVs.

* gcc.dg/vect/vect-early-break_134-pr120089.c: New testcase.

(cherry picked from commit 9def392a1b63a198d15d972f73b4afc888389d7c)

Diff:
---
 .../gcc.dg/vect/vect-early-break_134-pr120089.c| 66 ++
 gcc/tree-vect-slp.cc   | 17 +++---
 gcc/tree-vect-stmts.cc | 19 ---
 3 files changed, 87 insertions(+), 15 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_134-pr120089.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_134-pr120089.c
new file mode 100644
index ..4d8199ca6373
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_134-pr120089.c
@@ -0,0 +1,66 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-additional-options "-funswitch-loops" } */
+
+#include "tree-vect.h"
+
+typedef int type;
+typedef type Vec2[2];
+
+struct BytesVec {
+type d[100];
+};
+
+__attribute__((noipa)) struct BytesVec
+buildVertexBufferData(const Vec2 *origVertices, bool needsZW,
+  unsigned paddingSize, unsigned long t) {
+const unsigned vertexCount = t;
+struct BytesVec data = (struct BytesVec){.d = {0}};
+type *nextVertexPtr = data.d;
+
+for (unsigned vertexIdx = 0u; vertexIdx < vertexCount; ++vertexIdx) {
+
+if (vertexIdx > t)
+__builtin_trap();
+__builtin_memcpy(nextVertexPtr, &origVertices[vertexIdx],
+ 2 * sizeof(type));
+nextVertexPtr += 2;
+
+if (needsZW) {
+nextVertexPtr += 2;
+}
+
+nextVertexPtr += paddingSize;
+}
+
+return data;
+}
+Vec2 origVertices[] = {
+{0, 1}, {2, 3}, {4, 5}, {6, 7},
+{8, 9}, {10, 11}, {12, 13}, {14, 15},
+{16, 17}, {18, 19}, {20, 21}, {22, 23},
+{24, 25}, {26, 27}, {27, 28}, {29, 30},
+};
+
+int main()
+{
+  check_vect ();
+  struct BytesVec vec
+= buildVertexBufferData(origVertices, false, 0,
+   sizeof(origVertices) / sizeof(origVertices[0]));
+
+  int errors = 0;
+  for (unsigned i = 0; i < 100; i++) {
+  if (i / 2 < sizeof(origVertices) / sizeof(origVertices[0])) {
+ int ii = i;
+ int e = origVertices[ii / 2][ii % 2];
+ if (vec.d[i] != e)
+   errors++;
+  } else {
+ if (vec.d[i] != 0)
+   errors++;
+  }
+  }
+  if (errors)
+__builtin_abort();
+  return 0;
+}
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 19beeed8a3a9..958f000e7d6d 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -5040,14 +5040,17 @@ vect_analyze_slp (vec_info *vinfo, unsigned 
max_tree_size,
vec roots = vNULL;
vec remain = vNULL;
gphi *phi = as_a (STMT_VINFO_STMT (stmt_info));
-   stmts.create (1);
tree def = gimple_phi_arg_def_from_edge (phi, latch_e);
stmt_vec_info lc_info = loop_vinfo->lookup_def (def);
-   stmts.quick_push (vect_stmt_to_vectorize (lc_info));
-   vect_build_slp_instance (vinfo, slp_inst_kind_reduc_group,
-stmts, roots, remain,
-max_tree_size, &limit,
-bst_map, NULL, force_single_lane);
+   if (lc_info)
+ {
+   stmts.create (1);
+   stmts.quick_push (vect_stmt_to_vectorize (lc_info));
+   vect_build_slp_instance (vinfo, slp_inst_kind_reduc_group,
+stmts, roots, remain,
+max_tree_size, &limit,
+bst_map, NULL, force_single_lane);
+ }
/* When the latch def is from a different cycle this can only
   be a induction.  Build a simple instance for this.
   ???  We should be able to start discovery from the PHI
@@ -5057,8 +5060,6 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size,
tem.quick_push (stmt_info);
if (!bst_map->get (tem))
  {

[gcc r15-9654] ipa/120146 - deal with vanished varpool nodes in IPA PTA

2025-05-11 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:47e830211d39b5efb14144bbdaf8f2d83ba8375e

commit r15-9654-g47e830211d39b5efb14144bbdaf8f2d83ba8375e
Author: Richard Biener 
Date:   Wed May 7 10:20:55 2025 +0200

ipa/120146 - deal with vanished varpool nodes in IPA PTA

I don't understand why they vanish when still refered to, but
lets deal with that in a conservative way.

PR ipa/120146
* tree-ssa-structalias.cc (create_variable_info_for): If
the symtab cannot tell us whether all refs to a variable
are explicit assume they are not.

* g++.dg/ipa/pr120146.C: New testcase.

(cherry picked from commit b38e3a7196d25bc8bcb1fe55da7663745cea9470)

Diff:
---
 gcc/testsuite/g++.dg/ipa/pr120146.C | 12 
 gcc/tree-ssa-structalias.cc |  4 ++--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/g++.dg/ipa/pr120146.C 
b/gcc/testsuite/g++.dg/ipa/pr120146.C
new file mode 100644
index ..33644b4f7a61
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr120146.C
@@ -0,0 +1,12 @@
+// { dg-do compile }
+// { dg-options "-O -fipa-pta" }
+
+struct basic_ios {
+  ~basic_ios();
+};
+struct basic_istream : virtual basic_ios {};
+template  struct basic_ifstream : basic_istream {
+  template  basic_ifstream(_Path, int);
+};
+extern template class basic_ifstream;
+void CompareFiles_path2() { basic_ifstream(CompareFiles_path2, 0); }
diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc
index 3ad0c69930c7..deca44ae0bf3 100644
--- a/gcc/tree-ssa-structalias.cc
+++ b/gcc/tree-ssa-structalias.cc
@@ -6562,7 +6562,7 @@ create_variable_info_for (tree decl, const char *name, 
bool add_id)
  varpool_node *vnode = varpool_node::get (decl);
 
  /* For escaped variables initialize them from nonlocal.  */
- if (!vnode->all_refs_explicit_p ())
+ if (!vnode || !vnode->all_refs_explicit_p ())
make_copy_constraint (vi, nonlocal_id);
 
  /* While we can in theory walk references for the varpool
@@ -6581,7 +6581,7 @@ create_variable_info_for (tree decl, const char *name, 
bool add_id)
process_constraint (new_constraint (lhs, *rhsp));
  /* If this is a variable that escapes from the unit
 the initializer escapes as well.  */
- if (!vnode->all_refs_explicit_p ())
+ if (!vnode || !vnode->all_refs_explicit_p ())
{
  lhs.var = escaped_id;
  lhs.offset = 0;


[gcc r15-9655] tree-optimization/120211 - constrain LOOP_VINFO_EARLY_BREAKS_LIVE_IVS more

2025-05-11 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:44cd55a1df897e3160cffeb10f96171bafc06400

commit r15-9655-g44cd55a1df897e3160cffeb10f96171bafc06400
Author: Richard Biener 
Date:   Sun May 11 14:03:12 2025 +0200

tree-optimization/120211 - constrain LOOP_VINFO_EARLY_BREAKS_LIVE_IVS more

The PR120089 fix added more PHIs to LOOP_VINFO_EARLY_BREAKS_LIVE_IVS
but not checking that we only add PHIs with a latch argument.  The
following adds this missing check.

PR tree-optimization/120211
* tree-vect-stmts.cc (vect_stmt_relevant_p): Only add PHIs
from the loop header to LOOP_VINFO_EARLY_BREAKS_LIVE_IVS.

* gcc.dg/vect/vect-early-break_135-pr120211.c: New testcase.
* gcc.dg/torture/pr120211-1.c: Likewise.

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr120211-1.c| 20 
 .../gcc.dg/vect/vect-early-break_135-pr120211.c  | 12 
 gcc/tree-vect-stmts.cc   |  1 +
 3 files changed, 33 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/torture/pr120211-1.c 
b/gcc/testsuite/gcc.dg/torture/pr120211-1.c
new file mode 100644
index ..f9bc97cab5b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr120211-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+int a, b, d;
+void e() {
+  do {
+int f = 0;
+while (1) {
+  int c = a;
+  for (; (c & 1) == 0; c = 1)
+for (; c & 1;)
+  ;
+  if (a)
+break;
+  f++;
+}
+b = f & 5;
+if (b)
+  break;
+  } while (d++);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_135-pr120211.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_135-pr120211.c
new file mode 100644
index ..664b60de2aa6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_135-pr120211.c
@@ -0,0 +1,12 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-additional-options "-O3 -fno-tree-copy-prop -fno-tree-dominator-opts 
-fno-tree-loop-ivcanon -fno-tree-pre -fno-code-hoisting" } */
+
+int a, b[1];
+int main() {
+  int c = 0;
+  for (; c < 1; c++) {
+while (a)
+  c++;
+b[c] = 0;
+  }
+}
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 50d1abe3c7aa..978a4626b35b 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -424,6 +424,7 @@ vect_stmt_relevant_p (stmt_vec_info stmt_info, 
loop_vec_info loop_vinfo,
  alternate exit.  */
   if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
   && is_a  (stmt)
+  && gimple_bb (stmt) == LOOP_VINFO_LOOP (loop_vinfo)->header
   && ((! VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))
  && ! *live_p)
  || STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def))


[gcc r16-526] tree-optimization/120211 - constrain LOOP_VINFO_EARLY_BREAKS_LIVE_IVS more

2025-05-11 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:833db92d69cf371af3ade32e2a2b154c22e7ef15

commit r16-526-g833db92d69cf371af3ade32e2a2b154c22e7ef15
Author: Richard Biener 
Date:   Sun May 11 14:03:12 2025 +0200

tree-optimization/120211 - constrain LOOP_VINFO_EARLY_BREAKS_LIVE_IVS more

The PR120089 fix added more PHIs to LOOP_VINFO_EARLY_BREAKS_LIVE_IVS
but not checking that we only add PHIs with a latch argument.  The
following adds this missing check.

PR tree-optimization/120211
* tree-vect-stmts.cc (vect_stmt_relevant_p): Only add PHIs
from the loop header to LOOP_VINFO_EARLY_BREAKS_LIVE_IVS.

* gcc.dg/vect/vect-early-break_135-pr120211.c: New testcase.
* gcc.dg/torture/pr120211-1.c: Likewise.

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr120211-1.c| 20 
 .../gcc.dg/vect/vect-early-break_135-pr120211.c  | 12 
 gcc/tree-vect-stmts.cc   |  1 +
 3 files changed, 33 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/torture/pr120211-1.c 
b/gcc/testsuite/gcc.dg/torture/pr120211-1.c
new file mode 100644
index ..f9bc97cab5b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr120211-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+int a, b, d;
+void e() {
+  do {
+int f = 0;
+while (1) {
+  int c = a;
+  for (; (c & 1) == 0; c = 1)
+for (; c & 1;)
+  ;
+  if (a)
+break;
+  f++;
+}
+b = f & 5;
+if (b)
+  break;
+  } while (d++);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_135-pr120211.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_135-pr120211.c
new file mode 100644
index ..664b60de2aa6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_135-pr120211.c
@@ -0,0 +1,12 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-additional-options "-O3 -fno-tree-copy-prop -fno-tree-dominator-opts 
-fno-tree-loop-ivcanon -fno-tree-pre -fno-code-hoisting" } */
+
+int a, b[1];
+int main() {
+  int c = 0;
+  for (; c < 1; c++) {
+while (a)
+  c++;
+b[c] = 0;
+  }
+}
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index efe6a2c9c425..bd390b26e0a3 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -424,6 +424,7 @@ vect_stmt_relevant_p (stmt_vec_info stmt_info, 
loop_vec_info loop_vinfo,
  alternate exit.  */
   if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
   && is_a  (stmt)
+  && gimple_bb (stmt) == LOOP_VINFO_LOOP (loop_vinfo)->header
   && ((! VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))
  && ! *live_p)
  || STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def))


[gcc(refs/users/omachota/heads/rtl-ssa-dce)] rtl-ssa-dce: debugize insns

2025-05-11 Thread Ondrej Machota via Gcc-cvs
https://gcc.gnu.org/g:92e2b2fd496403a8d82b20b1fcefb265d1bf9e68

commit 92e2b2fd496403a8d82b20b1fcefb265d1bf9e68
Author: Ondřej Machota 
Date:   Sun May 11 19:08:12 2025 +0200

rtl-ssa-dce: debugize insns

Diff:
---
 gcc/dce.cc | 143 +
 1 file changed, 143 insertions(+)

diff --git a/gcc/dce.cc b/gcc/dce.cc
index f12269f5dc97..5b8648be5859 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -17,6 +17,8 @@ You should have received a copy of the GNU General Public 
License
 along with GCC; see the file COPYING3.  If not see
 .  */
 
+#include "bitmap.h"
+#include "sbitmap.h"
 #include 
 #include 
 #define INCLUDE_ALGORITHM
@@ -1896,6 +1898,147 @@ replace_dead_reg(rtx x, const_rtx old_rtx 
ATTRIBUTE_UNUSED, void *data)
  return NULL_RTX;
 }
 
+// visit every marked instruction in INSN dependency tree and unmark it
+static void
+unmark_debugizable(const insn_info& insn, auto_sbitmap &debugizable) 
+{
+  auto_vec worklist;
+  bitmap_set_bit (debugizable, insn.uid ());
+  worklist.safe_push (&insn);
+
+  while (!worklist.empty ()) {
+insn_info *current = worklist.pop ();
+int current_uid = current->uid ();
+
+// skip instruction that are not marked
+if (!bitmap_bit_p(debugizable, current_uid))
+  continue;
+
+bitmap_clear_bit(debugizable, current_uid);
+// add all marked dependencies to the worklist
+for (def_info *def : current.defs())
+{
+  if (def->kind() != access_kind::SET)
+continue;
+  
+  set_info *set = static_cast(def);
+  for (use_info *use : set->all_uses()) 
+  {
+insn_info *use_insn = use->insn();
+if (bitmap_bit_p(debugizable, use_insn->uid()))
+  worklist.safe_push (use_insn);
+  }
+}
+  }
+}
+
+static auto_sbitmap
+find_debugizable(const std::unordered_set &depends_on_dead_phi) 
+{
+  // only real instructions
+  auto_sbitmap debugizable(get_max_uid () + 1);
+  bitmap_clear(debugizable);
+
+  for (insn_info *insn : crtl->ssa->reverse_all_insns ()) {
+if (insn->is_artificial () || 
+  (m_marked.get_bit (insn->uid ()) && !insn->is_debug_insn()))
+  continue;
+
+// TODO: reset dead debug instructions - those that are dependend on a 
dead phi
+if (depends_on_dead_phi.count (insn) > 0) {
+  if (insn->is_debug_insn ())
+reset_dead_debug_insn (insn);
+  continue;
+}
+
+// this insn might have some debugizable dependencies and if we find that
+// current insn is not debugizable, we have to reset those dependencies
+gcc_checking_assert(insn->is_real ());
+
+rtx_insn *rtl = insn->rtl ();
+def_array defs = insn->defs ();
+rtx rtx_set;
+
+// If insn has debug uses and will be deleted, signalize it
+if (!MAY_HAVE_DEBUG_BIND_INSNS ||
+  (rtx_set = single_set (rtl)) == NULL_RTX ||
+  side_effects_p (SET_SRC (rtx_set)) ||
+  asm_noperands (PATTERN (rtl)) >= 0)
+  {
+unmark_debugizable(*insn, debugizable);
+continue; // TODO: call unmark_debugizable
+  }
+
+// some of the checks might be duplicate:
+if (insn->num_defs () != 1)
+{
+  if (insn->num_defs() > 1)
+unmark_debugizable(*insn, debugizable);
+  continue; // TODO: call unmark_debugizable if num_defs>1
+}
+
+def_info *def = *defs.begin ();
+if (def->kind () != access_kind::SET)
+  continue;
+
+set_info *set = static_cast (def);
+// this is a problem a bit
+// TODO: check instruction dependencies and their debugizability
+if (!set->has_nondebug_insn_uses ())
+  continue;
+
+bitmap_set_bit (debugizable, insn->uid ());
+  }
+
+  return debugizable;
+}
+
+static void 
+bruh(const auto_sbitmap& debugizable)
+{
+  for (insn_info *insn : crtl->ssa->reverse_all_insns ())
+  {
+if (insn->is_artificial () || !bitmap_bit_p(debugizable, insn->uid ()))
+  continue;
+
+rtx_insn *rtl = insn->rtl ();
+def_array defs = insn->defs ();
+rtx rtx_set = single_set (rtl);
+def_info *def = *defs.begin ();
+gcc_checking_assert (def->kind () != access_kind::SET);
+
+set_info *set = static_cast (def);
+
+// turn instruction into debug
+rtx dval = make_debug_expr_from_rtl (SET_DEST (rtx_set));
+
+/* Emit a debug bind insn before the insn in which
+reg dies.  */
+rtx bind_var_loc =
+  gen_rtx_VAR_LOCATION (GET_MODE (SET_DEST (rtx_set)),
+  DEBUG_EXPR_TREE_DECL (dval),
+  SET_SRC (rtx_set),
+  VAR_INIT_STATUS_INITIALIZED);
+
+obstack_watermark watermark = crtl->ssa->new_change_attempt();
+insn_info *debug_insn = crtl->ssa->create_insn(watermark, DEBUG_INSN, 
bind_var_loc);
+insn_change change(debug_insn);
+change.new_uses = insn->uses();
+change.move_range = insn_range_info(insn);
+
+rtx_insn *bind = emit_debug_insn_before (bind_var_loc, rtl);
+
+register_replacement replacement;
+for (use_info *u : set->all_uses ()) {
+  

[gcc(refs/users/omachota/heads/rtl-ssa-dce)] rtl-ssa-dce: debugize_insns

2025-05-11 Thread Ondrej Machota via Gcc-cvs
https://gcc.gnu.org/g:5a59807bef7e70e8216ce41c212b8ddb2d8caf22

commit 5a59807bef7e70e8216ce41c212b8ddb2d8caf22
Author: Ondřej Machota 
Date:   Sat May 10 15:38:28 2025 +0200

rtl-ssa-dce: debugize_insns

Diff:
---
 gcc/dce.cc | 82 --
 gcc/rtl-ssa/changes.cc |  7 +++--
 2 files changed, 84 insertions(+), 5 deletions(-)

diff --git a/gcc/dce.cc b/gcc/dce.cc
index fdf5a35d6765..f12269f5dc97 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -1876,6 +1876,26 @@ rtl_ssa_dce::debuggize_insn (insn_info *insn)
   
 }
 
+struct register_replacement {
+  unsigned int regno;
+  rtx expr;
+};
+
+static rtx
+replace_dead_reg(rtx x, const_rtx old_rtx ATTRIBUTE_UNUSED, void *data)
+{
+  auto replacement = static_cast(data);
+  
+ if (REG_P (x) && REGNO (x) >= FIRST_VIRTUAL_REGISTER && replacement->regno == 
REGNO (x))
+ {
+  if (GET_MODE (x) == GET_MODE (replacement->expr))
+ return replacement->expr;
+  return lowpart_subreg (GET_MODE (x), replacement->expr, GET_MODE 
(replacement->expr));
+ }
+
+ return NULL_RTX;
+}
+
 void
 rtl_ssa_dce::debugize_insns (const std::unordered_set 
&depends_on_dead_phi)
 {
@@ -1895,8 +1915,61 @@ rtl_ssa_dce::debugize_insns (const 
std::unordered_set &depends_on_d
 
 rtx_insn *rtl = insn->rtl ();
 def_array defs = insn->defs ();
-// def_info* s = nullptr;
-// s->kind() == access_kind::SET
+rtx rtx_set;
+
+// If insn has debug uses and will be deleted, signalize it
+if (!MAY_HAVE_DEBUG_BIND_INSNS ||
+  (rtx_set = single_set (rtl)) == NULL_RTX ||
+  side_effects_p (SET_SRC (rtx_set)) ||
+  asm_noperands (PATTERN (rtl)) >= 0)
+  continue;
+
+// some of the checks might be duplicate:
+if (insn->num_defs () != 1)
+  continue;
+
+def_info *def = *defs.begin ();
+if (def->kind () != access_kind::SET)
+  continue;
+
+set_info *set = static_cast (def);
+if (!set->has_nondebug_insn_uses ())
+  continue;
+
+rtx dval = make_debug_expr_from_rtl (SET_DEST (rtx_set));
+
+/* Emit a debug bind insn before the insn in which
+reg dies.  */
+rtx bind_var_loc =
+  gen_rtx_VAR_LOCATION (GET_MODE (SET_DEST (rtx_set)),
+  DEBUG_EXPR_TREE_DECL (dval),
+  SET_SRC (rtx_set),
+  VAR_INIT_STATUS_INITIALIZED);
+
+obstack_watermark watermark = crtl->ssa->new_change_attempt();
+insn_info *debug_insn = crtl->ssa->create_insn(watermark, DEBUG_INSN, 
bind_var_loc);
+insn_change change(debug_insn);
+change.new_uses = insn->uses();
+change.move_range = insn_range_info(insn);
+
+rtx_insn *bind = emit_debug_insn_before (bind_var_loc, rtl);
+
+register_replacement replacement;
+for (use_info *u : set->all_uses ()) {
+  // TODO: transform dependent insns
+  replacement.regno = u->regno();
+  replacement.expr = dval;
+
+  simplify_replace_fn_rtx(INSN_VAR_LOCATION_LOC(rtl), NULL_RTX, 
replace_dead_reg, &replacement);
+}
+
+// note:
+// 1. Walk over all insns from last to first. If an insntruction can be
+//debugized, update a bitmap. If the instruction is dead, walk over
+//its dependencies with worklist and reset the bitmap for visited 
+//instructions.
+// 2. Do the actual debugizing. 
+
 rtx set;
 // debugize_insns should be called only if MAY_HAVE_DEBUG_BIND_INSNS
 if (MAY_HAVE_DEBUG_BIND_INSNS
@@ -1933,7 +2006,7 @@ rtl_ssa_dce::debugize_insns (const 
std::unordered_set &depends_on_d
   insn_info *debug_insn = crtl->ssa->create_insn(watermark, DEBUG_INSN, 
rtx bind_var_loc);
   insn_change change(debug_insn);
   change.move_range = insn_range_info(insn)
-  // TODO: chains
+  // TODO: chains and defs
 
   def_info *d = *defs.begin ();
   if (d->kind() == access_kind::SET) {
@@ -1950,6 +2023,9 @@ rtl_ssa_dce::debugize_insns (const 
std::unordered_set &depends_on_d
  // replacements[REGNO (SET_DEST (set))] = dval;
 }   
   }
+
+  // TODO: check that all of the debug insn uses are live,
+  // othervise reset the instruction
 }
 
 static void
diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc
index b9861d24d380..4657aec47cd8 100644
--- a/gcc/rtl-ssa/changes.cc
+++ b/gcc/rtl-ssa/changes.cc
@@ -256,7 +256,7 @@ rtl_ssa::changes_are_worthwhile (array_slice changes,
 // SET has been deleted.  Clean up all remaining uses.  Such uses are
 // either dead phis or now-redundant live-out uses.
 void
-function_info::process_uses_of_deleted_def (set_info *set)
+function_info::process_uses_of_deleted_def (set_info *set, auto_sbitmap& 
visited_phis)
 {
   if (!set->has_any_uses ())
 return;
@@ -860,7 +860,10 @@ function_info::change_insns (array_slice 
changes)
{
  auto *set = dyn_cast (def);
  if (set && set->has_any_uses ())
-   process_uses_of_deleted_def (set);
+   {
+   auto_sbitmap phis(m_next_phi_uid);
+   proces

[gcc r16-530] testsuite: xtensa: add support for effective_target_sync_*

2025-05-11 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:aa0d25683bb5c7f2256d9e897fe471f0de84ea9b

commit r16-530-gaa0d25683bb5c7f2256d9e897fe471f0de84ea9b
Author: Max Filippov 
Date:   Sun Apr 27 18:05:20 2025 -0700

testsuite: xtensa: add support for effective_target_sync_*

Add new function check_effective_target_xtensa_atomic and use it in the
check_effective_target_sync_int_long and
check_effective_target_sync_char_short.

gcc/testsuite/ChangeLog:

* lib/target-supports.exp
(check_effective_target_xtensa_atomic): New function.
(check_effective_target_sync_int_long)
(check_effective_target_sync_char_short): Add test for xtensa.

Diff:
---
 gcc/testsuite/lib/target-supports.exp | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index 287e51bbfc66..24d0b3d08e34 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -10145,6 +10145,7 @@ proc check_effective_target_sync_int_long { } {
 || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
 || [check_effective_target_mips_llsc]
 || [istarget nvptx*-*-*]
+|| ([istarget xtensa*-*-*] && 
[check_effective_target_xtensa_atomic])
 }}]
 }
 
@@ -10182,7 +10183,9 @@ proc check_effective_target_sync_char_short { } {
 || ([istarget riscv*-*-*]
 && ([check_effective_target_riscv_zalrsc]
 || [check_effective_target_riscv_zabha]))
-|| [check_effective_target_mips_llsc] }}]
+|| [check_effective_target_mips_llsc]
+|| ([istarget xtensa*-*-*] && 
[check_effective_target_xtensa_atomic])
+}}]
 }
 
 # Return 1 if thread_fence does not rely on __sync_synchronize
@@ -14407,3 +14410,12 @@ proc 
check_effective_target_speculation_barrier_defined { } {
}
}]
 }
+
+# Return 1 if this is a compiler supporting Xtensa atomic operations
+proc check_effective_target_xtensa_atomic { } {
+return [check_no_compiler_messages xtensa_atomic assembly {
+   #if __XCHAL_HAVE_S32C1I != 1 && __XCHAL_HAVE_EXCLUSIVE != 1
+   #error FOO
+   #endif
+}]
+}


[gcc r16-533] Fix mips pr54240 testcase

2025-05-11 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:5e7c5c7e09a280d32c997623201a5139c696200b

commit r16-533-g5e7c5c7e09a280d32c997623201a5139c696200b
Author: Chao-ying Fu 
Date:   Fri Jan 31 17:13:50 2025 +

Fix mips pr54240 testcase

Like r9-5152-gd1409ea5a2f759 but for the mips testcase.

gcc/testsuite/
* gcc.target/mips/pr54240.c: Scan phiopt2.

Signed-off-by: Chao-ying Fu 
Signed-off-by: Aleksandar Rakic 

Diff:
---
 gcc/testsuite/gcc.target/mips/pr54240.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/mips/pr54240.c 
b/gcc/testsuite/gcc.target/mips/pr54240.c
index d3976f6cfef0..31b793bb8c64 100644
--- a/gcc/testsuite/gcc.target/mips/pr54240.c
+++ b/gcc/testsuite/gcc.target/mips/pr54240.c
@@ -27,4 +27,4 @@ NOMIPS16 int foo(S *s)
   return next->v;
 }
 
-/* { dg-final { scan-tree-dump "Hoisting adjacent loads" "phiopt1" } } */
+/* { dg-final { scan-tree-dump "Hoisting adjacent loads" "phiopt2" } } */