[gcc r16-377] [V2][RISC-V] Trivial permutation constant derivation

2025-05-04 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:8094ab80e5623d240f48a4b932c06c08b9e124f2

commit r16-377-g8094ab80e5623d240f48a4b932c06c08b9e124f2
Author: Jeff Law 
Date:   Sun May 4 16:59:51 2025 -0600

[V2][RISC-V] Trivial permutation constant derivation

This is a patch from late 2024 (just before stage1 freeze), but I never 
pushed
hard to the change, and thus never integrated it.

It's mostly unchanged except for updating insn in the hash table after 
finding
an optimizable case.  We were holding the deleted insn in the hash table 
rather
than the new insn.  Just something I noticed recently.

Bootstrapped and regression tested on my BPI and regression tested 
riscv32-elf
and riscv64-elf configurations.  We've used this since November internally, 
so
it's well exercised on spec as well.

gcc/
* config.gcc (riscv): Add riscv-vect-permcost.o to extra_objs.
* config/riscv/riscv-passes.def (pass_vector_permcost): Add new 
pass.
* config/riscv/riscv-protos.h (make_pass_vector_permconst): Declare.
* config/riscv/riscv-vect-permconst.cc: New file.
* config/riscv/t-riscv: Add build rule for riscv-vect-permcost.o

Diff:
---
 gcc/config.gcc   |   2 +-
 gcc/config/riscv/riscv-passes.def|   2 +
 gcc/config/riscv/riscv-protos.h  |   2 +
 gcc/config/riscv/riscv-vect-permconst.cc | 300 +++
 gcc/config/riscv/t-riscv |   7 +
 5 files changed, 312 insertions(+), 1 deletion(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 6dbe880c9d45..afbf82fd2b8f 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -551,7 +551,7 @@ pru-*-*)
 riscv*)
cpu_type=riscv
extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o 
riscv-shorten-memrefs.o riscv-selftests.o riscv-string.o"
-   extra_objs="${extra_objs} riscv-v.o riscv-vsetvl.o riscv-vector-costs.o 
riscv-avlprop.o"
+   extra_objs="${extra_objs} riscv-v.o riscv-vsetvl.o riscv-vector-costs.o 
riscv-avlprop.o riscv-vect-permconst.o"
extra_objs="${extra_objs} riscv-vector-builtins.o 
riscv-vector-builtins-shapes.o riscv-vector-builtins-bases.o 
sifive-vector-builtins-bases.o"
extra_objs="${extra_objs} thead.o riscv-target-attr.o riscv-zicfilp.o"
d_target_objs="riscv-d.o"
diff --git a/gcc/config/riscv/riscv-passes.def 
b/gcc/config/riscv/riscv-passes.def
index 7e6a2a0e53d7..bc803c4678ed 100644
--- a/gcc/config/riscv/riscv-passes.def
+++ b/gcc/config/riscv/riscv-passes.def
@@ -21,3 +21,5 @@ INSERT_PASS_AFTER (pass_rtl_store_motion, 1, 
pass_shorten_memrefs);
 INSERT_PASS_AFTER (pass_split_all_insns, 1, pass_avlprop);
 INSERT_PASS_BEFORE (pass_fast_rtl_dce, 1, pass_vsetvl);
 INSERT_PASS_BEFORE (pass_shorten_branches, 1, pass_insert_landing_pad);
+INSERT_PASS_AFTER (pass_cse2, 1, pass_vector_permconst);
+
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 2bedd878a04e..2e889903eb3a 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -201,6 +201,8 @@ rtl_opt_pass * make_pass_shorten_memrefs (gcc::context 
*ctxt);
 rtl_opt_pass * make_pass_avlprop (gcc::context *ctxt);
 rtl_opt_pass * make_pass_vsetvl (gcc::context *ctxt);
 rtl_opt_pass * make_pass_insert_landing_pad (gcc::context *ctxt);
+rtl_opt_pass * make_pass_vector_permconst (gcc::context *ctxt);
+
 
 /* Routines implemented in riscv-string.c.  */
 extern bool riscv_expand_block_compare (rtx, rtx, rtx, rtx);
diff --git a/gcc/config/riscv/riscv-vect-permconst.cc 
b/gcc/config/riscv/riscv-vect-permconst.cc
new file mode 100644
index ..feecc7ed6da0
--- /dev/null
+++ b/gcc/config/riscv/riscv-vect-permconst.cc
@@ -0,0 +1,300 @@
+/* Copyright (C) 2024 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or(at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#define IN_TARGET_CODE 1
+#define INCLUDE_ALGORITHM
+#define INCLUDE_FUNCTIONAL
+#define INCLUDE_MEMORY
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "backend.h"
+#include "rtl.h"
+#include "target.h"
+#include "tree-pass.h"
+#include "df.h"
+#include "rtl-ssa.h"
+#include "cfgcleanup.h"
+#include "insn-attr.h"
+#include "tm-constrs.h"
+#include "insn-opinit.h"
+#include "cfgrtl.h"
+
+/* So the basic idea of this pass is to identify loads of permutation
+   constants from the constant pool 

[gcc r16-375] [RISC-V] Adjust rvv tests after recent jump threading change

2025-05-04 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:c2962684e393007d8de59d37b8ac57b0b4843808

commit r16-375-gc2962684e393007d8de59d37b8ac57b0b4843808
Author: Jeff Law 
Date:   Sun May 4 11:05:44 2025 -0600

[RISC-V] Adjust rvv tests after recent jump threading change

Richi's jump threading patch is resulting in new jump threading 
opportunities
triggering in various vsetvl related tests.  When those new threading
opportunities are realized on vector code we usually end up with a different
number of vsetvls due to the inherent block copying.

At first I was adjusting cases to work with the new jump threads, then 
realized
we could easily end up back here if we change the threading heuristics and
such.  So I just made these tests disable jump threading.  I didn't do it
pervasively, just for those that have been affected.

gcc/testsuite

* gcc.target/riscv/rvv/vsetvl/avl_prop-2.c: Disable jump threading
and adjust number of expected vsetvls as needed.
* gcc.target/riscv/rvv/vsetvl/avl_single-56.c: Likewise.
* gcc.target/riscv/rvv/vsetvl/avl_single-67.c: Likewise.
* gcc.target/riscv/rvv/vsetvl/avl_single-68.c: Likewise.
* gcc.target/riscv/rvv/vsetvl/avl_single-71.c: Likewise.

Diff:
---
 gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-2.c| 4 ++--
 gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-56.c | 2 +-
 gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-67.c | 2 +-
 gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-68.c | 2 +-
 gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-71.c | 6 +++---
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-2.c 
b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-2.c
index 0379429a7548..edb12a126647 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_prop-2.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mrvv-vector-bits=scalable -march=rv64gc_zve32f -mabi=lp64d 
-O3 -mrvv-vector-bits=zvl" } */
+/* { dg-options "-mrvv-vector-bits=scalable -march=rv64gc_zve32f -mabi=lp64d 
-O3 -mrvv-vector-bits=zvl -fno-thread-jumps" } */
 
 int d0, sj, v0, rp, zi;
 
@@ -38,4 +38,4 @@ ka:
   goto ka;
 }
 
-/* { dg-final { scan-assembler-times {vsetivli\tzero,\s*1} 2 } } */
+/* { dg-final { scan-assembler-times {vsetivli\tzero,\s*1} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-56.c 
b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-56.c
index 5db1a402be60..3d3c5d6e9fbc 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-56.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-56.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 
-fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 
-fno-schedule-insns -fno-schedule-insns2 -fno-thread-jumps" } */
 
 #include "riscv_vector.h"
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-67.c 
b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-67.c
index 3f22fc870d93..013d32c55a89 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-67.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-67.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 
-fno-tree-vectorize -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 
-fno-tree-vectorize -fno-schedule-insns -fno-schedule-insns2 -fno-thread-jumps" 
} */
 
 #include "riscv_vector.h"
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-68.c 
b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-68.c
index 64666d31f1ac..aef832546c78 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-68.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-68.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 
-fno-tree-vectorize -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 
-fno-tree-vectorize -fno-schedule-insns -fno-schedule-insns2 -fno-thread-jumps" 
} */
 
 #include "riscv_vector.h"
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-71.c 
b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-71.c
index 07a64b43a532..fa4328f97f32 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-71.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-71.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 
-fno-tree-vectorize -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 
-fno-tree

[gcc r16-374] [PATCH] RISC-V: Implment H modifier for printing the next register name

2025-05-04 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:89e58171bae30eacf5e8a281eb4758b2712aeed2

commit r16-374-g89e58171bae30eacf5e8a281eb4758b2712aeed2
Author: Jin Ma 
Date:   Sun May 4 08:44:27 2025 -0600

[PATCH] RISC-V: Implment H modifier for printing the next register name

For RV32 inline assembly, when handling 64-bit integer data, it is
often necessary to process the lower and upper 32 bits separately.
Unfortunately, we can only output the current register name
(lower 32 bits) but not the next register name (upper 32 bits).

To address this, the modifier 'H' has been added to allow users
to handle the upper 32 bits of the data. While I believe the
modifier 'N' (representing the next register name) might be more
suitable for this functionality, 'N' is already in use.
Therefore, 'H' (representing the high register) was chosen instead.

Co-Authored-By: Dimitar Dimitrov 

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_print_operand): Add H.
* doc/extend.texi: Document for H.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/modifier-H-error-1.c: New test.
* gcc.target/riscv/modifier-H-error-2.c: New test.
* gcc.target/riscv/modifier-H.c: New test.

Diff:
---
 gcc/config/riscv/riscv.cc  | 22 ++
 gcc/doc/extend.texi|  1 +
 .../gcc.target/riscv/modifier-H-error-1.c  | 13 +
 .../gcc.target/riscv/modifier-H-error-2.c  | 11 +++
 gcc/testsuite/gcc.target/riscv/modifier-H.c| 22 ++
 5 files changed, 69 insertions(+)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 064c12c49f3a..a0657323f65f 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -6879,6 +6879,7 @@ riscv_asm_output_opcode (FILE *asm_out_file, const char 
*p)
'T' Print shift-index of inverted single-bit mask OP.
'~' Print w if TARGET_64BIT is true; otherwise not print anything.
'N'  Print register encoding as integer (0-31).
+   'H'  Print the name of the next register for integer.
 
Note please keep this list and the list in riscv.md in sync.  */
 
@@ -7174,6 +7175,27 @@ riscv_print_operand (FILE *file, rtx op, int letter)
asm_fprintf (file, "%u", (regno - offset));
break;
   }
+case 'H':
+  {
+   if (!REG_P (op))
+ {
+   output_operand_lossage ("modifier 'H' require register operand");
+   break;
+ }
+   if (REGNO (op) > 31)
+ {
+   output_operand_lossage ("modifier 'H' is for integer registers 
only");
+   break;
+ }
+   if (REGNO (op) == 31)
+ {
+   output_operand_lossage ("modifier 'H' cannot be applied to R31");
+   break;
+ }
+
+   fputs (reg_names[REGNO (op) + 1], file);
+   break;
+  }
 default:
   switch (code)
{
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 0978c4c41b25..212d24875584 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -12585,6 +12585,7 @@ The list below describes the supported modifiers and 
their effects for RISC-V.
 @item @code{z} @tab Print ''@code{zero}'' instead of 0 if the operand is an 
immediate with a value of zero.
 @item @code{i} @tab Print the character ''@code{i}'' if the operand is an 
immediate.
 @item @code{N} @tab Print the register encoding as integer (0 - 31).
+@item @code{H} @tab Print the name of the next register for integer.
 @end multitable
 
 @anchor{shOperandmodifiers}
diff --git a/gcc/testsuite/gcc.target/riscv/modifier-H-error-1.c 
b/gcc/testsuite/gcc.target/riscv/modifier-H-error-1.c
new file mode 100644
index ..43ecff6498e5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/modifier-H-error-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -O0" } */
+
+float foo ()
+{
+  float ret;
+  asm ("fld\t%H0,(a0)\n\t":"=f"(ret));
+
+  return ret;
+}
+
+/* { dg-error "modifier 'H' is for integer registers only" "" { target { 
"riscv*-*-*" } } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/modifier-H-error-2.c 
b/gcc/testsuite/gcc.target/riscv/modifier-H-error-2.c
new file mode 100644
index ..db478b6ddf61
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/modifier-H-error-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -O0 " } */
+
+void foo ()
+{
+  register int x31 __asm__ ("x31");
+  asm ("li\t%H0,1\n\t":"=r"(x31));
+}
+
+/* { dg-error "modifier 'H' cannot be applied to R31" "" { target { 
"riscv*-*-*" } } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/modifier-H.c 
b/gcc/testsuite/gcc.target/riscv/modifier-H.c
new file mode 100644
index ..357

[gcc r16-373] [to-be-committed][RISC-V] Adjust testcases and finish register move costing fix

2025-05-04 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:005424e3337a3234f95755e57ee41c061b6e4185

commit r16-373-g005424e3337a3234f95755e57ee41c061b6e4185
Author: Jeff Law 
Date:   Sun May 4 08:28:56 2025 -0600

[to-be-committed][RISC-V] Adjust testcases and finish register move costing 
fix

The recent adjustment to more correctly cost register moves tripped a few
testsuite regressions.

I'm pretty torn on the thead test adjustments.  But in reality they only 
worked
because the register move costing was broken.  So I've reverted the scan-asm
part of those to a prior state for two of those tests.  The other was only
failing at -Og/-Oz which was added to the exclude list.

The other Zfa test is similar, but we can make the test behave with a 
suitable
-mtune option and thus preserve the test.

While investigating I also noted that vector moves aren't being handled
correctly for subclasses of the integer/fp register files.  So I fixed those
while I was in there.

Note this may have an impact on some of your work Pan.  I haven't followed 
the
changes from the last week or so due to illness.

Waiting on pre-commit's verdict, though it did spin through my tester
successfully, though not all of the regressions related to that change are
addressed (there's still one for rv32 I'll look at shortly).

gcc/
* config/riscv/riscv.cc (riscv_register_move_cost): Handle
subclasses with vector registers as well.

gcc/testsuite/

* gcc.target/riscv/xtheadfmemidx-xtheadfmv-medany.c: Adjust expected
output.
* gcc.target/riscv/xtheadfmemidx-zfa-medany.c: Likewise.
* gcc.target/riscv/xtheadfmv-fmv.c: Skip for -Os and -Oz.
* gcc.target/riscv/zfa-fmovh-fmovp.c: Use sifive-p400 tuning.

Diff:
---
 gcc/config/riscv/riscv.cc   | 8 
 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-xtheadfmv-medany.c | 4 +---
 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-zfa-medany.c   | 4 +---
 gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c  | 2 +-
 gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp.c| 2 +-
 5 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 10e0f4adbdcf..064c12c49f3a 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -9659,17 +9659,17 @@ riscv_register_move_cost (machine_mode mode,
 
   if (from == V_REGS)
 {
-  if (to == GR_REGS)
+  if (to_is_gpr)
return get_vector_costs ()->regmove->VR2GR;
-  else if (to == FP_REGS)
+  else if (to_is_fpr)
return get_vector_costs ()->regmove->VR2FR;
 }
 
   if (to == V_REGS)
 {
-  if (from == GR_REGS)
+  if (from_is_gpr)
return get_vector_costs ()->regmove->GR2VR;
-  else if (from == FP_REGS)
+  else if (from_is_fpr)
return get_vector_costs ()->regmove->FR2VR;
 }
 
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-xtheadfmv-medany.c 
b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-xtheadfmv-medany.c
index 6746c3140578..38966fefad5d 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-xtheadfmv-medany.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-xtheadfmv-medany.c
@@ -35,6 +35,4 @@ double foo (int i, int j)
   return z;
 }
 
-/* { dg-final { scan-assembler-not {\mth\.flrd\M} } } */
-/* { dg-final { scan-assembler-times {\mlw\M} 2 } } */
-/* { dg-final { scan-assembler-times {\mth\.fmv\.hw\.x\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mth\.flrd\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-zfa-medany.c 
b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-zfa-medany.c
index fb1ac2b735c3..f0d9c80d16f2 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-zfa-medany.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-zfa-medany.c
@@ -35,6 +35,4 @@ double foo (int i, int j)
   return z;
 }
 
-/* { dg-final { scan-assembler-not {\mth\.flrd\M} } } */
-/* { dg-final { scan-assembler-times {\mlw\M} 2 } } */
-/* { dg-final { scan-assembler-times {\mfmvp\.d\.x\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mth\.flrd\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c 
b/gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c
index 9b4e23784480..81b240eac577 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmv-fmv.c
@@ -1,6 +1,6 @@
 /* { dg-do compile { target { rv32 } } } */
 /* { dg-options "-march=rv32gc_xtheadfmv -mabi=ilp32d" } */
-/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Oz"} } */
 
 double
 ll2d (long long ll)
diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp.c 
b/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp.c
index 5a52adce36ac..150cfd7fc058 100644
--- a/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp.c
+++ b/gcc/testsu

[gcc r16-376] Fortran: array subreferences and components of derived types [PR119986]

2025-05-04 Thread Harald Anlauf via Gcc-cvs
https://gcc.gnu.org/g:fceb6022798b587c9111d0241aaff72602dcd626

commit r16-376-gfceb6022798b587c9111d0241aaff72602dcd626
Author: Harald Anlauf 
Date:   Sat May 3 20:35:57 2025 +0200

Fortran: array subreferences and components of derived types [PR119986]

PR fortran/119986

gcc/fortran/ChangeLog:

* expr.cc (is_subref_array): When searching for array references,
do not terminate early so that inquiry references to complex
components work.
* primary.cc (gfc_variable_attr): A substring reference can refer
to either a scalar or array character variable.  Adjust search
accordingly.

gcc/testsuite/ChangeLog:

* gfortran.dg/actual_array_subref.f90: New test.

Diff:
---
 gcc/fortran/expr.cc   |   1 +
 gcc/fortran/primary.cc|  13 ++-
 gcc/testsuite/gfortran.dg/actual_array_subref.f90 | 103 ++
 3 files changed, 113 insertions(+), 4 deletions(-)

diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index 07e9bac37a1c..92a9ebdcbe8e 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -1194,6 +1194,7 @@ is_subref_array (gfc_expr * e)
 what follows cannot be a subreference array, unless there is a
 substring reference.  */
   if (!seen_array && ref->type == REF_COMPONENT
+ && ref->next == NULL
  && ref->u.c.component->ts.type != BT_CHARACTER
  && ref->u.c.component->ts.type != BT_CLASS
  && !gfc_bt_struct (ref->u.c.component->ts.type))
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 161d4c269648..72ecc7ccf934 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -2893,6 +2893,7 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
   gfc_symbol *sym;
   gfc_component *comp;
   bool has_inquiry_part;
+  bool has_substring_ref = false;
 
   if (expr->expr_type != EXPR_VARIABLE
   && expr->expr_type != EXPR_FUNCTION
@@ -2955,7 +2956,12 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
 
   has_inquiry_part = false;
   for (ref = expr->ref; ref; ref = ref->next)
-if (ref->type == REF_INQUIRY)
+if (ref->type == REF_SUBSTRING)
+  {
+   has_substring_ref = true;
+   optional = false;
+  }
+else if (ref->type == REF_INQUIRY)
   {
has_inquiry_part = true;
optional = false;
@@ -3003,9 +3009,8 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
*ts = comp->ts;
/* Don't set the string length if a substring reference
   follows.  */
-   if (ts->type == BT_CHARACTER
-   && ref->next && ref->next->type == REF_SUBSTRING)
-   ts->u.cl = NULL;
+   if (ts->type == BT_CHARACTER && has_substring_ref)
+ ts->u.cl = NULL;
  }
 
if (comp->ts.type == BT_CLASS)
diff --git a/gcc/testsuite/gfortran.dg/actual_array_subref.f90 
b/gcc/testsuite/gfortran.dg/actual_array_subref.f90
new file mode 100644
index ..932d7aba1214
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/actual_array_subref.f90
@@ -0,0 +1,103 @@
+! { dg-do run }
+! { dg-additional-options "-O2 -fcheck=bounds" }
+!
+! PR fortran/119986
+!
+! Check passing of inquiry references of complex arrays and substring
+! references of character arrays when these are components of derived types.
+!
+! Extended version of report by Neil Carlson.
+
+program main
+  implicit none
+  integer :: j
+
+  complex, parameter  :: z0(*) = [(cmplx(j,-j),j=1,4)]
+  type :: cx
+ real :: re
+ real :: im
+  end type cx
+  type(cx), parameter :: c0(*) = [(cx   (j,-j),j=1,4)]
+
+  type :: my_type
+ complex  :: z(4) = z0
+ type(cx) :: c(4) = c0
+  end type my_type
+  type(my_type) :: x
+
+  character(*), parameter :: s0(*) = ["abcd","efgh","ijkl","mnop"]
+  character(*), parameter :: expect(*) = s0(:)(2:3)
+  character(len(s0))  :: s1(4) = s0
+
+  type :: str1
+ character(len(s0))   :: s(4)  = s0
+  end type str1
+  type(str1) :: string1
+
+  type :: str2
+ character(:), allocatable :: s(:)
+  end type str2
+  type(str2) :: string2
+
+  integer :: stopcode = 0
+
+  if (len(expect) /= 2)stop 1
+  if (expect(4)   /= "no") stop 2
+  if (any(c0 %re  /= [ 1, 2, 3, 4])) stop 3
+  if (any(c0 %im  /= [-1,-2,-3,-4])) stop 4
+
+  stopcode = 10
+  call fubar ( x%z %re, x%z %im)
+  call fubar ( x%c %re, x%c %im)
+
+  stopcode = 20
+  call fubar ((x%z %re), (x%z %im))
+  call fubar ((x%c %re), (x%c %im))
+
+  stopcode = 30
+  call fubar ([x%z %re], [x%z %im])
+  call fubar ([x%c %re], [x%c %im])
+
+  stopcode = 50
+  call chk ( s0(:)(2:3) )
+  call chk ((s0(:)(2:3)))
+  call chk ([s0(:)(2:3)])
+
+  stopcode = 60
+  call chk ( s1(:)(2:3) )
+  call chk ((s1(:)(2:3)))
+  call chk ([s1(:)(2:3)])
+
+  stopcode = 70
+  call chk ( string1%s(:)(2:3) )
+  call chk ((string1%s(:)(2:3)))
+  call chk ([string1%s(:)(2:3)])
+
+  string2% s = s

[gcc r16-380] RISC-V: Apply clang-format to genrvv-type-indexer.cc [NFC]

2025-05-04 Thread Kito Cheng via Gcc-cvs
https://gcc.gnu.org/g:d3651f07bbf56837f019e366b75d01f197dab2f1

commit r16-380-gd3651f07bbf56837f019e366b75d01f197dab2f1
Author: Kito Cheng 
Date:   Mon May 5 10:16:14 2025 +0800

RISC-V: Apply clang-format to genrvv-type-indexer.cc [NFC]

Tweak the formatting of the genrvv-type-indexer.cc file to conform to
the style used by clang-format. This is a no-functional-change commit
that only modifies the formatting of the code.

gcc/Changelog:

* config/riscv/genrvv-type-indexer.cc: Apply clang-format to the
file.

Diff:
---
 gcc/config/riscv/genrvv-type-indexer.cc | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/gcc/config/riscv/genrvv-type-indexer.cc 
b/gcc/config/riscv/genrvv-type-indexer.cc
index 2fd429ad7348..f296089fbfe7 100644
--- a/gcc/config/riscv/genrvv-type-indexer.cc
+++ b/gcc/config/riscv/genrvv-type-indexer.cc
@@ -23,8 +23,14 @@ along with GCC; see the file COPYING3.  If not see
 #include 
 #include 
 
-#define BOOL_SIZE_LIST {1, 2, 4, 8, 16, 32, 64}
-#define EEW_SIZE_LIST {8, 16, 32, 64}
+#define BOOL_SIZE_LIST 
\
+  {
\
+1, 2, 4, 8, 16, 32, 64 
\
+  }
+#define EEW_SIZE_LIST  
\
+  {
\
+8, 16, 32, 64  
\
+  }
 #define LMUL1_LOG2 0
 
 std::string
@@ -167,7 +173,7 @@ floattype (unsigned sew, int lmul_log2)
 std::string
 expand_floattype (unsigned sew, int lmul_log2, unsigned nf)
 {
-  if (sew != 8 || nf!= 1
+  if (sew != 8 || nf != 1
   || (!valid_type (sew * 4, lmul_log2 + 2, /*float_t*/ true)))
 return "INVALID";
 
@@ -297,13 +303,13 @@ main (int argc, const char **argv)
 
   for (unsigned eew : EEW_SIZE_LIST)
fprintf (fp, "  /*SIGNED_EEW%d_LMUL1_INTERPRET*/ %s,\n", eew,
-inttype (eew, LMUL1_LOG2, /* unsigned_p */false).c_str ());
+inttype (eew, LMUL1_LOG2, /* unsigned_p */ false).c_str ());
 
   for (unsigned eew : EEW_SIZE_LIST)
fprintf (fp, "  /*UNSIGNED_EEW%d_LMUL1_INTERPRET*/ %s,\n", eew,
-inttype (eew, LMUL1_LOG2, /* unsigned_p */true).c_str ());
+inttype (eew, LMUL1_LOG2, /* unsigned_p */ true).c_str ());
 
-   fprintf (fp, "  /*X2*/ INVALID,\n");
+  fprintf (fp, "  /*X2*/ INVALID,\n");
 
   for (unsigned lmul_log2_offset : {1, 2, 3, 4, 5, 6})
{
@@ -428,8 +434,9 @@ main (int argc, const char **argv)
  fprintf (fp, "  /*UNSIGNED_EEW%d_LMUL1_INTERPRET*/ INVALID,\n",
   eew);
 
-   fprintf (fp, "  /*X2*/ %s,\n",
-inttype (sew * 2, lmul_log2 + 1, /*unsigned_p*/ 
true).c_str ());
+   fprintf (
+ fp, "  /*X2*/ %s,\n",
+ inttype (sew * 2, lmul_log2 + 1, /*unsigned_p*/ true).c_str ());
 
for (unsigned lmul_log2_offset : {1, 2, 3, 4, 5, 6})
  {


[gcc r16-372] Improve maybe_hot handling in inliner heuristics

2025-05-04 Thread Jan Hubicka via Gcc-cvs
https://gcc.gnu.org/g:064cac730f88dc71c6da578f9ae5b8e092ab6cd4

commit r16-372-g064cac730f88dc71c6da578f9ae5b8e092ab6cd4
Author: Jan Hubicka 
Date:   Sun May 4 10:52:35 2025 +0200

Improve maybe_hot handling in inliner heuristics

Inliner currently applies different heuristics to hot and cold calls (the
second are inlined only if the code size will shrink).  It may happen that 
the
call itself is hot, but the significant time is spent in callee and inlining
makes it faster.  For this reason we want to check if the anticipated 
speedup
is considered hot which is done by this patch (that is similar ot my earlier
ipa-cp change).

In general I think this is less important compared to ipa-cp change, since 
large
benefit from inlining happens only when something useful is propagated into 
the
callee and should be handled earlier by ipa-cp. However the patch improves
SPEC2k17 imagick runtime by about 9% as discussed in PR 11900 though it is
mostly problem of bad train data set which does not train well parts of 
program
that are hot for ref data set.  As discussed in the PR log, the particular 
call
that needs to be inlined has count that falls very slightly bellow the 
cutoff
and scaling it up by expected savings enables inlining.

gcc/ChangeLog:

PR target/119900
* cgraph.cc (cgraph_edge::maybe_hot_p): Add
a variant accepting a sreal scale; use reliability of
profile.
* cgraph.h (cgraph_edge::maybe_hot_p): Declare
a varaint accepting a sreal scale.
* ipa-inline.cc (callee_speedup): New function.
(want_inline_small_function_p): add early return
and avoid duplicated lookup of summaries; use scaled
maybe_hot predicate.

Diff:
---
 gcc/cgraph.cc | 42 ++
 gcc/cgraph.h  |  9 +++--
 gcc/ipa-inline.cc | 41 -
 3 files changed, 73 insertions(+), 19 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 6ae6a97f6f56..1a2ec38374ab 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -2984,13 +2984,22 @@ cgraph_edge::cannot_lead_to_return_p (void)
 return callee->cannot_return_p ();
 }
 
-/* Return true if the edge may be considered hot.  */
+/* Return true if the edge after scaling it profile by SCALE
+   may be considered hot.  */
 
 bool
-cgraph_edge::maybe_hot_p (void)
+cgraph_edge::maybe_hot_p (sreal scale)
 {
-  if (!maybe_hot_count_p (NULL, count.ipa ()))
+  /* Never consider calls in functions optimized for size hot.  */
+  if (opt_for_fn (caller->decl, optimize_size))
 return false;
+
+  /* If reliable IPA count is available, just use it.  */
+  profile_count c = count.ipa ();
+  if (c.reliable_p ())
+return maybe_hot_count_p (NULL, c * scale);
+
+  /* See if we can determine hotness using caller frequency.  */
   if (caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
   || (callee
  && callee->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED))
@@ -2999,25 +3008,42 @@ cgraph_edge::maybe_hot_p (void)
   && (callee
  && callee->frequency <= NODE_FREQUENCY_EXECUTED_ONCE))
 return false;
-  if (opt_for_fn (caller->decl, optimize_size))
-return false;
+  /* ??? This may make sense for hot functions determined by
+ user attribute, but if function is hot by profile, it may
+ contains non-hot calls.  In most practical cases this case
+ is handled by the reliable ipa count above, but i.e. after
+ inlining function with no profile to function with profile
+ we get here.. */
   if (caller->frequency == NODE_FREQUENCY_HOT)
 return true;
+
+  /* Use IPA count and if it s not available appy local heuristics.  */
+  if (c.initialized_p ())
+return maybe_hot_count_p (NULL, c * scale);
   if (!count.initialized_p ())
 return true;
   cgraph_node *where = caller->inlined_to ? caller->inlined_to : caller;
   if (!where->count.initialized_p ())
-return false;
+return true;
+  c = count * scale;
   if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE)
 {
-  if (count * 2 < where->count * 3)
+  if (c * 2 < where->count * 3)
return false;
 }
-  else if (count * param_hot_bb_frequency_fraction < where->count)
+  else if (c * param_hot_bb_frequency_fraction < where->count)
 return false;
   return true;
 }
 
+/* Return true if the edge may be considered hot.  */
+
+bool
+cgraph_edge::maybe_hot_p ()
+{
+  return maybe_hot_p (1);
+}
+
 /* Worker for cgraph_can_remove_if_no_direct_calls_p.  */
 
 static bool
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index abde770ba2b3..f7b67ed0a6c5 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1872,8 +1872,13 @@ public:
   /* Return true when the edge represents a direct recursion.  */
   bool recursive_p (void);
 
-  /* Return true if the edge may be considered hot.  */
-  bool maybe_hot_p (void);
+  /*