[gcc r16-3658] RISC-V: Add pattern for vector-scalar single-width floating-point sub

2025-09-08 Thread Paul-Antoine Arras via Gcc-cvs
https://gcc.gnu.org/g:1f01c51abff55301149f1057aaf0e7d7784bd6cc

commit r16-3658-g1f01c51abff55301149f1057aaf0e7d7784bd6cc
Author: Paul-Antoine Arras 
Date:   Fri Sep 5 13:03:40 2025 +0200

RISC-V: Add pattern for vector-scalar single-width floating-point sub

This pattern enables the combine pass (or late-combine, depending on the 
case)
to merge a vec_duplicate into a minus RTL instruction. The vec_duplicate is 
the
subtrahend operand.

Before this patch, we have two instructions, e.g.:
  vfmv.v.f   v2,fa0
  vfsub.vv   v1,v1,v2

After, we get only one:
  vfsub.vf   v1,v1,fa0

gcc/ChangeLog:

* config/riscv/autovec-opt.md (*vfsub_vf_): New pattern to
combine vec_duplicate + vfsub.vv into vfsub.vf.
* config/riscv/vector.md (@pred__scalar): Allow VLS 
modes.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/vls/floating-point-sub-2.c: Adjust 
scan
dumps.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c: Add vfsub.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_binop_data.h: Add data for
vfsub.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfsub-run-1-f16.c: New test.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfsub-run-1-f32.c: New test.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfsub-run-1-f64.c: New test.

Diff:
---
 gcc/config/riscv/autovec-opt.md|  19 +++
 gcc/config/riscv/vector.md |  12 +-
 .../riscv/rvv/autovec/vls/floating-point-sub-2.c   |   2 +-
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c  |   1 +
 .../riscv/rvv/autovec/vx_vf/vf_binop_data.h| 146 +
 .../riscv/rvv/autovec/vx_vf/vf_vfsub-run-1-f16.c   |  19 +++
 .../riscv/rvv/autovec/vx_vf/vf_vfsub-run-1-f32.c   |  15 +++
 .../riscv/rvv/autovec/vx_vf/vf_vfsub-run-1-f64.c   |  15 +++
 19 files changed, 239 insertions(+), 7 deletions(-)

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index f51b8ba80523..f4d13ca35684 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -2188,3 +2188,22 @@
   }
   [(set_attr "type" "vfalu")]
 )
+
+;; vfsub.vf
+(define_insn_and_split "*vfsub_vf_"
+  [(set (match_operand:V_VLSF 0 "register_operand")
+(minus:V_VLSF
+  (match_operand:V_VLSF 1 "register_operand")
+  (vec_duplicate:V_VLSF
+(match_operand: 2 "register_operand"]
+  "TARGET_VECTOR && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
+  {
+riscv_vector::emit_vlmax_insn (code_for_pred_scalar (MINUS, mode),
+  riscv_vector::BINARY_OP_FRM_DYN, operands);
+DONE;
+  }
+  [(set_attr "type" "vfalu")]
+)
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index d62f8bb2cd2e..c6c37dff9945 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -6441,8 +6441,8 @@
(set_attr "mode" "")])
 
 (define_insn "@pred__scalar"
-  [(set (match_operand:VF 0 "register_operand"   "=vd, vd, vr, vr")
-   (if_then_else:VF
+  [(set (match_operand:V_VLSF 0 "register_operand"   "=vd, vd, vr, vr")
+   (if_then_else:V_VLSF
  (unspec:
[(match_operand: 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
 (match_operand 5 "vector_length_operand""rvl,rvl,rvl,rvl")
@@ -6453,11 +6453,11 @@
 (reg:SI VL_REGNUM)
 (reg:SI VTYPE_REGNUM)
 (reg:SI FRM_REG

[gcc r16-3657] RISC-V: Add pattern for vector-scalar single-width floating-point add

2025-09-08 Thread Paul-Antoine Arras via Gcc-cvs
https://gcc.gnu.org/g:ff6d07960c5a2553199308c0943ea0b76baba0a3

commit r16-3657-gff6d07960c5a2553199308c0943ea0b76baba0a3
Author: Paul-Antoine Arras 
Date:   Thu Sep 4 12:46:28 2025 +0200

RISC-V: Add pattern for vector-scalar single-width floating-point add

This pattern enables the combine pass (or late-combine, depending on the 
case)
to merge a vec_duplicate into a plus RTL instruction.

Before this patch, we have two instructions, e.g.:
  vfmv.v.f   v2,fa0
  vfadd.vv   v1,v1,v2

After, we get only one:
  vfadd.vf   v1,v1,fa0

gcc/ChangeLog:

* config/riscv/autovec-opt.md (*vfadd_vf_): New pattern to
combine vec_duplicate + vfadd.vv into vfadd.vf.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/vls/floating-point-add-2.c: Adjust 
scan
dump.
* gcc.target/riscv/rvv/autovec/vls/floating-point-add-3.c: Likewise.
* gcc.target/riscv/rvv/autovec/vls/floating-point-sub-3.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c: Add vfadd.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_binop_data.h: Add data for
vfadd.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfadd-run-1-f16.c: New test.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfadd-run-1-f32.c: New test.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfadd-run-1-f64.c: New test.

Diff:
---
 gcc/config/riscv/autovec-opt.md|  19 +++
 .../riscv/rvv/autovec/vls/floating-point-add-2.c   |   2 +-
 .../riscv/rvv/autovec/vls/floating-point-add-3.c   |   2 +-
 .../riscv/rvv/autovec/vls/floating-point-sub-3.c   |   2 +-
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c  |   1 +
 .../riscv/rvv/autovec/vx_vf/vf_binop_data.h| 147 +
 .../riscv/rvv/autovec/vx_vf/vf_vfadd-run-1-f16.c   |  19 +++
 .../riscv/rvv/autovec/vx_vf/vf_vfadd-run-1-f32.c   |  15 +++
 .../riscv/rvv/autovec/vx_vf/vf_vfadd-run-1-f64.c   |  15 +++
 20 files changed, 236 insertions(+), 3 deletions(-)

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index 82a5fa0fae90..f51b8ba80523 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -2169,3 +2169,22 @@
   }
   [(set_attr "type" "vfwmul")]
 )
+
+;; vfadd.vf
+(define_insn_and_split "*vfadd_vf_"
+  [(set (match_operand:V_VLSF 0 "register_operand")
+(plus:V_VLSF
+  (vec_duplicate:V_VLSF
+(match_operand: 2 "register_operand"))
+  (match_operand:V_VLSF 1 "register_operand")))]
+  "TARGET_VECTOR && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
+  {
+riscv_vector::emit_vlmax_insn (code_for_pred_scalar (PLUS, mode),
+  riscv_vector::BINARY_OP_FRM_DYN, operands);
+DONE;
+  }
+  [(set_attr "type" "vfalu")]
+)
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-add-2.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-add-2.c
index 042dd0d5ccc6..00b9222e7657 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-add-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-add-2.c
@@ -39,5 +39,5 @@ DEF_OP_VX (add, 128, double, +)
 DEF_OP_VX (add, 256, double, +)
 DEF_OP_VX (add, 512, double, +)
 
-/* { dg-final { scan-assembler-times 
{vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 30 } } */
+/* { dg-final { scan-assembler-times 
{vfadd\.vf\s+v[0-9]+,\s*v[0-9]+,\s*f[ast]?[0-9]+} 30 } } 

[gcc r16-3656] RISC-V: Add pattern for vector-scalar widening floating-point multiply

2025-09-08 Thread Paul-Antoine Arras via Gcc-cvs
https://gcc.gnu.org/g:4488152579989e8921e3b56e221fb96c1a6fdcd5

commit r16-3656-g4488152579989e8921e3b56e221fb96c1a6fdcd5
Author: Paul-Antoine Arras 
Date:   Wed Sep 3 14:29:13 2025 +0200

RISC-V: Add pattern for vector-scalar widening floating-point multiply

This pattern enables the combine pass (or late-combine, depending on the 
case)
to merge a float_extend'ed vec_duplicate into a mult RTL instruction.

Before this patch, we have six instructions, e.g.:
  fcvt.d.sfa0,fa0
  vsetvli a5,zero,e64,m1,ta,ma
  vfmv.v.fv3,fa0
  vfwcvt.f.f.vv1,v2
  vsetvli zero,zero,e64,m1,ta,ma
  vfmul.vvv1,v3,v1

After, we get only one:
  vfwmul.vf   v1,v2,fa0

gcc/ChangeLog:

* config/riscv/autovec-opt.md (*vfwmul_vf_): New pattern to
combine float_extend + vec_duplicate + vfmul.vv into vfmul.vf.
* config/riscv/vector.md (*@pred_dual_widen__scalar):
Swap operands to match the RTL emitted by expand, i.e. first
float_extend then vec_duplicate.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c: Add vfwmul.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h: Add support for
widening variants.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_binop_widen_run.h: New test
helper.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmul-run-1-f16.c: New 
test.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwmul-run-1-f32.c: New 
test.

Diff:
---
 gcc/config/riscv/autovec-opt.md| 23 +++
 gcc/config/riscv/vector.md |  4 +--
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c  |  3 +-
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c  |  3 +-
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c  |  1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c  |  1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h  | 34 --
 .../riscv/rvv/autovec/vx_vf/vf_binop_widen_run.h   | 32 
 .../riscv/rvv/autovec/vx_vf/vf_vfwmul-run-1-f16.c  | 20 +
 .../riscv/rvv/autovec/vx_vf/vf_vfwmul-run-1-f32.c  | 16 ++
 14 files changed, 139 insertions(+), 6 deletions(-)

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index d2a89a5d63b4..82a5fa0fae90 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -2146,3 +2146,26 @@
   }
   [(set_attr "type" "vfminmax")]
 )
+
+;; vfwmul.vf
+(define_insn_and_split "*vfwmul_vf_"
+  [(set (match_operand:VWEXTF 0 "register_operand")
+(mult:VWEXTF
+  (float_extend:VWEXTF
+   (match_operand: 1 "register_operand"))
+  (vec_duplicate:VWEXTF
+   (float_extend:
+ (match_operand: 2 "register_operand")]
+  "TARGET_VECTOR && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
+  {
+riscv_vector::emit_vlmax_insn (code_for_pred_dual_widen_scalar (MULT,
+   mode),
+  riscv_vector::BINARY_OP_FRM_DYN, operands);
+
+DONE;
+  }
+  [(set_attr "type" "vfwmul")]
+)
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 95d44baf6fdd..d62f8bb2cd2e 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -7250,8 +7250,8 @@
  (any_widen_binop:VWEXTF
(float_extend:VWEXTF
  (match_operand: 3 "register_operand" "   vr,   
vr"))
-   (float_extend:VWEXTF
- (vec_duplicate:
+   (vec_duplicate:VWEXTF
+ (float_extend:
(match_operand: 4 "register_operand"   "f,
f"
  (match_operand:VWEXTF 2 "vector_merge_operand"   "   vu,
0")))]
   "TARGET_VECTOR"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
index 0be64f1fd646..cbec87e6c0b3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
@@ -22,6 +22,7 @@ DEF_VF_BINOP_CASE_2_WRAP

[gcc(refs/users/meissner/heads/work221-dmf)] Add ChangeLog.dmf and update REVISION.

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:9975c6ace0d1c20c67eca852dc9ea265bca576dd

commit 9975c6ace0d1c20c67eca852dc9ea265bca576dd
Author: Michael Meissner 
Date:   Mon Sep 8 14:01:09 2025 -0400

Add ChangeLog.dmf and update REVISION.

2025-09-08  Michael Meissner  

gcc/

* ChangeLog.dmf: New file for branch.
* REVISION: Update.

Diff:
---
 gcc/ChangeLog.dmf | 14 ++
 gcc/REVISION  |  2 +-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/ChangeLog.dmf b/gcc/ChangeLog.dmf
new file mode 100644
index ..40d6dcacd400
--- /dev/null
+++ b/gcc/ChangeLog.dmf
@@ -0,0 +1,14 @@
+ Branch work221-dmf, baseline 
+
+2025-09-08   Michael Meissner  
+
+Add ChangeLog.dmf and update REVISION.
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   * ChangeLog.dmf: New file for branch.
+   * REVISION: Update.
+
+   Clone branch
diff --git a/gcc/REVISION b/gcc/REVISION
index 0c170cfe7d4e..626a95903619 100644
--- a/gcc/REVISION
+++ b/gcc/REVISION
@@ -1 +1 @@
-work221 branch
+work221-dmf branch


[gcc] Created branch 'meissner/heads/work221-test' in namespace 'refs/users'

2025-09-08 Thread Michael Meissner via Gcc-cvs
The branch 'meissner/heads/work221-test' was created in namespace 'refs/users' 
pointing to:

 f54097b86628... Add ChangeLog.meissner and REVISION.


[gcc(refs/users/meissner/heads/work221)] Add ChangeLog.meissner and REVISION.

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:f54097b86628402dabe0fb8716d56192ef3383d6

commit f54097b86628402dabe0fb8716d56192ef3383d6
Author: Michael Meissner 
Date:   Mon Sep 8 13:58:10 2025 -0400

Add ChangeLog.meissner and REVISION.

2025-09-08  Michael Meissner  

gcc/

* REVISION: New file for branch.
* ChangeLog.meissner: New file.

gcc/c-family/

* ChangeLog.meissner: New file.

gcc/c/

* ChangeLog.meissner: New file.

gcc/cp/

* ChangeLog.meissner: New file.

gcc/fortran/

* ChangeLog.meissner: New file.

gcc/testsuite/

* ChangeLog.meissner: New file.

libgcc/

* ChangeLog.meissner: New file.

Diff:
---
 gcc/ChangeLog.meissner   | 38 ++
 gcc/REVISION |  1 +
 gcc/c-family/ChangeLog.meissner  | 38 ++
 gcc/c/ChangeLog.meissner | 38 ++
 gcc/cp/ChangeLog.meissner| 38 ++
 gcc/fortran/ChangeLog.meissner   | 38 ++
 gcc/testsuite/ChangeLog.meissner | 38 ++
 libgcc/ChangeLog.meissner| 38 ++
 libstdc++-v3/ChangeLog.meissner  | 38 ++
 9 files changed, 305 insertions(+)

diff --git a/gcc/ChangeLog.meissner b/gcc/ChangeLog.meissner
new file mode 100644
index ..ebce14bf532b
--- /dev/null
+++ b/gcc/ChangeLog.meissner
@@ -0,0 +1,38 @@
+ Branch work221, baseline 
+
+2025-09-08   Michael Meissner  
+
+Add ChangeLog.meissner and REVISION.
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   * REVISION: New file for branch.
+   * ChangeLog.meissner: New file.
+
+gcc/c-family/
+
+   * ChangeLog.meissner: New file.
+
+gcc/c/
+
+   * ChangeLog.meissner: New file.
+
+gcc/cp/
+
+   * ChangeLog.meissner: New file.
+
+gcc/fortran/
+
+   * ChangeLog.meissner: New file.
+
+gcc/testsuite/
+
+   * ChangeLog.meissner: New file.
+
+libgcc/
+
+   * ChangeLog.meissner: New file.
+
+   Clone branch
diff --git a/gcc/REVISION b/gcc/REVISION
new file mode 100644
index ..0c170cfe7d4e
--- /dev/null
+++ b/gcc/REVISION
@@ -0,0 +1 @@
+work221 branch
diff --git a/gcc/c-family/ChangeLog.meissner b/gcc/c-family/ChangeLog.meissner
new file mode 100644
index ..ebce14bf532b
--- /dev/null
+++ b/gcc/c-family/ChangeLog.meissner
@@ -0,0 +1,38 @@
+ Branch work221, baseline 
+
+2025-09-08   Michael Meissner  
+
+Add ChangeLog.meissner and REVISION.
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   * REVISION: New file for branch.
+   * ChangeLog.meissner: New file.
+
+gcc/c-family/
+
+   * ChangeLog.meissner: New file.
+
+gcc/c/
+
+   * ChangeLog.meissner: New file.
+
+gcc/cp/
+
+   * ChangeLog.meissner: New file.
+
+gcc/fortran/
+
+   * ChangeLog.meissner: New file.
+
+gcc/testsuite/
+
+   * ChangeLog.meissner: New file.
+
+libgcc/
+
+   * ChangeLog.meissner: New file.
+
+   Clone branch
diff --git a/gcc/c/ChangeLog.meissner b/gcc/c/ChangeLog.meissner
new file mode 100644
index ..ebce14bf532b
--- /dev/null
+++ b/gcc/c/ChangeLog.meissner
@@ -0,0 +1,38 @@
+ Branch work221, baseline 
+
+2025-09-08   Michael Meissner  
+
+Add ChangeLog.meissner and REVISION.
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   * REVISION: New file for branch.
+   * ChangeLog.meissner: New file.
+
+gcc/c-family/
+
+   * ChangeLog.meissner: New file.
+
+gcc/c/
+
+   * ChangeLog.meissner: New file.
+
+gcc/cp/
+
+   * ChangeLog.meissner: New file.
+
+gcc/fortran/
+
+   * ChangeLog.meissner: New file.
+
+gcc/testsuite/
+
+   * ChangeLog.meissner: New file.
+
+libgcc/
+
+   * ChangeLog.meissner: New file.
+
+   Clone branch
diff --git a/gcc/cp/ChangeLog.meissner b/gcc/cp/ChangeLog.meissner
new file mode 100644
index ..ebce14bf532b
--- /dev/null
+++ b/gcc/cp/ChangeLog.meissner
@@ -0,0 +1,38 @@
+ Branch work221, baseline 
+
+2025-09-08   Michael Meissner  
+
+Add ChangeLog.meissner and REVISION.
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   * REVISION: New file for branch.
+   * ChangeLog.meissner: New file.
+
+gcc/c-family/
+
+   * ChangeLog.meissner: New file.
+
+gcc/c/
+
+   * ChangeLog.meissner: New file.
+
+gcc/cp/
+
+   * ChangeLog.meissner: New file.
+
+gcc/fortran/
+
+   * ChangeLog.meissner: New file.
+
+gcc/testsuite/
+
+   * ChangeLog.meissner: New file.
+
+libgcc/
+
+   * ChangeLog.meissner: New file.
+
+   Clone branch
diff --git a/gcc/fortran/ChangeLog.meissner b/gcc/fortran/ChangeLog.meissner
new file mode 100644
index

[gcc] Created branch 'meissner/heads/work221-orig' in namespace 'refs/users'

2025-09-08 Thread Michael Meissner via Gcc-cvs
The branch 'meissner/heads/work221-orig' was created in namespace 'refs/users' 
pointing to:

 5ee35b12de83... Ada: Make -fdump-ada-spec deal with pointers to anonymous s


[gcc] Created branch 'meissner/heads/work221-bugs' in namespace 'refs/users'

2025-09-08 Thread Michael Meissner via Gcc-cvs
The branch 'meissner/heads/work221-bugs' was created in namespace 'refs/users' 
pointing to:

 f54097b86628... Add ChangeLog.meissner and REVISION.


[gcc] Created branch 'meissner/heads/work221-sha' in namespace 'refs/users'

2025-09-08 Thread Michael Meissner via Gcc-cvs
The branch 'meissner/heads/work221-sha' was created in namespace 'refs/users' 
pointing to:

 f54097b86628... Add ChangeLog.meissner and REVISION.


[gcc] Created branch 'meissner/heads/work221-submit' in namespace 'refs/users'

2025-09-08 Thread Michael Meissner via Gcc-cvs
The branch 'meissner/heads/work221-submit' was created in namespace 
'refs/users' pointing to:

 9c2730793df1... Add REVISION.


[gcc(refs/users/meissner/heads/work221-test)] Add ChangeLog.test and update REVISION.

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:a335aabaf43dc1a39a5830419ed06a019062e92f

commit a335aabaf43dc1a39a5830419ed06a019062e92f
Author: Michael Meissner 
Date:   Mon Sep 8 14:04:36 2025 -0400

Add ChangeLog.test and update REVISION.

2025-09-08  Michael Meissner  

gcc/

* ChangeLog.test: New file for branch.
* REVISION: Update.

Diff:
---
 gcc/ChangeLog.test | 14 ++
 gcc/REVISION   |  2 +-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/ChangeLog.test b/gcc/ChangeLog.test
new file mode 100644
index ..64c0782bb5d6
--- /dev/null
+++ b/gcc/ChangeLog.test
@@ -0,0 +1,14 @@
+ Branch work221-test, baseline 
+
+2025-09-08   Michael Meissner  
+
+Add ChangeLog.test and update REVISION.
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   * ChangeLog.test: New file for branch.
+   * REVISION: Update.
+
+   Clone branch
diff --git a/gcc/REVISION b/gcc/REVISION
index 0c170cfe7d4e..20c224ae1642 100644
--- a/gcc/REVISION
+++ b/gcc/REVISION
@@ -1 +1 @@
-work221 branch
+work221-test branch


[gcc(refs/users/meissner/heads/work221)] Add support for -mcpu=future

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:e81e8b3c08ace5974d4a540e34e9e1397cf874b7

commit e81e8b3c08ace5974d4a540e34e9e1397cf874b7
Author: Michael Meissner 
Date:   Mon Sep 8 14:09:41 2025 -0400

Add support for -mcpu=future

This patch adds the support that can be used in developing GCC support for
future PowerPC processors.

This support is done by adding support for CPU ISA bits that are set 
directly
via the -mcpu= option, without having a -m bit.

2025-09-08  Michael Meissner  

gcc/

* config.gcc (powerpc*-*-*): Add support for configuration option
--with-cpu=future.
* config/rs6000/aix71.h (ASM_CPU_SPEC): Pass -mfuture to the 
assembler
if -mcpu=future was used.
* config/rs6000/aix72.h (ASM_CPU_SPEC): Likewise.
* config/rs6000/aix73.h (ASM_CPU_SPEC): Likewise.
* config/rs6000/driver-rs6000.cc (asm_names): Likewise.
* config/rs6000/rs6000-c.cc (rs6000_target_modify_macros): If
-mcpu=future, define _ARCH_FUTURE.  Add CPU ISA flag bit argument.
(rs6000_cpu_cpp_builtins): Likewise.
* config/rs6000/rs6000-cpus.def (FUTURE_MASKS_SERVER): New macro.
(RS6000_CPU_ISA): New optional macro.
(future cpu): Set up for -mcpu=future.
* config/rs6000/rs6000-opts.h (PROCESSOR_FUTURE): Define as
PROCESSOR_POWER11 for now.
* config/rs6000/rs6000-protos.h (rs6000_target_modify_macros): Add
argument for CPU ISA bits.
(CPU_ISA_MASK_FUTURE): New macro.
(rs6000_target_modify_macros_ptr): Likewise.
* config/rs6000/rs6000-tables.opt: Regenerate.
* config/rs6000/rs6000.cc (rs6000_target_modify_macros_ptr): Add
additional argument.
(rs6000_print_isa_options): Likewise.
(RS6000_CPU_ISA): New macro.
(DEBUG_FMT_WX): Update to print both isa flags and CPU isa flags.
(rs6000_debug_reg_global): Add support for CPU ISA options that are
set directly via -mcpu=, rather than having separate -m
arguments.
(rs6000_option_override_internal): Likewise.
(rs6000_coy_isa_masks): New list of CPU ISA options for debugging.
(rs6000_pragma_target_parse): Add support for CPU ISA options that 
are
set directly via -mcpu=, rather than having separate -m
arguments.
(rs6000_function_specific_print): Likewise.
(rs6000_print_options_internal): Likewise.
(rs6000_print_isa_options): Likewise.
* config/rs6000/rs6000.h (ASM_CPU_SPEC): Add support for 
-mcpu=future.
* config/rs6000/rs6000.opt (rs6000_cpu_isa_flags): New target global
variable.
(x_rs6000_cpu_isa_flags): Likewise.

gcc/testsuite/

* gcc.target/powerpc/future-1.c: New test.
* gcc.target/powerpc/future-2.c: Likewise.

Diff:
---
 gcc/config.gcc  |   4 +-
 gcc/config/rs6000/aix71.h   |   1 +
 gcc/config/rs6000/aix72.h   |   1 +
 gcc/config/rs6000/aix73.h   |   1 +
 gcc/config/rs6000/driver-rs6000.cc  |   2 +
 gcc/config/rs6000/rs6000-c.cc   |  14 +++-
 gcc/config/rs6000/rs6000-cpus.def   |  24 +-
 gcc/config/rs6000/rs6000-opts.h |   4 +
 gcc/config/rs6000/rs6000-protos.h   |   5 +-
 gcc/config/rs6000/rs6000-tables.opt |  11 ++-
 gcc/config/rs6000/rs6000.cc | 118 +---
 gcc/config/rs6000/rs6000.h  |   7 ++
 gcc/config/rs6000/rs6000.opt|   8 ++
 gcc/testsuite/gcc.target/powerpc/future-1.c |  13 +++
 gcc/testsuite/gcc.target/powerpc/future-2.c |  24 ++
 15 files changed, 194 insertions(+), 43 deletions(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 9da9ac51eccd..1e3eed68dd08 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -533,7 +533,7 @@ powerpc*-*-*)
extra_headers="${extra_headers} ppu_intrinsics.h spu2vmx.h vec_types.h 
si2vmx.h"
extra_headers="${extra_headers} amo.h"
case x$with_cpu in
-   
xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[3456789]|xpower1[01]|xpower6x|xrs64a|xcell|xa2|xe500mc64|xe5500|xe6500)
+   
xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[3456789]|xpower1[01]|xpower6x|xrs64a|xcell|xa2|xe500mc64|xe5500|xe6500|xfuture)
cpu_is_64bit=yes
;;
esac
@@ -5704,7 +5704,7 @@ case "${target}" in
tm_defines="${tm_defines} CONFIG_PPC405CR"
eval "with_$which=405"
;;
-   "" | common | native \
+   "" | common | native | future \
| power[3456789] | power1[01] | power5+ | power6x \
| pow

[gcc(refs/users/meissner/heads/work221)] Update ChangeLog.*

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:ef089193fba41cfe371f6c48fc1be0f33b3c745a

commit ef089193fba41cfe371f6c48fc1be0f33b3c745a
Author: Michael Meissner 
Date:   Mon Sep 8 14:11:11 2025 -0400

Update ChangeLog.*

Diff:
---
 gcc/ChangeLog.meissner | 60 ++
 1 file changed, 60 insertions(+)

diff --git a/gcc/ChangeLog.meissner b/gcc/ChangeLog.meissner
index ebce14bf532b..832d9e5787c3 100644
--- a/gcc/ChangeLog.meissner
+++ b/gcc/ChangeLog.meissner
@@ -1,3 +1,63 @@
+ Branch work221, patch #1 
+
+Add support for -mcpu=future
+
+This patch adds the support that can be used in developing GCC support for
+future PowerPC processors.
+
+This support is done by adding support for CPU ISA bits that are set directly
+via the -mcpu= option, without having a -m bit.
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   * config.gcc (powerpc*-*-*): Add support for configuration option
+   --with-cpu=future.
+   * config/rs6000/aix71.h (ASM_CPU_SPEC): Pass -mfuture to the assembler
+   if -mcpu=future was used.
+   * config/rs6000/aix72.h (ASM_CPU_SPEC): Likewise.
+   * config/rs6000/aix73.h (ASM_CPU_SPEC): Likewise.
+   * config/rs6000/driver-rs6000.cc (asm_names): Likewise.
+   * config/rs6000/rs6000-c.cc (rs6000_target_modify_macros): If
+   -mcpu=future, define _ARCH_FUTURE.  Add CPU ISA flag bit argument.
+   (rs6000_cpu_cpp_builtins): Likewise.
+   * config/rs6000/rs6000-cpus.def (FUTURE_MASKS_SERVER): New macro.
+   (RS6000_CPU_ISA): New optional macro.
+   (future cpu): Set up for -mcpu=future.
+   * config/rs6000/rs6000-opts.h (PROCESSOR_FUTURE): Define as
+   PROCESSOR_POWER11 for now.
+   * config/rs6000/rs6000-protos.h (rs6000_target_modify_macros): Add
+   argument for CPU ISA bits.
+   (CPU_ISA_MASK_FUTURE): New macro.
+   (rs6000_target_modify_macros_ptr): Likewise.
+   * config/rs6000/rs6000-tables.opt: Regenerate.
+   * config/rs6000/rs6000.cc (rs6000_target_modify_macros_ptr): Add
+   additional argument.
+   (rs6000_print_isa_options): Likewise.
+   (RS6000_CPU_ISA): New macro.
+   (DEBUG_FMT_WX): Update to print both isa flags and CPU isa flags.
+   (rs6000_debug_reg_global): Add support for CPU ISA options that are
+   set directly via -mcpu=, rather than having separate -m
+   arguments.
+   (rs6000_option_override_internal): Likewise.
+   (rs6000_coy_isa_masks): New list of CPU ISA options for debugging.
+   (rs6000_pragma_target_parse): Add support for CPU ISA options that are
+   set directly via -mcpu=, rather than having separate -m
+   arguments.
+   (rs6000_function_specific_print): Likewise.
+   (rs6000_print_options_internal): Likewise.
+   (rs6000_print_isa_options): Likewise.
+   * config/rs6000/rs6000.h (ASM_CPU_SPEC): Add support for -mcpu=future.
+   * config/rs6000/rs6000.opt (rs6000_cpu_isa_flags): New target global
+   variable.
+   (x_rs6000_cpu_isa_flags): Likewise.
+
+gcc/testsuite/
+
+   * gcc.target/powerpc/future-1.c: New test.
+   * gcc.target/powerpc/future-2.c: Likewise.
+
  Branch work221, baseline 
 
 2025-09-08   Michael Meissner  


[gcc(refs/users/meissner/heads/work221-sha)] Add ChangeLog.sha and update REVISION.

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:c43c3d2068ee25aab9af4027a0940f9240702e69

commit c43c3d2068ee25aab9af4027a0940f9240702e69
Author: Michael Meissner 
Date:   Mon Sep 8 14:02:24 2025 -0400

Add ChangeLog.sha and update REVISION.

2025-09-08  Michael Meissner  

gcc/

* ChangeLog.sha: New file for branch.
* REVISION: Update.

Diff:
---
 gcc/ChangeLog.sha | 14 ++
 gcc/REVISION  |  2 +-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/ChangeLog.sha b/gcc/ChangeLog.sha
new file mode 100644
index ..0af4cdd11faf
--- /dev/null
+++ b/gcc/ChangeLog.sha
@@ -0,0 +1,14 @@
+ Branch work221-sha, baseline 
+
+2025-09-08   Michael Meissner  
+
+Add ChangeLog.sha and update REVISION.
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   * ChangeLog.sha: New file for branch.
+   * REVISION: Update.
+
+   Clone branch
diff --git a/gcc/REVISION b/gcc/REVISION
index 0c170cfe7d4e..fa018d185c45 100644
--- a/gcc/REVISION
+++ b/gcc/REVISION
@@ -1 +1 @@
-work221 branch
+work221-sha branch


[gcc(refs/users/meissner/heads/work221-dmf)] RFC2655-Add saturating subtract built-ins.

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:20516a64e9fae4e9d367f75f4c553d10037f72aa

commit 20516a64e9fae4e9d367f75f4c553d10037f72aa
Author: Michael Meissner 
Date:   Mon Sep 8 14:40:58 2025 -0400

RFC2655-Add saturating subtract built-ins.

This patch adds support for a saturating subtract built-in function that 
may be
added to a future PowerPC processor.  Note, if it is added, the name of the
built-in function may change before GCC 13 is released.  If the name 
changes,
we will submit a patch changing the name.

I also added support for providing dense math built-in functions, even 
though
at present, we have not added any new built-in functions for dense math.  
It is
likely we will want to add new dense math built-in functions as the dense 
math
support is fleshed out.

The patches have been tested on both little and big endian systems.  Can I 
check
it into the master branch?

2025-09-08   Michael Meissner  

gcc/

* config/rs6000/rs6000-builtin.cc (rs6000_invalid_builtin): Add 
support
for flagging invalid use of future built-in functions.
(rs6000_builtin_is_supported): Add support for future built-in
functions.
* config/rs6000/rs6000-builtins.def 
(__builtin_saturate_subtract32): New
built-in function for -mcpu=future.
(__builtin_saturate_subtract64): Likewise.
* config/rs6000/rs6000-gen-builtins.cc (enum bif_stanza): Add 
stanzas
for -mcpu=future built-ins.
(stanza_map): Likewise.
(enable_string): Likewise.
(struct attrinfo): Likewise.
(parse_bif_attrs): Likewise.
(write_decls): Likewise.
* config/rs6000/rs6000.md (sat_sub3): Add saturating subtract
built-in insn declarations.
(sat_sub3_dot): Likewise.
(sat_sub3_dot2): Likewise.
* doc/extend.texi (Future PowerPC built-ins): New section.

gcc/testsuite/

* gcc.target/powerpc/subfus-1.c: New test.
* gcc.target/powerpc/subfus-2.c: Likewise.

Diff:
---
 gcc/config/rs6000/rs6000-builtin.cc | 17 
 gcc/config/rs6000/rs6000-builtins.def   | 10 +
 gcc/config/rs6000/rs6000-gen-builtins.cc| 35 ++---
 gcc/config/rs6000/rs6000.md | 60 +
 gcc/doc/extend.texi | 24 
 gcc/testsuite/gcc.target/powerpc/subfus-1.c | 32 +++
 gcc/testsuite/gcc.target/powerpc/subfus-2.c | 32 +++
 7 files changed, 205 insertions(+), 5 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-builtin.cc 
b/gcc/config/rs6000/rs6000-builtin.cc
index 29b70a49060e..155c97b62764 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -139,6 +139,17 @@ rs6000_invalid_builtin (enum rs6000_gen_builtins fncode)
 case ENB_MMA:
   error ("%qs requires the %qs option", name, "-mmma");
   break;
+case ENB_FUTURE:
+  error ("%qs requires the %qs option", name, "-mcpu=future");
+  break;
+case ENB_FUTURE_64:
+  error ("%qs requires the %qs option and either the %qs or %qs option",
+name, "-mcpu=future", "-m64", "-mpowerpc64");
+  break;
+case ENB_DM:
+  error ("%qs requires the %qs or %qs options", name, "-mcpu=future",
+"-mdense-math");
+  break;
 default:
 case ENB_ALWAYS:
   gcc_unreachable ();
@@ -194,6 +205,12 @@ rs6000_builtin_is_supported (enum rs6000_gen_builtins 
fncode)
   return TARGET_HTM;
 case ENB_MMA:
   return TARGET_MMA;
+case ENB_FUTURE:
+  return TARGET_FUTURE;
+case ENB_FUTURE_64:
+  return TARGET_FUTURE && TARGET_POWERPC64;
+case ENB_DM:
+  return TARGET_DENSE_MATH;
 default:
   gcc_unreachable ();
 }
diff --git a/gcc/config/rs6000/rs6000-builtins.def 
b/gcc/config/rs6000/rs6000-builtins.def
index 555d7d589506..eef5f41f7615 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -137,6 +137,8 @@
 ;   endian   Needs special handling for endianness
 ;   ibmldRestrict usage to the case when TFmode is IBM-128
 ;   ibm128   Restrict usage to the case where __ibm128 is supported or if ibmld
+;   future   Restrict usage to future instructions
+;   dm   Restrict usage to dense math
 ;
 ; Each attribute corresponds to extra processing required when
 ; the built-in is expanded.  All such special processing should
@@ -3924,3 +3926,11 @@
 
   void __builtin_vsx_stxvp (v256, unsigned long, const v256 *);
 STXVP nothing {mma,pair}
+
+[future]
+  const signed int __builtin_saturate_subtract32 (signed int, signed int);
+  SAT_SUBSI sat_subsi3 {}
+
+[future-64]
+  const signed long __builtin_saturate_subtract64 (signed long,  signed long);
+  SAT_SUBDI sat_subdi3 {}
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.cc 
b/gcc/confi

[gcc(refs/users/meissner/heads/work221-dmf)] Update ChangeLog.*

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:bced48baabc09a5a13b2b04b7f99455b5d402e8d

commit bced48baabc09a5a13b2b04b7f99455b5d402e8d
Author: Michael Meissner 
Date:   Mon Sep 8 14:44:00 2025 -0400

Update ChangeLog.*

Diff:
---
 gcc/ChangeLog.dmf | 317 ++
 1 file changed, 317 insertions(+)

diff --git a/gcc/ChangeLog.dmf b/gcc/ChangeLog.dmf
index 40d6dcacd400..4d60b27621f5 100644
--- a/gcc/ChangeLog.dmf
+++ b/gcc/ChangeLog.dmf
@@ -1,3 +1,320 @@
+ Branch work221-dmf, patch #211 
+
+RFC2655-Add saturating subtract built-ins.
+
+This patch adds support for a saturating subtract built-in function that may be
+added to a future PowerPC processor.  Note, if it is added, the name of the
+built-in function may change before GCC 13 is released.  If the name changes,
+we will submit a patch changing the name.
+
+I also added support for providing dense math built-in functions, even though
+at present, we have not added any new built-in functions for dense math.  It is
+likely we will want to add new dense math built-in functions as the dense math
+support is fleshed out.
+
+The patches have been tested on both little and big endian systems.  Can I 
check
+it into the master branch?
+
+2025-09-08   Michael Meissner  
+
+gcc/
+
+   * config/rs6000/rs6000-builtin.cc (rs6000_invalid_builtin): Add support
+   for flagging invalid use of future built-in functions.
+   (rs6000_builtin_is_supported): Add support for future built-in
+   functions.
+   * config/rs6000/rs6000-builtins.def (__builtin_saturate_subtract32): New
+   built-in function for -mcpu=future.
+   (__builtin_saturate_subtract64): Likewise.
+   * config/rs6000/rs6000-gen-builtins.cc (enum bif_stanza): Add stanzas
+   for -mcpu=future built-ins.
+   (stanza_map): Likewise.
+   (enable_string): Likewise.
+   (struct attrinfo): Likewise.
+   (parse_bif_attrs): Likewise.
+   (write_decls): Likewise.
+   * config/rs6000/rs6000.md (sat_sub3): Add saturating subtract
+   built-in insn declarations.
+   (sat_sub3_dot): Likewise.
+   (sat_sub3_dot2): Likewise.
+   * doc/extend.texi (Future PowerPC built-ins): New section.
+
+gcc/testsuite/
+
+   * gcc.target/powerpc/subfus-1.c: New test.
+   * gcc.target/powerpc/subfus-2.c: Likewise.
+
+ Branch work221-dmf, patch #210 
+
+RFC2656-Support load/store vector with right length.
+
+This patch adds support for new instructions that may be added to the PowerPC
+architecture in the future to enhance the load and store vector with length
+instructions.
+
+The current instructions (lxvl, lxvll, stxvl, and stxvll) are inconvient to use
+since the count for the number of bytes must be in the top 8 bits of the GPR
+register, instead of the bottom 8 bits.  This meant that code generating these
+instructions typically had to do a shift left by 56 bits to get the count into
+the right position.  In a future version of the PowerPC architecture, new
+variants of these instructions might be added that expect the count to be in
+the bottom 8 bits of the GPR register.  These patches add this support to GCC
+if the user uses the -mcpu=future option.
+
+I discovered that the code in rs6000-string.cc to generate ISA 3.1 lxvl/stxvl
+future lxvll/stxvll instructions would generate these instructions on 32-bit.
+However the patterns for these instructions is only done on 64-bit systems.  So
+I added a check for 64-bit support before generating the instructions.
+
+The patches have been tested on both little and big endian systems.  Can I 
check
+it into the master branch?
+
+2025-09-08   Michael Meissner  
+
+gcc/
+
+   * config/rs6000/rs6000-string.cc (expand_block_move): Do not generate
+   lxvl and stxvl on 32-bit.
+   * config/rs6000/vsx.md (lxvl): If -mcpu=future, generate the lxvl with
+   the shift count automaticaly used in the insn.
+   (lxvrl): New insn for -mcpu=future.
+   (lxvrll): Likewise.
+   (stxvl): If -mcpu=future, generate the stxvl with the shift count
+   automaticaly used in the insn.
+   (stxvrl): New insn for -mcpu=future.
+   (stxvrll): Likewise.
+
+gcc/testsuite/
+
+   * gcc.target/powerpc/lxvrl.c: New test.
+   * lib/target-supports.exp (check_effective_target_powerpc_future_ok):
+   New effective target.
+
+ Branch work221-dmf, patch #202 
+
+RFC2653-PowerPC: Add support for 1,024 bit DMR registers.
+
+This patch is a prelimianry patch to add the full 1,024 bit dense math register
+(DMRs) for -mcpu=future.  The MMA 512-bit accumulators map onto the top of the
+DMR register.
+
+This patch only adds the new 1,024 bit register support.  It does not add
+support for any instructions that need 1,024 bit registers instead of 512 bit
+registers.
+
+I used the new mode 'TDOmode' to be the opaque mode used for 1,024 bit
+registers.  The 

[gcc(refs/users/meissner/heads/work221-float)] Add initial _Float16 support.

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:261ee5c479248aecc4a5bf6771f272eebf531f2f

commit 261ee5c479248aecc4a5bf6771f272eebf531f2f
Author: Michael Meissner 
Date:   Mon Sep 8 14:46:21 2025 -0400

Add initial _Float16 support.

2025-09-08  Michael Meissner  

gcc/

* config/rs6000/altivec.md (VM): Add V8HF.
(VM2): Likewise.
(VI_char): Likewise.
(VI_scalar): Likewise.
(VI_unit): Likewise.
(VP_small): Likewise.
(VP_small_lc): Likewise.
(VU_char): Likewise.
* config/rs6000/predicate.md (easy_fp_constant): Power10 can load
_Float16 constants directly.
(ieee16_xxspltiw_constant): New predicate.
* config/rs6000/rs6000-builtin.cc (rs6000_type_string): Add _Float16
support.
* config/rs6000/rs6000-call.cc (USE_FP_FOR_ARG_P): Likewise.
* config/rs6000/rs6000-modes.def (HFmode): Likewise.
* config/rs6000/rs6000-p8swap.cc (rs6000_gen_stvx): Drop V8HFmode
support since V8HFmode doesn't exist on power8 or earlier.
(rs6000_gen_lvx): Likewise.
(replace_swapped_load_constant): Likewise.
* config/rs6000/rs6000-protos.h (vec_const_128bit_type): Add mode 
field.
* config/rs6000/rs6000.cc (rs6000_hard_regno_mode_ok_uncached): Add
_Float16 support.
(rs6000_modes_tieable_p): Likewise.
(rs6000_debug_reg_global): Likewise.
(rs6000_setup_reg_addr_masks): Likewise.
(rs6000_init_hard_regno_mode_ok): Likewise.
(rs6000_secondary_reload_simple_move): Likewise.
(rs6000_preferred_reload_class): Likewise.
(rs6000_can_change_mode_class): Likewise.
(rs6000_function_value): Likewise.
(rs6000_scalar_mode_supported_p): Likewise.
(rs6000_floatn_mode): Likewise.
(constant_fp_to_128bit_vector): Likewise.
(vec_const_128bit_to_bytes): Likewise.
(constant_generates_xxspltiw): Likewise.
* config/rs6000/rs6000.h (TARGET_IEEE16): New macro.
* config/rs6000/rs6000.md (FMOVE128_GPR): Add support for V8HFmode.
(RELOAD): Likewise.
(movhf): Likewise.
(movhf_xxspltiw): Likewise.
(movhf_internal): Likewise.
* config/rs6000/rs6000.opt (-mieee16-gpr-args): New debug switch.
* config/rs6000/vector.md (VEC_L): Add V8HFmode.
(VEC_M): Likewise.
(VEC_E): Likewise.
(VEC_base): Likewise.
(VEC_base_l): Likewise.
(vec_pack_trunc_v4s): Likewise.
(vec_unpacks_hi_v8h): Likewise.
* config/rs600/vsx.md (V8HI_V8HF): New mode iterator.
(VSX_L): Add V8HFmode.
(VSX_XXBR): Likewise.
(VSm): Likewise.
(VSr): Likewise.
(VSisa): Likewise.
(??r): Likewise.
(VSc): Likewise.
(VM3): Likewise.
(VM3_char): Likewise.
(vsx_le_perm_load_): Likewise.
(vsx_le_perm_store_): Likewise.
(permute splits): Likewise.
(vsx_ld_elemrev_): Likewise.
(vsx_st_elemrev__internal): Likewise.
(vsx_xvcvhpsp): Add comment.
(vsx_xvcvhpsp_v8hf): New insn.
(vsx_xvcvsphp): Add comment.
(vsx_xvcvsphp_v8hf): New insn.
(extendhf2): Likewise.
(trunchf2): Likewise.
(xxswapd_): Add V8HFmode.
(vsx_lxvd2x8_le__store_p9): Likewise.

Diff:
---
 gcc/config/rs6000/altivec.md|  28 +-
 gcc/config/rs6000/predicates.md |  19 
 gcc/config/rs6000/rs6000-builtin.cc |   2 +
 gcc/config/rs6000/rs6000-call.cc|  10 +-
 gcc/config/rs6000/rs6000-modes.def  |   3 +
 gcc/config/rs6000/rs6000-p8swap.cc  |  14 +--
 gcc/config/rs6000/rs6000-protos.h   |   1 +
 gcc/config/rs6000/rs6000.cc | 130 ++
 gcc/config/rs6000/rs6000.h  |   3 +
 gcc/config/rs6000/rs6000.md |  60 +++-
 gcc/config/rs6000/rs6000.opt|   4 +
 gcc/config/rs6000/vector.md |  59 +++-
 gcc/config/rs6000/vsx.md| 178 +++-
 13 files changed, 402 insertions(+), 109 deletions(-)

diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 7edc288a6565..b6f92a71f963 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -191,6 +191,7 @@
 ;; otherwise handled by altivec (v2df, v2di, ti)
 (define_mode_iterator VM [V4SI
  V8HI
+ V8HF
  V16QI
  V4SF
  V2DF
@@ -203,6 +204,7 @@
 ;; Like VM, except don't do TImode
 (define_mode_iterator VM2 [V4SI
   V8HI
+  V8HF
   V16Q

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction gfc_set_temporary_descriptor

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:6dd4da98ba10271645c7a28db623554002aef630

commit 6dd4da98ba10271645c7a28db623554002aef630
Author: Mikael Morin 
Date:   Wed Jul 23 12:12:01 2025 +0200

Extraction gfc_set_temporary_descriptor

Diff:
---
 gcc/fortran/trans-array.cc  | 62 +
 gcc/fortran/trans-descriptor.cc | 53 +++
 gcc/fortran/trans-descriptor.h  |  4 +++
 3 files changed, 76 insertions(+), 43 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 31ed8a7d3079..660107aaef89 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -624,13 +624,14 @@ gfc_set_loop_bounds_from_array_spec 
(gfc_interface_mapping * mapping,
DYNAMIC is true if the caller may want to extend the array later
using realloc.  This prevents us from putting the array on the stack.  */
 
-static void
+static tree
 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
  gfc_array_info * info, tree size, tree nelem,
  tree initial, bool dynamic, bool dealloc)
 {
   tree tmp;
   tree desc;
+  tree ptr = NULL_TREE;
   bool onstack;
 
   desc = info->descriptor;
@@ -638,7 +639,7 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, 
stmtblock_t * post,
   if (size == NULL_TREE || (dynamic && integer_zerop (size)))
 {
   /* A callee allocated array.  */
-  gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
+  ptr = null_pointer_node;
   onstack = false;
 }
   else
@@ -666,8 +667,7 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, 
stmtblock_t * post,
   fold_build1_loc (input_location,
DECL_EXPR, TREE_TYPE (tmp),
tmp));
- tmp = gfc_build_addr_expr (NULL_TREE, tmp);
- gfc_conv_descriptor_data_set (pre, desc, tmp);
+ ptr = gfc_build_addr_expr (NULL_TREE, tmp);
}
   else
{
@@ -675,7 +675,7 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, 
stmtblock_t * post,
  if (initial == NULL_TREE)
{
  tmp = gfc_call_malloc (pre, NULL, size);
- tmp = gfc_evaluate_now (tmp, pre);
+ ptr = gfc_evaluate_now (tmp, pre);
}
  else
{
@@ -718,18 +718,12 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, 
stmtblock_t * post,
  build_empty_stmt (input_location));
  gfc_add_expr_to_block (pre, tmp);
 
- tmp = fold_convert (pvoid_type_node, packed);
+ ptr = fold_convert (pvoid_type_node, packed);
}
-
- gfc_conv_descriptor_data_set (pre, desc, tmp);
}
 }
   info->data = gfc_conv_descriptor_data_get (desc);
 
-  /* The offset is zero because we create temporaries with a zero
- lower bound.  */
-  gfc_conv_descriptor_offset_set (pre, desc, gfc_index_zero_node);
-
   if (dealloc && !onstack)
 {
   /* Free the temporary.  */
@@ -737,6 +731,8 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, 
stmtblock_t * post,
   tmp = gfc_call_free (tmp);
   gfc_add_expr_to_block (post, tmp);
 }
+
+  return ptr;
 }
 
 
@@ -970,6 +966,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t 
* post, gfc_ss * ss,
   gfc_ss *s;
   gfc_array_info *info;
   tree from[GFC_MAX_DIMENSIONS], to[GFC_MAX_DIMENSIONS];
+  tree stride[GFC_MAX_DIMENSIONS];
   tree type;
   tree desc;
   tree tmp;
@@ -1105,13 +1102,12 @@ gfc_trans_create_temp_array (stmtblock_t * pre, 
stmtblock_t * post, gfc_ss * ss,
   TREE_USED (desc) = 0;
 }
 
+  bool rank_changer = false;
   if (class_expr != NULL_TREE
   || (fcn_ss && fcn_ss->info && fcn_ss->info->class_container))
 {
   tree class_data;
-  tree dtype;
   gfc_expr *expr1 = fcn_ss ? fcn_ss->info->expr : NULL;
-  bool rank_changer;
 
   /* Pick out these transformational functions because they change the rank
 or shape of the first argument. This requires that the class type be
@@ -1165,17 +1161,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, 
stmtblock_t * post, gfc_ss * ss,
   class_data = gfc_class_data_get (tmp);
 
   if (rank_changer)
-   {
- /* Take the dtype from the class expression.  */
- tree class_descr = gfc_class_data_get (class_expr);
- dtype = gfc_conv_descriptor_dtype_get (class_descr);
- gfc_conv_descriptor_dtype_set (pre, desc, dtype);
-
-
- /* These transformational functions change the rank.  */
- gfc_conv_descriptor_rank_set (pre, desc, ss->loop->dimen);
- fcn_ss->info->class_container = NULL_TREE;
-   }
+   fcn_ss->info->class_container = NULL_TREE;
 
   /* Assign the new descriptor to the _data field. This allows the
 vptr _copy to be used for scalarized assi

[gcc r16-3673] c: Update TLS model after processing a TLS variable

2025-09-08 Thread H.J. Lu via Gcc-cvs
https://gcc.gnu.org/g:8cad8f94b450be9b73d07bdeef7fa1778d3f2b96

commit r16-3673-g8cad8f94b450be9b73d07bdeef7fa1778d3f2b96
Author: H.J. Lu 
Date:   Fri Sep 5 15:40:51 2025 -0700

c: Update TLS model after processing a TLS variable

Set a tentative TLS model in grokvardecl and update TLS mode with the
default TLS access model after a TLS variable has been fully processed
if the default TLS access model is stronger.

gcc/c/

PR c/107419
* c-decl.cc (c_decl_attributes): Update TLS model with the
default TLS access model if the default TLS access model is
stronger.
(grokdeclarator): Set a tentative TLS model which will be
updated by c_decl_attributes later.

Signed-off-by: H.J. Lu 

Diff:
---
 gcc/c/c-decl.cc | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 589abf4e4e28..62a0545947e5 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5582,7 +5582,16 @@ c_decl_attributes (tree *node, tree attributes, int 
flags)
   tree last_decl = lookup_last_decl (*node);
   if (last_decl == error_mark_node)
 last_decl = NULL_TREE;
-  return decl_attributes (node, attributes, flags, last_decl);
+  tree attr = decl_attributes (node, attributes, flags, last_decl);
+  if (VAR_P (*node) && DECL_THREAD_LOCAL_P (*node))
+{
+  // tls_model attribute can set a stronger TLS access model.
+  tls_model model = DECL_TLS_MODEL (*node);
+  tls_model default_model = decl_default_tls_model (*node);
+  if (default_model > model)
+   set_decl_tls_model (*node, default_model);
+}
+  return attr;
 }
 
 
@@ -8181,8 +8190,11 @@ grokdeclarator (const struct c_declarator *declarator,
TREE_PUBLIC (decl) = extern_ref;
  }
 
+   // NB: Set a tentative TLS model to avoid tls_model attribute
+   // warnings due to lack of thread storage duration.  It will
+   // be updated by c_decl_attributes later.
if (threadp)
- set_decl_tls_model (decl, decl_default_tls_model (decl));
+ set_decl_tls_model (decl, TLS_MODEL_REAL);
   }
 
 if ((storage_class == csc_extern


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Déplacement gfc_descriptor_size

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:0c0c1436a8a90e4d2edb08b6e93b42af78ba6bab

commit 0c0c1436a8a90e4d2edb08b6e93b42af78ba6bab
Author: Mikael Morin 
Date:   Wed Jul 23 16:36:42 2025 +0200

Déplacement gfc_descriptor_size

Diff:
---
 gcc/fortran/trans-array.cc  | 47 -
 gcc/fortran/trans-array.h   |  2 --
 gcc/fortran/trans-descriptor.cc | 47 +
 gcc/fortran/trans-descriptor.h  |  2 ++
 4 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index bfb14f04bd7e..ff6f7520393f 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -5780,53 +5780,6 @@ gfc_conv_array_extent_dim (tree lbound, tree ubound, 
tree* or_expr)
 }
 
 
-/* For an array descriptor, get the total number of elements.  This is just
-   the product of the extents along from_dim to to_dim.  */
-
-static tree
-gfc_conv_descriptor_size_1 (tree desc, int from_dim, int to_dim)
-{
-  tree res;
-  int dim;
-
-  res = gfc_index_one_node;
-
-  for (dim = from_dim; dim < to_dim; ++dim)
-{
-  tree lbound;
-  tree ubound;
-  tree extent;
-
-  lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
-  ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
-
-  extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
-  res = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
-res, extent);
-}
-
-  return res;
-}
-
-
-/* Full size of an array.  */
-
-tree
-gfc_conv_descriptor_size (tree desc, int rank)
-{
-  return gfc_conv_descriptor_size_1 (desc, 0, rank);
-}
-
-
-/* Size of a coarray for all dimensions but the last.  */
-
-tree
-gfc_conv_descriptor_cosize (tree desc, int rank, int corank)
-{
-  return gfc_conv_descriptor_size_1 (desc, rank, rank + corank - 1);
-}
-
-
 /* Fills in an array descriptor, and returns the size of the array.
The size will be a simple_val, ie a variable or a constant.  Also
calculates the offset of the base.  The pointer argument overflow,
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index f74dc4ab9cf9..66e8ed332b03 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -188,5 +188,3 @@ void gfc_trans_string_copy (stmtblock_t *, tree, tree, int, 
tree, tree, int);
 
 /* Calculate extent / size of an array.  */
 tree gfc_conv_array_extent_dim (tree, tree, tree*);
-tree gfc_conv_descriptor_size (tree, int);
-tree gfc_conv_descriptor_cosize (tree, int, int);
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 83e2c83826d1..76997a28f0bb 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -638,3 +638,50 @@ gfc_get_descriptor_offsets_for_info (const_tree desc_type, 
tree *data_off,
 #undef STRIDE_SUBFIELD
 #undef LBOUND_SUBFIELD
 #undef UBOUND_SUBFIELD
+
+
+/* For an array descriptor, get the total number of elements.  This is just
+   the product of the extents along from_dim to to_dim.  */
+
+static tree
+gfc_conv_descriptor_size_1 (tree desc, int from_dim, int to_dim)
+{
+  tree res;
+  int dim;
+
+  res = gfc_index_one_node;
+
+  for (dim = from_dim; dim < to_dim; ++dim)
+{
+  tree lbound;
+  tree ubound;
+  tree extent;
+
+  lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
+  ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
+
+  extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
+  res = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
+res, extent);
+}
+
+  return res;
+}
+
+
+/* Full size of an array.  */
+
+tree
+gfc_conv_descriptor_size (tree desc, int rank)
+{
+  return gfc_conv_descriptor_size_1 (desc, 0, rank);
+}
+
+
+/* Size of a coarray for all dimensions but the last.  */
+
+tree
+gfc_conv_descriptor_cosize (tree desc, int rank, int corank)
+{
+  return gfc_conv_descriptor_size_1 (desc, rank, rank + corank - 1);
+}
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index 3f602219c284..c035ec638edd 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -86,6 +86,8 @@ void gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree 
desc, tree dim, tr
 void gfc_conv_descriptor_token_set (stmtblock_t *block, tree desc, tree value);
 
 tree gfc_build_null_descriptor (tree type);
+tree gfc_conv_descriptor_size (tree, int);
+tree gfc_conv_descriptor_cosize (tree, int, int);
 
 void
 gfc_get_descriptor_offsets_for_info (const_tree desc_type, tree *data_off,


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Renseignement token dans gcf_set_descriptor_from_scalar

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:ff179b8a8ff6839473b6a7e57f6acc74ebe9f755

commit ff179b8a8ff6839473b6a7e57f6acc74ebe9f755
Author: Mikael Morin 
Date:   Wed Jul 23 09:44:49 2025 +0200

Renseignement token dans gcf_set_descriptor_from_scalar

Correction renseignement token

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

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 253d6638f2ed..87ddf839a931 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -955,11 +955,13 @@ gfc_set_descriptor_from_scalar_class (stmtblock_t *block, 
tree descr,
 void
 gfc_set_descriptor_from_scalar (stmtblock_t *block, tree descr,
tree scalar, gfc_expr *scalar_expr,
-   tree cond_presence)
+   tree cond_presence, tree caf_token)
 {
-  tree type;
-  type = gfc_get_scalar_to_descriptor_type (TREE_TYPE (scalar),
-   gfc_expr_attr (scalar_expr));
+  if (flag_coarray == GFC_FCOARRAY_LIB && caf_token)
+gfc_conv_descriptor_token_set (block, descr, caf_token);
+
+  tree type = gfc_get_scalar_to_descriptor_type (TREE_TYPE (scalar),
+gfc_expr_attr (scalar_expr));
   gfc_conv_descriptor_dtype_set (block, descr,
 gfc_get_dtype (type));
   if (cond_presence)
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index 79db264c91c1..9284320f0ba1 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -103,6 +103,6 @@ void gfc_init_descriptor_variable (stmtblock_t *block, 
gfc_symbol *sym, tree des
 void gfc_set_descriptor_from_scalar_class (stmtblock_t *, tree, tree, gfc_expr 
*);
 void gfc_set_descriptor_from_scalar (stmtblock_t *, tree, tree);
 void gfc_set_descriptor_from_scalar (stmtblock_t *, tree, tree, gfc_expr *,
-tree);
+tree, tree);
 
 #endif /* GFC_TRANS_DESCRIPTOR_H */
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index a72af35fa298..7bb2f01f7366 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -806,6 +806,7 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_symbol *fsym,
   tree var;
   tree tmp;
   tree packed = NULL_TREE;
+  tree caf_token = NULL_TREE;
 
   /* The derived type needs to be converted to a temporary CLASS object.  */
   tmp = gfc_typenode_for_spec (&fsym->ts);
@@ -822,12 +823,17 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_symbol *fsym,
 
   if (flag_coarray == GFC_FCOARRAY_LIB && CLASS_DATA (fsym)->attr.codimension)
 {
-  tree token;
   tmp = gfc_get_tree_for_caf_expr (e);
   if (POINTER_TYPE_P (TREE_TYPE (tmp)))
tmp = build_fold_indirect_ref (tmp);
-  gfc_get_caf_token_offset (parmse, &token, nullptr, tmp, NULL_TREE, e);
-  gfc_conv_descriptor_token_set (&parmse->pre, ctree, token);
+  gfc_get_caf_token_offset (parmse, &caf_token, nullptr, tmp, NULL_TREE, 
e);
+  /* Update the token here, unless it's done elsewhere like in
+ gfc_set_descriptor_from_scalar.  */
+  if ((parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
+  || (parmse->ss && parmse->ss->info && parmse->ss->info->useflags)
+  || e->rank != 0
+  || fsym->ts.u.derived->components->as == nullptr)
+   gfc_conv_descriptor_token_set (&parmse->pre, ctree, caf_token);
 }
 
   if (optional)
@@ -893,8 +899,8 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_symbol *fsym,
 
  /* Scalar to an assumed-rank array.  */
  if (fsym->ts.u.derived->components->as)
-   gfc_set_descriptor_from_scalar (&parmse->pre, ctree,
-   parmse->expr, e, cond_optional);
+   gfc_set_descriptor_from_scalar (&parmse->pre, ctree, parmse->expr,
+   e, cond_optional, caf_token);
   else
{
  tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);


[gcc(refs/users/meissner/heads/work221-sha)] PR target/117251: Improve vector nand to vector nand fusion

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:2f85422483914e5c6c0e5faf748c5a15adf5c500

commit 2f85422483914e5c6c0e5faf748c5a15adf5c500
Author: Michael Meissner 
Date:   Mon Sep 8 15:44:31 2025 -0400

PR target/117251: Improve vector nand to vector nand fusion

See the following post for a complete explanation of what the patches
for PR target/117251:

 * https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686474.html

This is patch #37 of 45 to generate the 'XXEVAL' instruction on power10
and power11 instead of using the Altivec 'VNAND' instruction feeding
into 'VNAND'.  The 'XXEVAL' instruction can use all 64 vector
registers, instead of the 32 registers that traditional Altivec vector
instructions use.  By allowing all of the vector registers to be used,
it reduces the amount of spilling that a large benchmark generated.

Currently the following code:

vector int a, b, c, d;
a = ~ ((~ (c & d)) & b);

Generates:

vnand  t,c,d
vnand  a,t,b

Now in addition with this patch, if the arguments or result is
allocated to a traditional FPR register, the GCC compiler will now
generate the following code instead of adding vector move instructions:

xxeval a,b,c,241

Since fusion using 2 Altivec instructions is slightly faster than using
the 'XXEVAL' instruction we prefer to generate the Altivec instructions
if we can.  In addition, because 'XXEVAL' is a prefixed instruction, it
possibly might generate an extra NOP instruction to align the 'XXEVAL'
instruction.

I have tested these patches on both big endian and little endian
PowerPC servers, with no regressions.  Can I check these patchs into
the trunk?

2025-09-08  Michael Meissner  

gcc/

PR target/117251
* config/rs6000/fusion.md: Regenerate.
* config/rs6000/genfusion.pl (gen_logical_addsubf): Add support
to generate vector nand => nand fusion if XXEVAL is supported.

Diff:
---
 gcc/config/rs6000/fusion.md| 15 +--
 gcc/config/rs6000/genfusion.pl |  1 +
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
index ba3a5a52b990..241b8a494fb1 100644
--- a/gcc/config/rs6000/fusion.md
+++ b/gcc/config/rs6000/fusion.md
@@ -2390,20 +2390,23 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnand -> vnand
 (define_insn "*fuse_vnand_vnand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-(ior:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v"))
-  (not:VM (match_operand:VM 1 
"altivec_register_operand" "v,v,v,v"
- (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+(ior:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v"))
+  (not:VM (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"
+ (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
vnand %3,%1,%0\;vnand %3,%3,%2
vnand %3,%1,%0\;vnand %3,%3,%2
vnand %3,%1,%0\;vnand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,241
vnand %4,%1,%0\;vnand %3,%4,%2"
   [(set_attr "type" "fused_vector")
(set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnor -> vnand
diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index 54699d199fc5..728a447c65a9 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -251,6 +251,7 @@ sub gen_logical_addsubf
   "vand_vnor"   => 224,
   "vnand_vxor"  => 225,
   "vnand_vor"   => 239,
+  "vnand_vnand" => 241,
 );
 
 KIND: foreach $kind ('scalar','vector') {


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction gfc_set_descriptor_from_scalar

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:9c131b38a654fdd57140a4693a303644edefbe23

commit 9c131b38a654fdd57140a4693a303644edefbe23
Author: Mikael Morin 
Date:   Tue Jul 22 21:03:11 2025 +0200

Extraction gfc_set_descriptor_from_scalar

Diff:
---
 gcc/fortran/trans-descriptor.cc | 20 
 gcc/fortran/trans-descriptor.h  |  2 ++
 gcc/fortran/trans-expr.cc   | 16 ++--
 3 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index a3de865f73b6..ff59042049e9 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -950,3 +950,23 @@ gfc_set_descriptor_from_scalar_class (stmtblock_t *block, 
tree descr,
 
   gfc_conv_descriptor_data_set (block, descr, tmp);
 }
+
+
+void
+gfc_set_descriptor_from_scalar (stmtblock_t *block, tree descr,
+   tree scalar, gfc_expr *scalar_expr,
+   tree cond_presence)
+{
+  tree type;
+  type = gfc_get_scalar_to_descriptor_type (TREE_TYPE (scalar),
+   gfc_expr_attr (scalar_expr));
+  gfc_conv_descriptor_dtype_set (block, descr,
+gfc_get_dtype (type));
+  if (cond_presence)
+scalar = build3_loc (input_location, COND_EXPR,
+TREE_TYPE (scalar),
+cond_presence, scalar,
+fold_convert (TREE_TYPE (scalar),
+  null_pointer_node));
+  gfc_conv_descriptor_data_set (block, descr, scalar);
+}
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index c7285529acf7..2848dcc01a4e 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -101,5 +101,7 @@ tree gfc_create_null_actual_descriptor (stmtblock_t *, 
gfc_typespec *,
 void gfc_init_descriptor_variable (stmtblock_t *block, gfc_symbol *sym, tree 
descr);
 
 void gfc_set_descriptor_from_scalar_class (stmtblock_t *, tree, tree, gfc_expr 
*);
+void gfc_set_descriptor_from_scalar (stmtblock_t *, tree, tree, gfc_expr *,
+tree);
 
 #endif /* GFC_TRANS_DESCRIPTOR_H */
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 7741d5ef0246..9c6b93a85cf9 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -901,20 +901,8 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_symbol *fsym,
 
  /* Scalar to an assumed-rank array.  */
  if (fsym->ts.u.derived->components->as)
-   {
- tree type;
- type = gfc_get_scalar_to_descriptor_type (TREE_TYPE 
(parmse->expr),
-   gfc_expr_attr (e));
- gfc_conv_descriptor_dtype_set (&parmse->pre, ctree,
-gfc_get_dtype (type));
- if (optional)
-   parmse->expr = build3_loc (input_location, COND_EXPR,
-  TREE_TYPE (parmse->expr),
-  cond_optional, parmse->expr,
-  fold_convert (TREE_TYPE 
(parmse->expr),
-null_pointer_node));
- gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
-   }
+   gfc_set_descriptor_from_scalar (&parmse->pre, ctree,
+   parmse->expr, e, cond_optional);
   else
{
  tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);


[gcc(refs/users/meissner/heads/work221-float)] Convert between _Float16 and 128-bit binary floating point.

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:585b849e5af5793b904c5cc9daf3af0cf60d375b

commit 585b849e5af5793b904c5cc9daf3af0cf60d375b
Author: Michael Meissner 
Date:   Mon Sep 8 20:34:47 2025 -0400

Convert between _Float16 and 128-bit binary floating point.

2025-09-08  Michael Meissner  

gcc/

* config/rs6000/vsx.md (extendhf2, FLOAT128 iterator): New 
insn.
(trunchf2, FLOAT128 iterator): Likewise.

Diff:
---
 gcc/config/rs6000/vsx.md | 42 +-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 218351447349..3e429bdb1765 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -3156,7 +3156,7 @@
   [(set_attr "type" "vecdouble")])
 
 
-;; Convert IEEE 16-bit floating point to/from SF and DF modes.
+;; Convert IEEE 16-bit floating point to/from binary floating point modes.
 
 (define_insn "extendhf2"
   [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
@@ -3166,6 +3166,26 @@
   "xscvhpdp %x0,%x1"
   [(set_attr "type" "fpsimple")])
 
+(define_insn_and_split "extendhf2"
+  [(set (match_operand:FLOAT128 0 "vsx_register_operand" "=wa")
+   (float_extend:FLOAT128
+(match_operand:HF 1 "vsx_register_operand" "wa")))
+   (clobber (match_scratch:DF 2 "=wa"))]
+  "TARGET_IEEE16
+   && (FLOAT128_IBM_P (mode) || FLOAT128_IEEE_P (mode))"
+  "#"
+  "&& 1"
+  [(set (match_dup 2)
+   (float_extend:DF (match_dup 1)))
+   (set (match_dup 0)
+   (float_extend:FLOAT128 (match_dup 2)))]
+{
+  if (GET_CODE (operands[2]) == SCRATCH)
+operands[2] = gen_reg_rtx (DFmode);
+}
+  [(set_attr "type" "fpsimple")
+   (set_attr "length" "8")])
+
 (define_insn "trunchf2"
   [(set (match_operand:HF 0 "vsx_register_operand" "=wa")
(float_truncate:HF
@@ -3174,6 +3194,26 @@
   "xscvdphp %x0,%1"
   [(set_attr "type" "fpsimple")])
 
+(define_insn_and_split "trunchf2"
+  [(set (match_operand:HF 0 "vsx_register_operand" "=wa")
+   (float_truncate:HF
+(match_operand:FLOAT128 1 "vsx_register_operand" "wa")))
+   (clobber (match_scratch:DF 2 "=wa"))]
+  "TARGET_IEEE16
+   && (FLOAT128_IBM_P (mode) || FLOAT128_IEEE_P (mode))"
+  "#"
+  "&& 1"
+  [(set (match_dup 2)
+   (float_truncate:DF (match_dup 1)))
+   (set (match_dup 0)
+   (float_truncate:HF (match_dup 2)))]
+{
+  if (GET_CODE (operands[2]) == SCRATCH)
+operands[2] = gen_reg_rtx (DFmode);
+}
+  [(set_attr "type" "fpsimple")
+   (set_attr "length" "8")])
+
 
 ;; Permute operations


[gcc(refs/users/meissner/heads/work221-float)] Update ChangeLog.*

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:949dabec582829cf7e035a964b48884d6692c9df

commit 949dabec582829cf7e035a964b48884d6692c9df
Author: Michael Meissner 
Date:   Mon Sep 8 20:37:05 2025 -0400

Update ChangeLog.*

Diff:
---
 gcc/ChangeLog.float | 12 
 1 file changed, 12 insertions(+)

diff --git a/gcc/ChangeLog.float b/gcc/ChangeLog.float
index 3c41a0714228..4006bf572854 100644
--- a/gcc/ChangeLog.float
+++ b/gcc/ChangeLog.float
@@ -1,3 +1,15 @@
+ Branch work221-float, patch #301 
+
+Convert between _Float16 and 128-bit binary floating point.
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   * config/rs6000/vsx.md (extendhf2, FLOAT128 iterator): New insn.
+   (trunchf2, FLOAT128 iterator): Likewise.
+
+
  Branch work221-float, patch #300 
 
 Add initial _Float16 support.


[gcc(refs/users/meissner/heads/work221-sha)] PR target/117251: Improve vector eqv to vector nor fusion

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:3b80648fa9cb5403cceb127b1f9a008518604493

commit 3b80648fa9cb5403cceb127b1f9a008518604493
Author: Michael Meissner 
Date:   Mon Sep 8 15:25:39 2025 -0400

PR target/117251: Improve vector eqv to vector nor fusion

See the following post for a complete explanation of what the patches
for PR target/117251:

 * https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686474.html

This is patch #18 of 45 to generate the 'XXEVAL' instruction on power10
and power11 instead of using the Altivec 'VEQV' instruction feeding
into 'VNOR'.  The 'XXEVAL' instruction can use all 64 vector registers,
instead of the 32 registers that traditional Altivec vector
instructions use.  By allowing all of the vector registers to be used,
it reduces the amount of spilling that a large benchmark generated.

Currently the following code:

vector int a, b, c, d;
a = ~ ((~ (c ^ d)) | b);

Generates:

veqv   t,c,d
vnor   a,t,b

Now in addition with this patch, if the arguments or result is
allocated to a traditional FPR register, the GCC compiler will now
generate the following code instead of adding vector move instructions:

xxeval a,b,c,96

Since fusion using 2 Altivec instructions is slightly faster than using
the 'XXEVAL' instruction we prefer to generate the Altivec instructions
if we can.  In addition, because 'XXEVAL' is a prefixed instruction, it
possibly might generate an extra NOP instruction to align the 'XXEVAL'
instruction.

I have tested these patches on both big endian and little endian
PowerPC servers, with no regressions.  Can I check these patchs into
the trunk?

2025-09-08  Michael Meissner  

gcc/

PR target/117251
* config/rs6000/fusion.md: Regenerate.
* config/rs6000/genfusion.pl (gen_logical_addsubf): Add support
to generate vector eqv => nor fusion if XXEVAL is supported.

Diff:
---
 gcc/config/rs6000/fusion.md| 15 +--
 gcc/config/rs6000/genfusion.pl |  1 +
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
index 486aa813575d..e5099178d63d 100644
--- a/gcc/config/rs6000/fusion.md
+++ b/gcc/config/rs6000/fusion.md
@@ -2513,20 +2513,23 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector veqv -> vnor
 (define_insn "*fuse_veqv_vnor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-(and:VM (not:VM (not:VM (xor:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v")
-  (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"
- (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+(and:VM (not:VM (not:VM (xor:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v")
+  (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"
+ (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
veqv %3,%1,%0\;vnor %3,%3,%2
veqv %3,%1,%0\;vnor %3,%3,%2
veqv %3,%1,%0\;vnor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,96
veqv %4,%1,%0\;vnor %3,%4,%2"
   [(set_attr "type" "fused_vector")
(set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnand -> vnor
diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index 8f60fe76c87b..79d9eaed7da6 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -232,6 +232,7 @@ sub gen_logical_addsubf
   "vorc_vnor"   =>  64,
   "vorc_veqv"   =>  75,
   "vorc_vorc"   =>  79,
+  "veqv_vnor"   =>  96,
 );
 
 KIND: foreach $kind ('scalar','vector') {


[gcc r16-3677] Use vpermil{ps, pd} instead of vperm{d, q} when permutation is in-lane.

2025-09-08 Thread hongtao Liu via Gcc-cvs
https://gcc.gnu.org/g:7a527754fdb61597b6a4c3289b63af3c86b2aa9d

commit r16-3677-g7a527754fdb61597b6a4c3289b63af3c86b2aa9d
Author: liuhongt 
Date:   Mon Sep 1 01:12:49 2025 -0700

Use vpermil{ps,pd} instead of vperm{d,q} when permutation is in-lane.

gcc/ChangeLog:

* config/i386/i386-expand.cc (expand_vec_perm_vpermil): Extend
to handle V8SImode.
* config/i386/i386.cc (avx_vpermilp_parallel): Extend to
handle vector integer modes with same vector size and same
component size.
* config/i386/sse.md
(_vpermilp): Ditto.
(V48_AVX): New mode iterator.
(ssefltmodesuffix): Extend for V16SI/V8DI/V16SF/V8DF.

gcc/testsuite/ChangeLog:

* gcc.target/i386/avx256_avoid_vec_perm-3.c: New test.
* gcc.target/i386/avx256_avoid_vec_perm-4.c: New test.
* gcc.target/i386/avx512bw-vpalignr-4.c: Adjust testcase.
* gcc.target/i386/avx512vl-vpalignr-4.c: Ditto.

Diff:
---
 gcc/config/i386/i386-expand.cc | 13 ++--
 gcc/config/i386/i386.cc|  6 ++
 gcc/config/i386/sse.md | 22 
 .../gcc.target/i386/avx256_avoid_vec_perm-3.c  | 24 ++
 .../gcc.target/i386/avx256_avoid_vec_perm-4.c  | 21 +++
 .../gcc.target/i386/avx512bw-vpalignr-4.c  |  4 +---
 .../gcc.target/i386/avx512vl-vpalignr-4.c  |  2 +-
 7 files changed, 78 insertions(+), 14 deletions(-)

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 3278f1fea251..dc26b3452cb1 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -20826,7 +20826,8 @@ expand_vec_perm_vpermil (struct expand_vec_perm_d *d)
   rtx rperm[8], vperm;
   unsigned i;
 
-  if (!TARGET_AVX || d->vmode != V8SFmode || !d->one_operand_p)
+  if (!TARGET_AVX || !d->one_operand_p
+  || (d->vmode != V8SImode && d->vmode != V8SFmode))
 return false;
 
   /* We can only permute within the 128-bit lane.  */
@@ -20856,7 +20857,15 @@ expand_vec_perm_vpermil (struct expand_vec_perm_d *d)
 
   vperm = gen_rtx_CONST_VECTOR (V8SImode, gen_rtvec_v (8, rperm));
   vperm = force_reg (V8SImode, vperm);
-  emit_insn (gen_avx_vpermilvarv8sf3 (d->target, d->op0, vperm));
+  rtx target = d->target;
+  rtx op0 = d->op0;
+  if (d->vmode == V8SImode)
+{
+  target = lowpart_subreg (V8SFmode, target, V8SImode);
+  op0 = lowpart_subreg (V8SFmode, op0, V8SImode);
+}
+
+  emit_insn (gen_avx_vpermilvarv8sf3 (target, op0, vperm));
 
   return true;
 }
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index d71975a42bea..5311d8c43342 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -20603,6 +20603,7 @@ avx_vpermilp_parallel (rtx par, machine_mode mode)
   switch (mode)
 {
 case E_V8DFmode:
+case E_V8DImode:
   /* In the 512-bit DFmode case, we can only move elements within
  a 128-bit lane.  First fill the second part of the mask,
 then fallthru.  */
@@ -20621,6 +20622,7 @@ avx_vpermilp_parallel (rtx par, machine_mode mode)
   /* FALLTHRU */
 
 case E_V4DFmode:
+case E_V4DImode:
   /* In the 256-bit DFmode case, we can only move elements within
  a 128-bit lane.  */
   for (i = 0; i < 2; ++i)
@@ -20638,6 +20640,7 @@ avx_vpermilp_parallel (rtx par, machine_mode mode)
   break;
 
 case E_V16SFmode:
+case E_V16SImode:
   /* In 512 bit SFmode case, permutation in the upper 256 bits
 must mirror the permutation in the lower 256-bits.  */
   for (i = 0; i < 8; ++i)
@@ -20646,6 +20649,7 @@ avx_vpermilp_parallel (rtx par, machine_mode mode)
   /* FALLTHRU */
 
 case E_V8SFmode:
+case E_V8SImode:
   /* In 256 bit SFmode case, we have full freedom of
  movement within the low 128-bit lane, but the high 128-bit
  lane must mirror the exact same pattern.  */
@@ -20656,7 +20660,9 @@ avx_vpermilp_parallel (rtx par, machine_mode mode)
   /* FALLTHRU */
 
 case E_V2DFmode:
+case E_V2DImode:
 case E_V4SFmode:
+case E_V4SImode:
   /* In the 128-bit case, we've full freedom in the placement of
 the elements from the source operand.  */
   for (i = 0; i < nelt; ++i)
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 73906b85d899..e87c26fcc072 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -302,6 +302,12 @@
V16SF (V8SF "TARGET_AVX512VL")
V8DF (V4DF "TARGET_AVX512VL")])
 
+(define_mode_iterator V48_AVX
+  [(V16SI "TARGET_AVX512F") (V8SI "TARGET_AVX") V4SI
+   (V8DI "TARGET_AVX512F") (V4DI "TARGET_AVX") (V2DI "TARGET_SSE2")
+   (V16SF "TARGET_AVX512F") (V8SF "TARGET_AVX") V4SF
+   (V8DF "TARGET_AVX512F") (V4DF "TARGET_AVX") (V2DF "TARGET_SSE2")])
+
 ;; All AVX-512{F,VL} vector modes. Supposed TARGET_AVX512F baselin

[gcc r16-3676] Exclude fake cross-lane permutation from avx256_avoid_vec_perm.

2025-09-08 Thread hongtao Liu via Gcc-cvs
https://gcc.gnu.org/g:f4154da55586ab591c1b01936ebd6ab370bc2e80

commit r16-3676-gf4154da55586ab591c1b01936ebd6ab370bc2e80
Author: liuhongt 
Date:   Tue Aug 19 22:46:40 2025 -0700

Exclude fake cross-lane permutation from avx256_avoid_vec_perm.

SLP may take a broadcast as kind of vec_perm, the patch checks the
permutation index to exclude those false positive.

gcc/ChangeLog:

* config/i386/i386.cc (ix86_vector_costs::add_stmt_cost):
Check permutation index for vec_perm, don't count it if we
know it's not a cross-lane permutation.

gcc/testsuite/ChangeLog:

* gcc.target/i386/avx256_avoid_vec_perm.c: Adjust testcase.
* gcc.target/i386/avx256_avoid_vec_perm-2.c: New test.
* gcc.target/i386/avx256_avoid_vec_perm-5.c: New test.

Diff:
---
 gcc/config/i386/i386.cc| 59 +-
 .../gcc.target/i386/avx256_avoid_vec_perm-2.c  | 21 
 .../gcc.target/i386/avx256_avoid_vec_perm-5.c  | 24 +
 .../gcc.target/i386/avx256_avoid_vec_perm.c|  2 +-
 4 files changed, 103 insertions(+), 3 deletions(-)

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 471be3e86158..d71975a42bea 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -26392,8 +26392,63 @@ ix86_vector_costs::add_stmt_cost (int count, 
vect_cost_for_stmt kind,
 stmt_cost = ix86_default_vector_cost (kind, mode);
 
   if (kind == vec_perm && vectype
-  && GET_MODE_SIZE (TYPE_MODE (vectype)) == 32)
-m_num_avx256_vec_perm[where]++;
+  && GET_MODE_SIZE (TYPE_MODE (vectype)) == 32
+  /* BIT_FIELD_REF  0 times vec_perm costs 0 in body.  */
+  && count != 0)
+{
+  bool real_perm = true;
+  unsigned nunits = TYPE_VECTOR_SUBPARTS (vectype);
+
+  if (node
+ && SLP_TREE_LOAD_PERMUTATION (node).exists ()
+ /* Loop vectorization will have 4 times vec_perm
+with index as {0, 0, 0, 0}.
+But it actually generates
+vec_perm_expr 
+vec_perm_expr 
+vec_perm_expr 
+Need to be handled separately.  */
+ && is_a  (m_vinfo))
+   {
+ unsigned half = nunits / 2;
+ unsigned i = 0;
+ bool allsame = true;
+ unsigned first = SLP_TREE_LOAD_PERMUTATION (node)[0];
+ bool cross_lane_p = false;
+ for (i = 0 ; i != SLP_TREE_LANES (node); i++)
+   {
+ unsigned tmp = SLP_TREE_LOAD_PERMUTATION (node)[i];
+ /* allsame is just a broadcast.  */
+ if (tmp != first)
+   allsame = false;
+
+ /* 4 times vec_perm with number of lanes multiple of nunits.  */
+ tmp = tmp & (nunits - 1);
+ unsigned index = i & (nunits - 1);
+ if ((index < half && tmp >= half)
+ || (index >= half && tmp < half))
+   cross_lane_p = true;
+
+ if (!allsame && cross_lane_p)
+   break;
+   }
+
+ if (i == SLP_TREE_LANES (node))
+   real_perm = false;
+   }
+
+  if (real_perm)
+   {
+ m_num_avx256_vec_perm[where] += count;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+   {
+ fprintf (dump_file, "Detected avx256 cross-lane permutation: ");
+ if (stmt_info)
+   print_gimple_expr (dump_file, stmt_info->stmt, 0, TDF_SLIM);
+ fprintf (dump_file, " \n");
+   }
+   }
+}
 
   /* Penalize DFmode vector operations for Bonnell.  */
   if (TARGET_CPU_P (BONNELL) && kind == vector_stmt
diff --git a/gcc/testsuite/gcc.target/i386/avx256_avoid_vec_perm-2.c 
b/gcc/testsuite/gcc.target/i386/avx256_avoid_vec_perm-2.c
new file mode 100644
index ..8d4e641444d2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx256_avoid_vec_perm-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=sierraforest -O2 -fdump-tree-slp-details" } */
+/* { dg-final { scan-tree-dump-times {(?n)Detected avx256 cross-lane 
permutation} 1 "slp2" } } */
+
+void
+foo (double* a, double* __restrict b, int c, int n)
+{
+  a[0] = b[100] * b[2];
+  a[1] = b[100] * b[3];
+  a[2] = b[100] * b[0];
+  a[3] = b[100] * b[1];
+}
+
+void
+foo1 (double* a, double* __restrict b, int c, int n)
+{
+  a[0] = b[100] * b[0];
+  a[1] = b[100] * b[1];
+  a[2] = b[100] * b[3];
+  a[3] = b[100] * b[2];
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx256_avoid_vec_perm-5.c 
b/gcc/testsuite/gcc.target/i386/avx256_avoid_vec_perm-5.c
new file mode 100644
index ..c11bea8c7b36
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx256_avoid_vec_perm-5.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=sierraforest -Ofast" } */
+/* { dg-final { scan-assembler-not {(?n)vpermpd.*%ymm} } } */
+
+typedef struct {
+  unsigned short m1, m2, m3, m4;
+} the_struct_t;
+typedef struct {
+  d

[gcc(refs/users/meissner/heads/work221-float)] Update conversions between _Float16 and various floating point types.

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:fde5b8c4c9fb16fb9aab1c9aff6e2beab61e24a3

commit fde5b8c4c9fb16fb9aab1c9aff6e2beab61e24a3
Author: Michael Meissner 
Date:   Mon Sep 8 23:30:04 2025 -0400

Update conversions between _Float16 and various floating point types.

2025-09-08  Michael Meissner  

gcc/

* config/rs6000/rs6000.md (HF_CONVERT): New mode iterator.
(extendhf2): Move from vsx.md, add conversion to/from decimal
types.
(trunc2): Likewise.
* config/rs6000/vsx.md (extendhf2): Move to vsx.md.
(trunchf2): Likewise.

Diff:
---
 gcc/config/rs6000/rs6000.md | 49 +
 gcc/config/rs6000/vsx.md| 59 -
 2 files changed, 49 insertions(+), 59 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 7ba204d5..a81758e62a02 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -858,6 +858,10 @@
 (SF "TARGET_P8_VECTOR")
 (DI "TARGET_POWERPC64")])
 
+;; Mode iterator for floating point modes other than SF/DFmode that we
+;; convert to/from _Float16 (HFmode) via DFmode.
+(define_mode_iterator HF_CONVERT [TF KF IF SD DD TD])
+
 (include "darwin.md")
 
 ;; Start with fixed-point load and store insns.  Here we put only the more
@@ -5850,6 +5854,51 @@
   "xxsel %x0,%x4,%x3,%x1"
   [(set_attr "type" "vecmove")])
 
+
+;; Convert IEEE 16-bit floating point to/from other floating point modes.
+
+(define_insn "extendhf2"
+  [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
+   (float_extend:SFDF
+(match_operand:HF 1 "vsx_register_operand" "wa")))]
+  "TARGET_IEEE16"
+  "xscvhpdp %x0,%x1"
+  [(set_attr "type" "fpsimple")])
+
+(define_insn "trunchf2"
+  [(set (match_operand:HF 0 "vsx_register_operand" "=wa")
+   (float_truncate:HF
+(match_operand:SFDF 1 "vsx_register_operand" "wa")))]
+  "TARGET_IEEE16"
+  "xscvdphp %x0,%1"
+  [(set_attr "type" "fpsimple")])
+
+;; Use DFmode to convert to/from HFmode for floating point types other
+;; than SF/DFmode.
+(define_expand "extendhf2"
+  [(set (match_operand:HF_CONVERT 0 "vsx_register_operand" "=wa")
+   (float_extend:HF_CONVERT
+(match_operand:HF 1 "vsx_register_operand" "wa")))]
+  "TARGET_IEEE16"
+{
+  rtx df_tmp = gen_reg_rtx (DFmode);
+  convert_move (df_tmp, operands[1], 0);
+  convert_move (operands[0], df_tmp, 0);
+  DONE;
+})
+
+(define_expand "trunchf2"
+  [(set (match_operand:HF 0 "vsx_register_operand" "=wa")
+   (float_truncate:HF
+(match_operand:HF_CONVERT 1 "vsx_register_operand" "wa")))]
+  "TARGET_IEEE16"
+{
+  rtx df_tmp = gen_reg_rtx (DFmode);
+  convert_move (df_tmp, operands[1], 0);
+  convert_move (operands[0], df_tmp, 0);
+  DONE;
+})
+
 
 ;; Conversions to and from floating-point.
 
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 3e429bdb1765..09b4d53813ba 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -3155,65 +3155,6 @@
   "xvrdpiz %x0,%x1"
   [(set_attr "type" "vecdouble")])
 
-
-;; Convert IEEE 16-bit floating point to/from binary floating point modes.
-
-(define_insn "extendhf2"
-  [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
-   (float_extend:SFDF
-(match_operand:HF 1 "vsx_register_operand" "wa")))]
-  "TARGET_IEEE16"
-  "xscvhpdp %x0,%x1"
-  [(set_attr "type" "fpsimple")])
-
-(define_insn_and_split "extendhf2"
-  [(set (match_operand:FLOAT128 0 "vsx_register_operand" "=wa")
-   (float_extend:FLOAT128
-(match_operand:HF 1 "vsx_register_operand" "wa")))
-   (clobber (match_scratch:DF 2 "=wa"))]
-  "TARGET_IEEE16
-   && (FLOAT128_IBM_P (mode) || FLOAT128_IEEE_P (mode))"
-  "#"
-  "&& 1"
-  [(set (match_dup 2)
-   (float_extend:DF (match_dup 1)))
-   (set (match_dup 0)
-   (float_extend:FLOAT128 (match_dup 2)))]
-{
-  if (GET_CODE (operands[2]) == SCRATCH)
-operands[2] = gen_reg_rtx (DFmode);
-}
-  [(set_attr "type" "fpsimple")
-   (set_attr "length" "8")])
-
-(define_insn "trunchf2"
-  [(set (match_operand:HF 0 "vsx_register_operand" "=wa")
-   (float_truncate:HF
-(match_operand:SFDF 1 "vsx_register_operand" "wa")))]
-  "TARGET_IEEE16"
-  "xscvdphp %x0,%1"
-  [(set_attr "type" "fpsimple")])
-
-(define_insn_and_split "trunchf2"
-  [(set (match_operand:HF 0 "vsx_register_operand" "=wa")
-   (float_truncate:HF
-(match_operand:FLOAT128 1 "vsx_register_operand" "wa")))
-   (clobber (match_scratch:DF 2 "=wa"))]
-  "TARGET_IEEE16
-   && (FLOAT128_IBM_P (mode) || FLOAT128_IEEE_P (mode))"
-  "#"
-  "&& 1"
-  [(set (match_dup 2)
-   (float_truncate:DF (match_dup 1)))
-   (set (match_dup 0)
-   (float_truncate:HF (match_dup 2)))]
-{
-  if (GET_CODE (operands[2]) == SCRATCH)
-operands[2] = gen_reg_rtx (DFmode);
-}
-  [(set_attr "type" "fpsimple")
-   (set_attr "length" "8")])
-
 
 ;; Permut

[gcc] Created branch 'meissner/heads/work221' in namespace 'refs/users'

2025-09-08 Thread Michael Meissner via Gcc-cvs
The branch 'meissner/heads/work221' was created in namespace 'refs/users' 
pointing to:

 5ee35b12de83... Ada: Make -fdump-ada-spec deal with pointers to anonymous s


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction gfc_set_descriptor_for_assign_realloc

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:f5c0fa1d9cbf0a5ebbcdfc7bdcba64d5b91ac61a

commit f5c0fa1d9cbf0a5ebbcdfc7bdcba64d5b91ac61a
Author: Mikael Morin 
Date:   Thu Jul 31 12:11:15 2025 +0200

Extraction gfc_set_descriptor_for_assign_realloc

Diff:
---
 gcc/fortran/trans-array.cc  | 228 ++--
 gcc/fortran/trans-array.h   |   1 +
 gcc/fortran/trans-descriptor.cc | 215 +
 gcc/fortran/trans-descriptor.h  |   3 +
 4 files changed, 225 insertions(+), 222 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 84ec10e7808c..10a661e76260 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -10571,76 +10571,6 @@ gfc_check_pdt_dummy (gfc_symbol * der_type, tree decl, 
int rank,
 }
 
 
-/* Returns the value of LBOUND for an expression.  This could be broken out
-   from gfc_conv_intrinsic_bound but this seemed to be simpler.  This is
-   called by gfc_alloc_allocatable_for_assignment.  */
-static tree
-get_std_lbound (gfc_expr *expr, tree desc, int dim, bool assumed_size)
-{
-  tree lbound;
-  tree ubound;
-  tree stride;
-  tree cond, cond1, cond3, cond4;
-  tree tmp;
-  gfc_ref *ref;
-
-  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
-{
-  tmp = gfc_rank_cst[dim];
-  lbound = gfc_conv_descriptor_lbound_get (desc, tmp);
-  ubound = gfc_conv_descriptor_ubound_get (desc, tmp);
-  stride = gfc_conv_descriptor_stride_get (desc, tmp);
-  cond1 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
-  ubound, lbound);
-  cond3 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
-  stride, gfc_index_zero_node);
-  cond3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
-  logical_type_node, cond3, cond1);
-  cond4 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
-  stride, gfc_index_zero_node);
-  if (assumed_size)
-   cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
-   tmp, build_int_cst (gfc_array_index_type,
-   expr->rank - 1));
-  else
-   cond = logical_false_node;
-
-  cond1 = fold_build2_loc (input_location, TRUTH_OR_EXPR,
-  logical_type_node, cond3, cond4);
-  cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
- logical_type_node, cond, cond1);
-
-  return fold_build3_loc (input_location, COND_EXPR,
- gfc_array_index_type, cond,
- lbound, gfc_index_one_node);
-}
-
-  if (expr->expr_type == EXPR_FUNCTION)
-{
-  /* A conversion function, so use the argument.  */
-  gcc_assert (expr->value.function.isym
- && expr->value.function.isym->conversion);
-  expr = expr->value.function.actual->expr;
-}
-
-  if (expr->expr_type == EXPR_VARIABLE)
-{
-  tmp = TREE_TYPE (expr->symtree->n.sym->backend_decl);
-  for (ref = expr->ref; ref; ref = ref->next)
-   {
- if (ref->type == REF_COMPONENT
-   && ref->u.c.component->as
-   && ref->next
-   && ref->next->u.ar.type == AR_FULL)
-   tmp = TREE_TYPE (ref->u.c.component->backend_decl);
-   }
-  return GFC_TYPE_ARRAY_LBOUND(tmp, dim);
-}
-
-  return gfc_index_one_node;
-}
-
-
 /* Returns true if an expression represents an lhs that can be reallocated
on assignment.  */
 
@@ -10790,8 +10720,8 @@ concat_str_length (gfc_expr* expr)
At the end of the function, the expressions have been replaced with variable
references.  */
 
-static void
-update_reallocated_descriptor (stmtblock_t *block, gfc_loopinfo *loop)
+void
+gfc_update_reallocated_descriptor (stmtblock_t *block, gfc_loopinfo *loop)
 {
   for (gfc_ss *s = loop->ss; s != gfc_ss_terminator; s = s->loop_chain)
 {
@@ -10844,7 +10774,6 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo 
*loop,
   gfc_array_info *linfo;
   tree realloc_expr;
   tree alloc_expr;
-  tree size1;
   tree size2;
   tree elemsize1;
   tree elemsize2;
@@ -10852,19 +10781,15 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo 
*loop,
   tree cond_null;
   tree cond;
   tree tmp;
-  tree tmp2;
   tree lbound;
   tree ubound;
   tree desc;
   tree old_desc;
   tree desc2;
-  tree offset;
   tree jump_label1;
   tree jump_label2;
-  tree lbd;
   tree class_expr2 = NULL_TREE;
   int n;
-  gfc_array_spec * as;
   bool coarray = (flag_coarray == GFC_FCOARRAY_LIB
  && gfc_caf_attr (expr1, true).codimension);
   tree token;
@@ -11090,20 +11015,6 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo 
*loop,
  build_empty_stmt (input_location));
   gfc_add_expr_to_block (&fblock, tmp);
 
-  /* Get arrayspec if expr is a full array.  */
-  if (expr2 && expr2->expr_type

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Refactor set_gfc_from_cfi

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:ef2b995bff3e3f7758e7aab4dd6698a354f58c10

commit ef2b995bff3e3f7758e7aab4dd6698a354f58c10
Author: Mikael Morin 
Date:   Fri Aug 15 15:27:59 2025 +0200

Refactor set_gfc_from_cfi

Correction régression bind_c_optional-1

Correction renseignement stride

Correction régression bind-c-contiguous-3

Correction motif array_reference_3

Suppression code commenté

Modif dump

Diff:
---
 gcc/fortran/trans-descriptor.cc | 174 
 gcc/testsuite/gfortran.dg/array_reference_3.f90 |   2 +-
 2 files changed, 89 insertions(+), 87 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index f9f5f7166129..d6fe1fc91c01 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -1795,6 +1795,61 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree 
desc, tree ptr,
 }
 
 
+static void
+set_gfc_dimension_from_cfi (stmtblock_t *block, tree gfc, tree cfi, tree idx,
+   tree lbound, tree offset_var, tree cont_stride_var,
+   bool contiguous)
+{
+  /* gfc->dim[i].lbound = ... */
+  lbound = fold_convert (gfc_array_index_type, lbound);
+  lbound = gfc_evaluate_now (lbound, block);
+  gfc_conv_descriptor_lbound_set (block, gfc, idx, lbound);
+
+  /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
+  tree tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+ lbound, gfc_index_one_node);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+gfc_get_cfi_dim_extent (cfi, idx), tmp);
+  gfc_conv_descriptor_ubound_set (block, gfc, idx, tmp);
+
+  tree stride;
+  if (contiguous)
+{
+  /* gfc->dim[i].stride
+  = idx == 0 ? 1 : gfc->dim[i-1].stride * cfi->dim[i-1].extent */
+  tree cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
+  idx, build_zero_cst (TREE_TYPE (idx)));
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (idx),
+idx, build_int_cst (TREE_TYPE (idx), 1));
+  tmp = gfc_get_cfi_dim_extent (cfi, tmp);
+  tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
+tmp, cont_stride_var);
+  tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
+   gfc_index_one_node, tmp);
+  stride = gfc_evaluate_now (tmp, block);
+  gfc_add_modify (block, cont_stride_var, stride);
+}
+  else
+{
+  /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
+  tmp = gfc_get_cfi_dim_sm (cfi, idx);
+  tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
+gfc_array_index_type, tmp,
+fold_convert (gfc_array_index_type,
+  gfc_get_cfi_desc_elem_len (cfi)));
+  stride = gfc_evaluate_now (tmp, block);
+}
+  gfc_conv_descriptor_stride_set (block, gfc, idx, stride);
+
+  /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
+  tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
+stride, lbound);
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+offset_var, tmp);
+  gfc_add_modify (block, offset_var, tmp);
+}
+
+
 void
 gfc_set_gfc_from_cfi (stmtblock_t *block, tree gfc, gfc_expr *e, tree rank,
  tree gfc_strlen, tree cfi, gfc_symbol *fsym)
@@ -1834,43 +1889,21 @@ gfc_set_gfc_from_cfi (stmtblock_t *block, tree gfc, 
gfc_expr *e, tree rank,
   gfc_conv_descriptor_span_set (&block2, gfc, tmp);
 
   /* Calculate offset + set lbound, ubound and stride.  */
-  gfc_conv_descriptor_offset_set (&block2, gfc, gfc_index_zero_node);
+  tree offset = gfc_create_var (gfc_array_index_type, "offset");
+  gfc_add_modify (&block2, offset, gfc_index_zero_node);
   /* Loop: for (i = 0; i < rank; ++i).  */
   tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
   /* Loop body.  */
   stmtblock_t loop_body;
   gfc_init_block (&loop_body);
-  /* gfc->dim[i].lbound = ... */
-  tmp = gfc_get_cfi_dim_lbound (cfi, idx);
-  gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp);
-
-  /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
-  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-gfc_conv_descriptor_lbound_get (gfc, idx),
-gfc_index_one_node);
-  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
-gfc_get_cfi_dim_extent (cfi, idx), tmp);
-  gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp);
-
-  /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
-  

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Refactoring set_dimension_fields

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:5243a81e4852ae0823230ca46e4e94498e23fb67

commit 5243a81e4852ae0823230ca46e4e94498e23fb67
Author: Mikael Morin 
Date:   Sat Aug 16 16:28:37 2025 +0200

Refactoring set_dimension_fields

Diff:
---
 gcc/fortran/trans-descriptor.cc | 46 -
 1 file changed, 27 insertions(+), 19 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index cddffac71246..65ebfeb504a6 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -1017,6 +1017,25 @@ set_dimension_bounds (stmtblock_t * block, tree descr, 
tree dim,
 }
 
 
+static void
+set_dimension_fields (stmtblock_t * block, tree descr, tree dim,
+ tree lbound, tree ubound, tree stride, tree *offset)
+{
+  stride = gfc_evaluate_now (stride, block);
+  set_dimension_bounds (block, descr, dim, lbound, ubound, stride, offset);
+  gfc_conv_descriptor_stride_set (block, descr, dim, stride);
+}
+
+
+static void
+set_dimension_fields (stmtblock_t * block, tree descr, tree dim,
+ tree lbound, tree ubound, tree stride, tree offset_var)
+{
+  stride = gfc_evaluate_now (stride, block);
+  set_dimension_bounds (block, descr, dim, lbound, ubound, stride, offset_var);
+  gfc_conv_descriptor_stride_set (block, descr, dim, stride);
+}
+
 static void
 shift_dimension_bounds (stmtblock_t * block, tree descr, tree dim,
tree new_lbound, tree orig_lbound, tree orig_ubound,
@@ -1496,22 +1515,13 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree 
dest, int dest_rank,
   gfc_add_block_to_block (block, &lower_se.post);
   gfc_add_block_to_block (block, &upper_se.post);
 
-  /* Set bounds in descriptor.  */
-  gfc_conv_descriptor_lbound_set (block, dest, gfc_rank_cst[dim], lbound);
-  gfc_conv_descriptor_ubound_set (block, dest, gfc_rank_cst[dim], ubound);
-
-  /* Set stride.  */
   stride = gfc_evaluate_now (stride, block);
-  gfc_conv_descriptor_stride_set (block, dest, gfc_rank_cst[dim], stride);
 
-  /* Update offset.  */
-  tree tmp = fold_build2_loc (input_location, MULT_EXPR,
- gfc_array_index_type, lbound, stride);
-  offset = fold_build2_loc (input_location, MINUS_EXPR,
-   gfc_array_index_type, offset, tmp);
+  set_dimension_fields (block, dest, gfc_rank_cst[dim],
+   lbound, ubound, stride, &offset);
 
   /* Update stride.  */
-  tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
+  tree tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
   stride = fold_build2_loc (input_location, MULT_EXPR,
gfc_array_index_type, stride, tmp);
 }
@@ -1852,15 +1862,13 @@ set_gfc_dimension_from_cfi (stmtblock_t *block, tree 
gfc, tree cfi, tree idx,
 {
   /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
   tmp = gfc_get_cfi_dim_sm (cfi, idx);
-  tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
-gfc_array_index_type, tmp,
-fold_convert (gfc_array_index_type,
-  gfc_get_cfi_desc_elem_len (cfi)));
-  stride = gfc_evaluate_now (tmp, block);
+  stride = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
+   gfc_array_index_type, tmp,
+   fold_convert (gfc_array_index_type,
+ gfc_get_cfi_desc_elem_len (cfi)));
 }
 
-  set_dimension_bounds (block, gfc, idx, lbound, ubound, stride, offset_var);
-  gfc_conv_descriptor_stride_set (block, gfc, idx, stride);
+  set_dimension_fields (block, gfc, idx, lbound, ubound, stride, offset_var);
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Suppression déclarations inutiles

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:6a96de713f0c6fb56c290d5235a1fd0f54e1c80a

commit 6a96de713f0c6fb56c290d5235a1fd0f54e1c80a
Author: Mikael Morin 
Date:   Thu Jul 31 17:50:45 2025 +0200

Suppression déclarations inutiles

Diff:
---
 gcc/fortran/trans-descriptor.h | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index 381389b826ad..6ca550fe8de2 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -63,18 +63,11 @@ void gfc_conv_descriptor_data_set (stmtblock_t *block, tree 
desc, tree value);
 void gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value);
 void gfc_conv_descriptor_offset_set (stmtblock_t *block, tree desc, tree 
value);
 void gfc_conv_descriptor_dtype_set (stmtblock_t *block, tree desc, tree value);
-void gfc_conv_descriptor_elem_len_set (stmtblock_t *block, tree desc, tree 
value);
 void gfc_conv_descriptor_version_set (stmtblock_t *block, tree desc, tree 
value);
 void gfc_conv_descriptor_rank_set (stmtblock_t *block, tree desc, tree value);
 void gfc_conv_descriptor_rank_set (stmtblock_t *block, tree desc, int value);
-void gfc_conv_descriptor_type_set (stmtblock_t *block, tree desc, tree value);
-tree gfc_conv_descriptor_type_set (tree desc, tree value);
-tree gfc_conv_descriptor_type_set (tree desc, int value);
-void gfc_conv_descriptor_span_set (stmtblock_t *block, tree desc, tree value);
 void gfc_conv_descriptor_dimension_set (stmtblock_t *block, tree desc, tree 
dim, tree value);
 void gfc_conv_descriptor_dimension_set (stmtblock_t *block, tree desc, int 
dim, tree value);
-void gfc_conv_descriptor_stride_set (stmtblock_t *block, tree desc, tree dim, 
tree value);
-void gfc_conv_descriptor_lbound_set (stmtblock_t *block, tree desc, tree dim, 
tree value);
 void gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree desc, tree dim, 
tree value);
 void gfc_conv_descriptor_token_set (stmtblock_t *block, tree desc, tree value);


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Suppression mise à jour offset forall

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:325ea51eeae8412fb4a15d78363267ed7c03e106

commit 325ea51eeae8412fb4a15d78363267ed7c03e106
Author: Mikael Morin 
Date:   Mon Feb 17 17:28:01 2025 +0100

Suppression mise à jour offset forall

Sauvegarde

Correction régression forall

Diff:
---
 gcc/fortran/trans-array.cc  | 55 +
 gcc/fortran/trans-array.h   |  3 ++-
 gcc/fortran/trans-descriptor.cc | 37 ++-
 gcc/fortran/trans-descriptor.h  |  4 ++-
 gcc/fortran/trans-expr.cc   |  4 ++-
 gcc/fortran/trans-stmt.cc   | 10 ++--
 gcc/fortran/trans.h |  4 ++-
 7 files changed, 78 insertions(+), 39 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index aee0351667fd..84ec10e7808c 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -960,7 +960,8 @@ get_class_info_from_ss (stmtblock_t * pre, gfc_ss *ss, tree 
*eltype,
 tree
 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * 
ss,
 tree eltype, tree initial, bool dynamic,
-bool dealloc, bool callee_alloc, locus * where)
+bool dealloc, bool callee_alloc, locus * where,
+bool shift_bounds)
 {
   gfc_loopinfo *loop;
   gfc_ss *s;
@@ -1048,19 +1049,23 @@ gfc_trans_create_temp_array (stmtblock_t * pre, 
stmtblock_t * post, gfc_ss * ss,
{
  dim = s->dim[n];
 
- /* Callee allocated arrays may not have a known bound yet.  */
- if (loop->to[n])
-   loop->to[n] = gfc_evaluate_now (
-   fold_build2_loc (input_location, MINUS_EXPR,
-gfc_array_index_type,
-loop->to[n], loop->from[n]),
-   pre);
- loop->from[n] = gfc_index_zero_node;
+ if (shift_bounds)
+   {
+ /* Callee allocated arrays may not have a known bound yet.  */
+ if (loop->to[n])
+   {
+ tree t = fold_build2_loc (input_location, MINUS_EXPR,
+   gfc_array_index_type,
+   loop->to[n], loop->from[n]);
+ loop->to[n] = gfc_evaluate_now (t, pre);
+   }
+ loop->from[n] = gfc_index_zero_node;
 
- /* We have just changed the loop bounds, we must clear the
-corresponding specloop, so that delta calculation is not skipped
-later in gfc_set_delta.  */
- loop->specloop[n] = NULL;
+ /* We have just changed the loop bounds, we must clear the
+corresponding specloop, so that delta calculation is not
+skipped later in gfc_set_delta.  */
+ loop->specloop[n] = NULL;
+   }
 
  /* We are constructing the temporary's descriptor based on the loop
 dimensions.  As the dimensions may be accessed in arbitrary order
@@ -1221,13 +1226,18 @@ gfc_trans_create_temp_array (stmtblock_t * pre, 
stmtblock_t * post, gfc_ss * ss,
{
  stride[n] = size;
 
- tmp = fold_build2_loc (input_location, PLUS_EXPR,
-gfc_array_index_type,
-to[n], gfc_index_one_node);
+ tmp = gfc_index_one_node;
+ if (!shift_bounds && !integer_zerop (from[n]))
+   tmp = fold_build2_loc (input_location, MINUS_EXPR,
+  gfc_array_index_type, 
+  gfc_index_one_node, from[n]);
+
+ tree extent = fold_build2_loc (input_location, PLUS_EXPR,
+gfc_array_index_type, to[n], tmp);
 
  /* Check whether the size for this dimension is negative.  */
  cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
- tmp, gfc_index_zero_node);
+ extent, gfc_index_zero_node);
  cond = gfc_evaluate_now (cond, pre);
 
  if (n == 0)
@@ -1237,7 +1247,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, 
stmtblock_t * post, gfc_ss * ss,
   logical_type_node, or_expr, cond);
 
  size = fold_build2_loc (input_location, MULT_EXPR,
- gfc_array_index_type, size, tmp);
+ gfc_array_index_type, size, extent);
  size = gfc_evaluate_now (size, pre);
}
 }
@@ -1265,9 +1275,9 @@ gfc_trans_create_temp_array (stmtblock_t * pre, 
stmtblock_t * post, gfc_ss * ss,
dealloc);
 
   gfc_set_temporary_descriptor (pre, desc, class_expr, elemsize, data_ptr,
-   to, stride, total_dim,
+   from, to, stride, total_dim,

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Mise à jour offset & span dans gfc_array_init_size

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:973804222e18699ad649c1d406e30dded298e6eb

commit 973804222e18699ad649c1d406e30dded298e6eb
Author: Mikael Morin 
Date:   Fri Feb 14 11:22:35 2025 +0100

Mise à jour offset & span dans gfc_array_init_size

Diff:
---
 gcc/fortran/trans-array.cc | 30 ++
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 2bd625db6aee..abf311351e25 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -5816,8 +5816,8 @@ descriptor_element_size (tree descriptor, tree 
expr3_elem_size,
 /*GCC ARRAYS*/
 
 static tree
-gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
-gfc_expr ** lower, gfc_expr ** upper, stmtblock_t * pblock,
+gfc_array_init_size (tree descriptor, int rank, int corank, gfc_expr ** lower,
+gfc_expr ** upper, stmtblock_t * pblock,
 stmtblock_t * descriptor_block, tree * overflow,
 tree expr3_elem_size, gfc_expr *expr3, tree expr3_desc,
 bool e3_has_nodescriptor, gfc_expr *expr,
@@ -6060,6 +6060,12 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
   if (rank == 0)
 return element_size;
 
+  /* Update the array descriptor with the offset and the span.  */
+  offset = gfc_evaluate_now (offset, pblock);
+  gfc_conv_descriptor_offset_set (descriptor_block, descriptor, offset);
+  tmp = fold_convert (gfc_array_index_type, element_size);
+  gfc_conv_descriptor_span_set (descriptor_block, descriptor, tmp);
+
   stride = fold_convert (size_type_node, stride);
 
   /* First check for overflow. Since an array of type character can
@@ -6086,12 +6092,6 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
   size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
  stride, element_size);
 
-  if (poffset != NULL)
-{
-  offset = gfc_evaluate_now (offset, pblock);
-  *poffset = offset;
-}
-
   if (integer_zerop (or_expr))
 return size;
   if (integer_onep (or_expr))
@@ -6153,7 +6153,6 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree 
status, tree errmsg,
 {
   tree tmp;
   tree pointer;
-  tree offset = NULL_TREE;
   tree token = NULL_TREE;
   tree size;
   tree msg;
@@ -6282,9 +6281,8 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree 
status, tree errmsg,
   size = gfc_array_init_size (se->expr, alloc_w_e3_arr_spec ? expr->rank
   : ref->u.ar.as->rank,
  coarray ? ref->u.ar.as->corank : 0,
- &offset, lower, upper,
- &se->pre, &set_descriptor_block, &overflow,
- expr3_elem_size, expr3, e3_arr_desc,
+ lower, upper, &se->pre, &set_descriptor_block,
+ &overflow, expr3_elem_size, expr3, e3_arr_desc,
  e3_has_nodescriptor, expr, element_size,
  explicit_ts);
 
@@ -6422,14 +6420,6 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree 
status, tree errmsg,
 
   gfc_add_expr_to_block (&se->pre, tmp);
 
-  /* Update the array descriptor with the offset and the span.  */
-  if (dimension)
-{
-  gfc_conv_descriptor_offset_set (&set_descriptor_block, se->expr, offset);
-  tmp = fold_convert (gfc_array_index_type, element_size);
-  gfc_conv_descriptor_span_set (&set_descriptor_block, se->expr, tmp);
-}
-
   set_descriptor = gfc_finish_block (&set_descriptor_block);
   if (status != NULL_TREE)
 {


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Déplacement gfc_grow_array

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:66251d041e8186d71d518722cbe2cc5058687c3a

commit 66251d041e8186d71d518722cbe2cc5058687c3a
Author: Mikael Morin 
Date:   Thu Jul 31 14:41:23 2025 +0200

Déplacement gfc_grow_array

Diff:
---
 gcc/fortran/trans-array.cc  | 37 -
 gcc/fortran/trans-descriptor.cc | 39 +++
 gcc/fortran/trans-descriptor.h  |  1 +
 3 files changed, 40 insertions(+), 37 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 06e6418591d5..ea2723064cd4 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1309,43 +1309,6 @@ gfc_get_iteration_count (tree start, tree end, tree step)
 }
 
 
-/* Extend the data in array DESC by EXTRA elements.  */
-
-static void
-gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
-{
-  tree arg0, arg1;
-  tree tmp;
-  tree size;
-  tree ubound;
-
-  if (integer_zerop (extra))
-return;
-
-  ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
-
-  /* Add EXTRA to the upper bound.  */
-  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
-ubound, extra);
-  gfc_conv_descriptor_ubound_set (pblock, desc, gfc_rank_cst[0], tmp);
-
-  /* Get the value of the current data pointer.  */
-  arg0 = gfc_conv_descriptor_data_get (desc);
-
-  /* Calculate the new array size.  */
-  size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
-  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
-ubound, gfc_index_one_node);
-  arg1 = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
- fold_convert (size_type_node, tmp),
- fold_convert (size_type_node, size));
-
-  /* Call the realloc() function.  */
-  tmp = gfc_call_realloc (pblock, arg0, arg1);
-  gfc_conv_descriptor_data_set (pblock, desc, tmp);
-}
-
-
 /* Return true if the bounds of iterator I can only be determined
at run time.  */
 
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index a885ad4d77aa..5ab51ad326f2 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -2468,3 +2468,42 @@ gfc_set_pdt_array_descriptor (stmtblock_t *block, tree 
descr,
 
   return size;
 }
+
+
+/* Extend the data in array DESC by EXTRA elements.  */
+
+void
+gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
+{
+  tree arg0, arg1;
+  tree tmp;
+  tree size;
+  tree ubound;
+
+  if (integer_zerop (extra))
+return;
+
+  ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
+
+  /* Add EXTRA to the upper bound.  */
+  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+ubound, extra);
+  gfc_conv_descriptor_ubound_set (pblock, desc, gfc_rank_cst[0], tmp);
+
+  /* Get the value of the current data pointer.  */
+  arg0 = gfc_conv_descriptor_data_get (desc);
+
+  /* Calculate the new array size.  */
+  size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
+  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+ubound, gfc_index_one_node);
+  arg1 = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
+ fold_convert (size_type_node, tmp),
+ fold_convert (size_type_node, size));
+
+  /* Call the realloc() function.  */
+  tmp = gfc_call_realloc (pblock, arg0, arg1);
+  gfc_conv_descriptor_data_set (pblock, desc, tmp);
+}
+
+
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index 33ed46d1c47a..f383cd97c262 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -147,5 +147,6 @@ void gfc_set_descriptor_for_assign_realloc (stmtblock_t *, 
gfc_loopinfo *,
tree, tree, bool);
 tree gfc_set_pdt_array_descriptor (stmtblock_t *, tree, gfc_array_spec *,
   gfc_actual_arglist *, tree);
+void gfc_grow_array (stmtblock_t *, tree, tree);
 
 #endif /* GFC_TRANS_DESCRIPTOR_H */


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Factorisation descriptor_element_size

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:b552327eaf3ded4a1386b236e3417a4da2ca3450

commit b552327eaf3ded4a1386b236e3417a4da2ca3450
Author: Mikael Morin 
Date:   Fri Feb 14 11:04:01 2025 +0100

Factorisation descriptor_element_size

Diff:
---
 gcc/fortran/trans-array.cc | 85 +++---
 1 file changed, 51 insertions(+), 34 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 660107aaef89..2bd625db6aee 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -5744,6 +5744,46 @@ gfc_conv_array_extent_dim (tree lbound, tree ubound, 
tree* or_expr)
 }
 
 
+static tree
+descriptor_element_size (tree descriptor, tree expr3_elem_size,
+gfc_expr *expr3)
+{
+  tree type;
+  tree tmp;
+
+  type = TREE_TYPE (descriptor);
+
+  /* Obviously, if there is a SOURCE expression (expr3) we must use its element
+ size.  */
+  if (expr3_elem_size != NULL_TREE)
+tmp = expr3_elem_size;
+  else if (expr3 != NULL)
+{
+  if (expr3->ts.type == BT_CLASS)
+   {
+ gfc_se se_sz;
+ gfc_expr *sz = gfc_copy_expr (expr3);
+ gfc_add_vptr_component (sz);
+ gfc_add_size_component (sz);
+ gfc_init_se (&se_sz, NULL);
+ gfc_conv_expr (&se_sz, sz);
+ gfc_free_expr (sz);
+ tmp = se_sz.expr;
+   }
+  else
+   {
+ tmp = gfc_typenode_for_spec (&expr3->ts);
+ tmp = TYPE_SIZE_UNIT (tmp);
+   }
+}
+  else
+tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
+
+  /* Convert to size_t.  */
+  return fold_convert (size_type_node, tmp);
+}
+
+
 /* Fills in an array descriptor, and returns the size of the array.
The size will be a simple_val, ie a variable or a constant.  Also
calculates the offset of the base.  The pointer argument overflow,
@@ -5781,7 +5821,7 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
 stmtblock_t * descriptor_block, tree * overflow,
 tree expr3_elem_size, gfc_expr *expr3, tree expr3_desc,
 bool e3_has_nodescriptor, gfc_expr *expr,
-tree *element_size, bool explicit_ts)
+tree element_size, bool explicit_ts)
 {
   tree type;
   tree tmp;
@@ -6015,37 +6055,10 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
 }
 
   /* The stride is the number of elements in the array, so multiply by the
- size of an element to get the total size.  Obviously, if there is a
- SOURCE expression (expr3) we must use its element size.  */
-  if (expr3_elem_size != NULL_TREE)
-tmp = expr3_elem_size;
-  else if (expr3 != NULL)
-{
-  if (expr3->ts.type == BT_CLASS)
-   {
- gfc_se se_sz;
- gfc_expr *sz = gfc_copy_expr (expr3);
- gfc_add_vptr_component (sz);
- gfc_add_size_component (sz);
- gfc_init_se (&se_sz, NULL);
- gfc_conv_expr (&se_sz, sz);
- gfc_free_expr (sz);
- tmp = se_sz.expr;
-   }
-  else
-   {
- tmp = gfc_typenode_for_spec (&expr3->ts);
- tmp = TYPE_SIZE_UNIT (tmp);
-   }
-}
-  else
-tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
-
-  /* Convert to size_t.  */
-  *element_size = fold_convert (size_type_node, tmp);
+ size of an element to get the total size.  */
 
   if (rank == 0)
-return *element_size;
+return element_size;
 
   stride = fold_convert (size_type_node, stride);
 
@@ -6054,14 +6067,14 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
  dividing.  */
   tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
 size_type_node,
-TYPE_MAX_VALUE (size_type_node), *element_size);
+TYPE_MAX_VALUE (size_type_node), element_size);
   cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR,
logical_type_node, tmp, stride),
   PRED_FORTRAN_OVERFLOW);
   tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
 integer_one_node, integer_zero_node);
   cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR,
-   logical_type_node, *element_size,
+   logical_type_node, element_size,
build_int_cst (size_type_node, 0)),
   PRED_FORTRAN_SIZE_ZERO);
   tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
@@ -6071,7 +6084,7 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
   *overflow = gfc_evaluate_now (tmp, pblock);
 
   size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
- stride, *element_size);
+ stride, element_size);
 
   if (poffset != NULL)
 {
@@ -6259

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Introduction macro PTR_DECREMENT_BYTES

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:7d31a818c4c956a47617d253d9c87880fdc61e2c

commit 7d31a818c4c956a47617d253d9c87880fdc61e2c
Author: Mikael Morin 
Date:   Mon Sep 8 21:51:03 2025 +0200

Introduction macro PTR_DECREMENT_BYTES

Correction ; manquant ifindloc1.m4

Correction matmul

Correction matmul

Diff:
---
 libgfortran/intrinsics/random.c | 18 +-
 libgfortran/io/transfer.c   | 12 ++--
 libgfortran/libgfortran.h   |  3 ++-
 libgfortran/m4/cshift0.m4   |  4 ++--
 libgfortran/m4/cshift1.m4   |  2 +-
 libgfortran/m4/cshift1a.m4  |  6 +++---
 libgfortran/m4/eoshift1.m4  |  2 +-
 libgfortran/m4/eoshift3.m4  |  2 +-
 libgfortran/m4/ifindloc0.m4 | 12 ++--
 libgfortran/m4/ifindloc1.m4 | 17 ++---
 libgfortran/m4/ifindloc2.m4 |  4 ++--
 libgfortran/m4/iforeach-s.m4|  4 ++--
 libgfortran/m4/iforeach-s2.m4   |  4 ++--
 libgfortran/m4/iforeach.m4  |  4 ++--
 libgfortran/m4/ifunction-s.m4   | 10 +-
 libgfortran/m4/ifunction-s2.m4  | 10 +-
 libgfortran/m4/ifunction.m4 | 10 +-
 libgfortran/m4/ifunction_logical.m4 |  2 +-
 libgfortran/m4/in_pack.m4   |  2 +-
 libgfortran/m4/in_unpack.m4 |  2 +-
 libgfortran/m4/matmul_internal.m4   | 15 ---
 libgfortran/m4/pack.m4  |  2 +-
 libgfortran/m4/reshape.m4   |  4 ++--
 libgfortran/m4/spread.m4|  4 ++--
 libgfortran/m4/unpack.m4|  6 +++---
 25 files changed, 83 insertions(+), 78 deletions(-)

diff --git a/libgfortran/intrinsics/random.c b/libgfortran/intrinsics/random.c
index 251eb4f61c2b..b0b08638f8b4 100644
--- a/libgfortran/intrinsics/random.c
+++ b/libgfortran/intrinsics/random.c
@@ -661,7 +661,7 @@ arandom_r4 (gfc_array_r4 *x)
   count[n] = 0;
   /* We could precalculate these products, but this is a less
  frequently used path so probably not worth it.  */
-  dest -= stride[n] * extent[n];
+ PTR_DECREMENT_BYTES (dest, stride[n] * extent[n]);
   n++;
   if (n == dim)
 {
@@ -727,7 +727,7 @@ arandom_r8 (gfc_array_r8 *x)
   count[n] = 0;
   /* We could precalculate these products, but this is a less
  frequently used path so probably not worth it.  */
-  dest -= stride[n] * extent[n];
+ PTR_DECREMENT_BYTES (dest, stride[n] * extent[n]);
   n++;
   if (n == dim)
 {
@@ -795,7 +795,7 @@ arandom_r10 (gfc_array_r10 *x)
   count[n] = 0;
   /* We could precalculate these products, but this is a less
  frequently used path so probably not worth it.  */
-  dest -= stride[n] * extent[n];
+ PTR_DECREMENT_BYTES (dest, stride[n] * extent[n]);
   n++;
   if (n == dim)
 {
@@ -866,7 +866,7 @@ arandom_r16 (gfc_array_r16 *x)
   count[n] = 0;
   /* We could precalculate these products, but this is a less
  frequently used path so probably not worth it.  */
-  dest -= stride[n] * extent[n];
+ PTR_DECREMENT_BYTES (dest, stride[n] * extent[n]);
   n++;
   if (n == dim)
 {
@@ -937,7 +937,7 @@ arandom_r17 (gfc_array_r17 *x)
   count[n] = 0;
   /* We could precalculate these products, but this is a less
  frequently used path so probably not worth it.  */
-  dest -= stride[n] * extent[n];
+ PTR_DECREMENT_BYTES (dest, stride[n] * extent[n]);
   n++;
   if (n == dim)
 {
@@ -1069,7 +1069,7 @@ arandom_m2 (gfc_array_m2 *x)
  count[n] = 0;
  /* We could precalculate these products, but this is a less
 frequently used path so probably not worth it.  */
- dest -= stride[n] * extent[n];
+ PTR_DECREMENT_BYTES (dest, stride[n] * extent[n]);
  n++;
  if (n == dim)
{
@@ -1134,7 +1134,7 @@ arandom_m4 (gfc_array_m4 *x)
  count[n] = 0;
  /* We could precalculate these products, but this is a less
 frequently used path so probably not worth it.  */
- dest -= stride[n] * extent[n];
+ PTR_DECREMENT_BYTES (dest, stride[n] * extent[n]);
  n++;
  if (n == dim)
{
@@ -1199,7 +1199,7 @@ arandom_m8 (gfc_array_m8 *x)
  count[n] = 0;
  /* We could precalculate these products, but this is a less
 frequently used path so probably not worth it.  */
- dest -= stride[n] * extent[n];
+ PTR_DECREMENT_BYTES (dest, stride[n] * extent[n]);
  n++;
  if (n == dim)
{
@@ -1266,7 +1266,7 @@ arandom_m16 (gfc_array_m16 *x)
  count[n] = 0;
  /* We could precalculate these products, but this is a less
 frequently used path so probably not worth it.  */
- dest -= stride[n] * exten

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Refactor set_dimension_fields descriptor_init_count

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:a54c389f9eac340ac6683595903a1de9e4b35b6e

commit a54c389f9eac340ac6683595903a1de9e4b35b6e
Author: Mikael Morin 
Date:   Sat Aug 16 19:16:15 2025 +0200

Refactor set_dimension_fields descriptor_init_count

Correction régression class_allocate_22

Ajout scan tree var

Correction dumps coarray_12

Diff:
---
 gcc/fortran/trans-descriptor.cc  | 18 +++-
 gcc/testsuite/gfortran.dg/coarray_12.f90 |  3 +-
 gcc/testsuite/lib/scandump.exp   | 50 
 gcc/testsuite/lib/scantree.exp   | 26 +
 4 files changed, 82 insertions(+), 15 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 071840f0e871..1b08120e74a3 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -2816,15 +2816,8 @@ gfc_descriptor_init_count (tree descriptor, int rank, 
int corank,
  ubound = lower[n];
}
}
-  gfc_conv_descriptor_lbound_set (descriptor_block, descriptor,
- gfc_rank_cst[n], se.expr);
   conv_lbound = se.expr;
-
-  /* Work out the offset for this component.  */
-  tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
-se.expr, stride);
-  offset = fold_build2_loc (input_location, MINUS_EXPR,
-   gfc_array_index_type, offset, tmp);
+  conv_lbound = gfc_evaluate_now (conv_lbound, pblock);
 
   /* Set upper bound.  */
   gfc_init_se (&se, NULL);
@@ -2860,13 +2853,11 @@ gfc_descriptor_init_count (tree descriptor, int rank, 
int corank,
  if (ubound->expr_type == EXPR_FUNCTION)
se.expr = gfc_evaluate_now (se.expr, pblock);
}
-  gfc_conv_descriptor_ubound_set (descriptor_block, descriptor,
- gfc_rank_cst[n], se.expr);
   conv_ubound = se.expr;
+  conv_ubound = gfc_evaluate_now (conv_ubound, pblock);
 
-  /* Store the stride.  */
-  gfc_conv_descriptor_stride_set (descriptor_block, descriptor,
- gfc_rank_cst[n], stride);
+  set_dimension_fields (descriptor_block, descriptor, gfc_rank_cst[n],
+   conv_lbound, conv_ubound, stride, &offset);
 
   /* Calculate size and check whether extent is negative.  */
   size = gfc_conv_array_extent_dim (conv_lbound, conv_ubound, &empty_cond);
@@ -2950,7 +2941,6 @@ gfc_descriptor_init_count (tree descriptor, int rank, int 
corank,
 return gfc_index_one_node;
 
   /* Update the array descriptor with the offset and the span.  */
-  offset = gfc_evaluate_now (offset, pblock);
   gfc_conv_descriptor_offset_set (descriptor_block, descriptor, offset);
   tmp = fold_convert (gfc_array_index_type, element_size);
   gfc_conv_descriptor_span_set (descriptor_block, descriptor, tmp);
diff --git a/gcc/testsuite/gfortran.dg/coarray_12.f90 
b/gcc/testsuite/gfortran.dg/coarray_12.f90
index 70efaaff5160..9bbb9e3a3035 100644
--- a/gcc/testsuite/gfortran.dg/coarray_12.f90
+++ b/gcc/testsuite/gfortran.dg/coarray_12.f90
@@ -46,7 +46,8 @@ end subroutine testAlloc5
 
 
 ! { dg-final { scan-tree-dump-times "a.dim.0..lbound = 1;" 1 "original" } }
-! { dg-final { scan-tree-dump-times "a.dim.0..ubound = .*nn;" 1 "original" } }
+! { dg-final { global ubound_value; scan-tree-dump-var {a\.dim\[0\]\.ubound = 
(D\.\d+);} "original" "ubound_value" } }
+! { dg-final { global ubound_value; scan-tree-dump-times "$ubound_value = 
.*nn;" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "a.dim.1..lbound = 1;" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "a.dim.1..ubound = .*mm;" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "a.dim.2..lbound = 1;" 1 "original" } }
diff --git a/gcc/testsuite/lib/scandump.exp b/gcc/testsuite/lib/scandump.exp
index a8441daa22fa..74a77f0a57e1 100644
--- a/gcc/testsuite/lib/scandump.exp
+++ b/gcc/testsuite/lib/scandump.exp
@@ -214,6 +214,56 @@ proc scan-dump-not { args } {
 }
 }
 
+# Utility for scanning compiler result, invoked via dg-final.
+# Call pass if pattern is present, otherwise fail.
+#
+# Argument 0 is the type of dump we are searching (rtl, tree, ipa)
+# Argument 1 is the regexp to match.
+# Argument 2 is the suffix for the dump file
+# Argument 3 is the suffix of the dump base
+# Argument 4 is the variable name to store the matched content
+# Argument 5 handles expected failures and the like
+proc scan-dump-var { args } {
+
+if { [llength $args] >= 6 } {
+switch [dg-process-target [lindex $args 5]] {
+"S" { }
+"N" { return }
+"F" { setup_xfail "*-*-*" }
+"P" { }
+}
+}
+
+set testcase [testname-for-summary]
+# The name might include a list of options; extract the file name.
+set filename [lindex $testcase 0]
+
+set printable_pattern [make_pattern_printable [li

[gcc(refs/users/meissner/heads/work221-sha)] PR target/117251: Improve vector and to vector nor fusion

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:2988d5aaa8c2f850e2fadef7f47fc74f57104d32

commit 2988d5aaa8c2f850e2fadef7f47fc74f57104d32
Author: Michael Meissner 
Date:   Mon Sep 8 15:41:28 2025 -0400

PR target/117251: Improve vector and to vector nor fusion

See the following post for a complete explanation of what the patches
for PR target/117251:

 * https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686474.html

This is patch #34 of 45 to generate the 'XXEVAL' instruction on power10
and power11 instead of using the Altivec 'VAND' instruction feeding
into 'VNOR'.  The 'XXEVAL' instruction can use all 64 vector registers,
instead of the 32 registers that traditional Altivec vector
instructions use.  By allowing all of the vector registers to be used,
it reduces the amount of spilling that a large benchmark generated.

Currently the following code:

vector int a, b, c, d;
a = ~ ((c & d) | b);

Generates:

vand   t,c,d
vnor   a,t,b

Now in addition with this patch, if the arguments or result is
allocated to a traditional FPR register, the GCC compiler will now
generate the following code instead of adding vector move instructions:

xxeval a,b,c,224

Since fusion using 2 Altivec instructions is slightly faster than using
the 'XXEVAL' instruction we prefer to generate the Altivec instructions
if we can.  In addition, because 'XXEVAL' is a prefixed instruction, it
possibly might generate an extra NOP instruction to align the 'XXEVAL'
instruction.

I have tested these patches on both big endian and little endian
PowerPC servers, with no regressions.  Can I check these patchs into
the trunk?

2025-09-08  Michael Meissner  

gcc/

PR target/117251
* config/rs6000/fusion.md: Regenerate.
* config/rs6000/genfusion.pl (gen_logical_addsubf): Add support
to generate vector and => nor fusion if XXEVAL is supported.

Diff:
---
 gcc/config/rs6000/fusion.md| 15 +--
 gcc/config/rs6000/genfusion.pl |  1 +
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
index e3d9f7376a8d..68b52d4f5893 100644
--- a/gcc/config/rs6000/fusion.md
+++ b/gcc/config/rs6000/fusion.md
@@ -2480,20 +2480,23 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vand -> vnor
 (define_insn "*fuse_vand_vnor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-(and:VM (not:VM (and:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-  (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
- (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+(and:VM (not:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+  (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+ (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
vand %3,%1,%0\;vnor %3,%3,%2
vand %3,%1,%0\;vnor %3,%3,%2
vand %3,%1,%0\;vnor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,224
vand %4,%1,%0\;vnor %3,%4,%2"
   [(set_attr "type" "fused_vector")
(set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vandc -> vnor
diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index 3a603eb09675..56e5d96ec5f3 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -248,6 +248,7 @@ sub gen_logical_addsubf
   "vorc_vor"=> 191,
   "vandc_vnor"  => 208,
   "vandc_veqv"  => 210,
+  "vand_vnor"   => 224,
 );
 
 KIND: foreach $kind ('scalar','vector') {


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction gfc_copy_descriptor

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:a79b1e796eb8b63b2d41f58d3032697cd7a7ee86

commit a79b1e796eb8b63b2d41f58d3032697cd7a7ee86
Author: Mikael Morin 
Date:   Thu Jul 31 20:42:28 2025 +0200

Extraction gfc_copy_descriptor

Diff:
---
 gcc/fortran/trans-descriptor.cc | 24 
 gcc/fortran/trans-descriptor.h  |  1 +
 gcc/fortran/trans-expr.cc   | 23 +++
 3 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 7fcd8a8bb207..66fa9d57b725 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -1305,6 +1305,30 @@ gfc_copy_descriptor (stmtblock_t *block, tree dest, tree 
src,
 }
 
 
+void
+gfc_copy_descriptor (stmtblock_t *block, tree dest, tree src, bool lhs_type)
+{
+  gfc_conv_descriptor_data_set (block, dest,
+   gfc_conv_descriptor_data_get (src));
+  gfc_conv_descriptor_offset_set (block, dest,
+ gfc_conv_descriptor_offset_get (src));
+
+  gfc_conv_descriptor_dtype_set (block, dest,
+gfc_conv_descriptor_dtype_get (src));
+
+  /* Assign the dimension as range-ref.  */
+  tree tmp = gfc_get_descriptor_dimension (dest);
+  tree tmp2 = gfc_get_descriptor_dimension (src);
+
+  tree type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
+  tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
+   gfc_index_zero_node, NULL_TREE, NULL_TREE);
+  tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
+gfc_index_zero_node, NULL_TREE, NULL_TREE);
+  gfc_add_modify (block, tmp, tmp2);
+}
+
+
 void
 gfc_copy_descriptor (stmtblock_t *block, tree dest, tree src, tree ptr,
 int rank, gfc_ss *ss)
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index ab4d1755132a..44f6d51dc6cd 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -110,6 +110,7 @@ void gfc_shift_descriptor (stmtblock_t *, tree, int, tree 
[GFC_MAX_DIMENSIONS],
 void gfc_copy_sequence_descriptor (stmtblock_t *, tree, tree, int);
 void gfc_copy_descriptor (stmtblock_t *, tree, tree, gfc_expr *, bool);
 void gfc_copy_descriptor (stmtblock_t *, tree, tree, tree, int, gfc_ss *);
+void gfc_copy_descriptor (stmtblock_t *, tree, tree, bool);
 
 void gfc_set_descriptor_from_scalar_class (stmtblock_t *, tree, tree, gfc_expr 
*);
 void gfc_set_descriptor_from_scalar (stmtblock_t *, tree, tree, 
symbol_attribute,
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 9b8d10dc968f..72341a8b9ae9 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -760,32 +760,15 @@ gfc_get_vptr_from_expr (tree expr)
   return NULL_TREE;
 }
 
+
 void
 gfc_class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
 bool lhs_type)
 {
-  tree tmp, tmp2, type;
-
-  gfc_conv_descriptor_data_set (block, lhs_desc,
-   gfc_conv_descriptor_data_get (rhs_desc));
-  gfc_conv_descriptor_offset_set (block, lhs_desc,
- gfc_conv_descriptor_offset_get (rhs_desc));
-
-  gfc_conv_descriptor_dtype_set (block, lhs_desc,
-gfc_conv_descriptor_dtype_get (rhs_desc));
-
-  /* Assign the dimension as range-ref.  */
-  tmp = gfc_get_descriptor_dimension (lhs_desc);
-  tmp2 = gfc_get_descriptor_dimension (rhs_desc);
-
-  type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
-  tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
-   gfc_index_zero_node, NULL_TREE, NULL_TREE);
-  tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
-gfc_index_zero_node, NULL_TREE, NULL_TREE);
-  gfc_add_modify (block, tmp, tmp2);
+  gfc_copy_descriptor (block, lhs_desc, rhs_desc, lhs_type);
 }
 
+
 /* Takes a derived type expression and returns the address of a temporary
class object of the 'declared' type.  If opt_vptr_src is not NULL, this is
used for the temporary class object.


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction gfc_set_descriptor

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:f1bc70e891099b9cdbaaba8af0cf95d27b3ddc9f

commit f1bc70e891099b9cdbaaba8af0cf95d27b3ddc9f
Author: Mikael Morin 
Date:   Sun Jul 20 17:25:26 2025 +0200

Extraction gfc_set_descriptor

Correction bootstsrap

Diff:
---
 gcc/fortran/trans-array.cc  | 163 +-
 gcc/fortran/trans-descriptor.cc | 170 
 gcc/fortran/trans-descriptor.h  |   8 ++
 3 files changed, 181 insertions(+), 160 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index c1bad7057af5..65f80c4dd9fd 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -7780,7 +7780,6 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
   tree tmp;
   tree desc;
   stmtblock_t block;
-  tree start;
   int full;
   bool subref_array_target = false;
   bool deferred_array_component = false;
@@ -8086,12 +8085,6 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
   int dim, ndim, codim;
   tree parm;
   tree parmtype;
-  tree dtype;
-  tree stride;
-  tree from;
-  tree to;
-  tree base;
-  tree offset;
 
   ndim = info->ref ? info->ref->u.ar.dimen : ss->dimen;
 
@@ -8212,160 +8205,10 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
  gfc_get_array_span (desc, expr)));
}
 
-  /* Set the span field.  */
-  tmp = NULL_TREE;
-  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
-   tmp = gfc_conv_descriptor_span_get (desc);
-  else
-   tmp = gfc_get_array_span (desc, expr);
-  if (tmp)
-   gfc_conv_descriptor_span_set (&loop.pre, parm, tmp);
-
-  /* The following can be somewhat confusing.  We have two
- descriptors, a new one and the original array.
- {parm, parmtype, dim} refer to the new one.
- {desc, type, n, loop} refer to the original, which maybe
- a descriptorless array.
- The bounds of the scalarization are the bounds of the section.
- We don't have to worry about numeric overflows when calculating
- the offsets because all elements are within the array data.  */
-
-  /* Set the dtype.  */
-  if (se->unlimited_polymorphic)
-   dtype = gfc_get_dtype (TREE_TYPE (desc), &loop.dimen);
-  else if (expr->ts.type == BT_ASSUMED)
-   {
- tree tmp2 = desc;
- if (DECL_LANG_SPECIFIC (tmp2) && GFC_DECL_SAVED_DESCRIPTOR (tmp2))
-   tmp2 = GFC_DECL_SAVED_DESCRIPTOR (tmp2);
- if (POINTER_TYPE_P (TREE_TYPE (tmp2)))
-   tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
- dtype = gfc_conv_descriptor_dtype_get (tmp2);
-   }
-  else
-   dtype = gfc_get_dtype (parmtype);
-  gfc_conv_descriptor_dtype_set (&loop.pre, parm, dtype);
-
-  /* The 1st element in the section.  */
-  base = gfc_index_zero_node;
-  if (expr->ts.type == BT_CHARACTER && expr->rank == 0 && codim)
-   base = gfc_index_one_node;
-
-  /* The offset from the 1st element in the section.  */
-  offset = gfc_index_zero_node;
-
-  for (n = 0; n < ndim; n++)
-   {
- stride = gfc_conv_array_stride (desc, n);
-
- /* Work out the 1st element in the section.  */
- if (info->ref
- && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
-   {
- gcc_assert (info->subscript[n]
- && info->subscript[n]->info->type == GFC_SS_SCALAR);
- start = info->subscript[n]->info->data.scalar.value;
-   }
- else
-   {
- /* Evaluate and remember the start of the section.  */
- start = info->start[n];
- stride = gfc_evaluate_now (stride, &loop.pre);
-   }
-
- tmp = gfc_conv_array_lbound (desc, n);
- tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp),
-start, tmp);
- tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
-tmp, stride);
- base = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
-   base, tmp);
-
- if (info->ref
- && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
-   {
- /* For elemental dimensions, we only need the 1st
-element in the section.  */
- continue;
-   }
-
- /* Vector subscripts need copying and are handled elsewhere.  */
- if (info->ref)
-   gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
-
- /* look for the corresponding scalarizer dimension: dim.  */
- for (dim = 0; dim < ndim; dim++)
-   if (ss->dim[dim] == n)
- break;
-
- /* loop exited early: the DIM being looked for has been found.  */
- gcc_assert (dim < ndim);
+  gfc_set_descriptor (&loop.pre, parm, desc, expr, loop.dimen

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction set_descriptor_with_shape

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:616fc48e8ef5bcc318f472f2219e0e045a1ff055

commit 616fc48e8ef5bcc318f472f2219e0e045a1ff055
Author: Mikael Morin 
Date:   Sun Aug 17 19:28:04 2025 +0200

Extraction set_descriptor_with_shape

Diff:
---
 gcc/fortran/trans-descriptor.cc | 110 
 gcc/fortran/trans-descriptor.h  |   4 +-
 gcc/fortran/trans-intrinsic.cc  | 107 ++
 3 files changed, 117 insertions(+), 104 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 761eb57e4ea2..60cb6f1b9798 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -1676,3 +1676,113 @@ gfc_set_contiguous_descriptor (stmtblock_t *block, tree 
desc, tree size,
  gfc_index_zero_node, size);
   gfc_conv_descriptor_data_set (block, desc, data_ptr);
 }
+
+
+void
+gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, tree ptr,
+  gfc_expr *shape, gfc_expr *lower, locus *where)
+{
+  /* Set the span field.  */
+  tree tmp = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
+  tmp = fold_convert (gfc_array_index_type, tmp);
+  gfc_conv_descriptor_span_set (block, desc, tmp);
+
+  /* Set data value, dtype, and offset.  */
+  tmp = GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc));
+  gfc_conv_descriptor_data_set (block, desc, fold_convert (tmp, ptr));
+  gfc_conv_descriptor_dtype_set (block, desc,
+gfc_get_dtype (TREE_TYPE (desc)));
+
+  /* Start scalarization of the bounds, using the shape argument.  */
+
+  gfc_ss *shape_ss = gfc_walk_expr (shape);
+  gcc_assert (shape_ss != gfc_ss_terminator);
+  gfc_se shapese, lowerse;
+  gfc_init_se (&shapese, nullptr);
+  gfc_ss *lower_ss = nullptr;
+  if (lower)
+{
+  lower_ss = gfc_walk_expr (lower);
+  gcc_assert (lower_ss != gfc_ss_terminator);
+  gfc_init_se (&lowerse, nullptr);
+}
+
+  gfc_loopinfo loop;
+  gfc_init_loopinfo (&loop);
+  gfc_add_ss_to_loop (&loop, shape_ss);
+  if (lower)
+gfc_add_ss_to_loop (&loop, lower_ss);
+  gfc_conv_ss_startstride (&loop);
+  gfc_conv_loop_setup (&loop, where);
+  gfc_mark_ss_chain_used (shape_ss, 1);
+  if (lower)
+gfc_mark_ss_chain_used (lower_ss, 1);
+
+  gfc_copy_loopinfo_to_se (&shapese, &loop);
+  shapese.ss = shape_ss;
+  if (lower)
+{
+  gfc_copy_loopinfo_to_se (&lowerse, &loop);
+  lowerse.ss = lower_ss;
+}
+
+  tree stride = gfc_create_var (gfc_array_index_type, "stride");
+  tree offset = gfc_create_var (gfc_array_index_type, "offset");
+  gfc_add_modify (block, stride, gfc_index_one_node);
+  gfc_add_modify (block, offset, gfc_index_zero_node);
+
+  /* Loop body.  */
+  stmtblock_t body;
+  gfc_start_scalarized_body (&loop, &body);
+
+  tree dim = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+ loop.loopvar[0], loop.from[0]);
+
+  tree lbound;
+  if (lower)
+{
+  gfc_conv_expr (&lowerse, lower);
+  gfc_add_block_to_block (&body, &lowerse.pre);
+  lbound = fold_convert (gfc_array_index_type, lowerse.expr);
+  gfc_add_block_to_block (&body, &lowerse.post);
+}
+  else
+lbound = gfc_index_one_node;
+
+  /* Set bounds and stride.  */
+  gfc_conv_descriptor_lbound_set (&body, desc, dim, lbound);
+  gfc_conv_descriptor_stride_set (&body, desc, dim, stride);
+
+  gfc_conv_expr (&shapese, shape);
+  gfc_add_block_to_block (&body, &shapese.pre);
+  tree ubound = fold_build2_loc (
+input_location, MINUS_EXPR, gfc_array_index_type,
+fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, lbound,
+fold_convert (gfc_array_index_type, shapese.expr)),
+gfc_index_one_node);
+  gfc_conv_descriptor_ubound_set (&body, desc, dim, ubound);
+  gfc_add_block_to_block (&body, &shapese.post);
+
+  /* Calculate offset.  */
+  tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
+stride, lbound);
+  gfc_add_modify (&body, offset,
+ fold_build2_loc (input_location, PLUS_EXPR,
+  gfc_array_index_type, offset, tmp));
+
+  /* Update stride.  */
+  gfc_add_modify (
+&body, stride,
+fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, stride,
+fold_convert (gfc_array_index_type, shapese.expr)));
+  /* Finish scalarization loop.  */
+  gfc_trans_scalarizing_loops (&loop, &body);
+  gfc_add_block_to_block (block, &loop.pre);
+  gfc_add_block_to_block (block, &loop.post);
+  gfc_cleanup_loop (&loop);
+
+  gfc_add_modify (block, offset,
+ fold_build1_loc (input_location, NEGATE_EXPR,
+  gfc_array_index_type, offset));
+  gfc_conv_descriptor_offset_set (block, desc, offset);
+}
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index e945d8e884f0..c477e65de0d6 100644
--- a/gcc/fortran/tra

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Déroulement boucle set_gfc_from_cfi

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:a15a4f5c622d56b71ea05745c2f798eef4665f7c

commit a15a4f5c622d56b71ea05745c2f798eef4665f7c
Author: Mikael Morin 
Date:   Fri Aug 15 15:42:37 2025 +0200

Déroulement boucle set_gfc_from_cfi

Diff:
---
 gcc/fortran/trans-descriptor.cc | 78 ++---
 1 file changed, 42 insertions(+), 36 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index d6fe1fc91c01..a26a3b2b01a9 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -2042,26 +2042,6 @@ gfc_set_gfc_from_cfi (stmtblock_t *block, stmtblock_t 
*block2, tree gfc_desc,
   tree offset = gfc_create_var (gfc_array_index_type, "offset");
   gfc_add_modify (block2, offset, gfc_index_zero_node);
 
-  if (sym->as->rank > 0 && !sym->attr.pointer && !sym->attr.allocatable)
-for (int i = 0; i < sym->as->rank; ++i)
-  {
-   gfc_se se;
-   gfc_init_se (&se, NULL );
-   if (sym->as->lower[i])
- {
-   gfc_conv_expr (&se, sym->as->lower[i]);
-   tmp = se.expr;
- }
-   else
- tmp = gfc_index_one_node;
-   gfc_add_block_to_block (block2, &se.pre);
-   gfc_conv_descriptor_lbound_set (block2, gfc_desc, gfc_rank_cst[i], tmp);
-   gfc_add_block_to_block (block2, &se.post);
-  }
-
-  /* Loop: for (i = 0; i < rank; ++i).  */
-  tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
-
   /* Stride  */
   tree stride;
   if (do_copy_inout)
@@ -2069,25 +2049,51 @@ gfc_set_gfc_from_cfi (stmtblock_t *block, stmtblock_t 
*block2, tree gfc_desc,
   else
 stride = NULL_TREE;
 
-  /* Loop body.  */
-  stmtblock_t loop_body;
-  gfc_init_block (&loop_body);
-  /* gfc->dim[i].lbound = ... */
-  tree lbound;
-  if (sym->attr.pointer || sym->attr.allocatable)
-lbound = gfc_get_cfi_dim_lbound (cfi, idx);
-  else if (sym->as->rank < 0)
-lbound = gfc_index_one_node;
+  if (sym->as->rank > 0 && !sym->attr.pointer && !sym->attr.allocatable)
+{
+  for (int i = 0; i < sym->as->rank; ++i)
+   {
+ gfc_se se;
+ gfc_init_se (&se, NULL );
+ if (sym->as->lower[i])
+   {
+ gfc_conv_expr (&se, sym->as->lower[i]);
+ tmp = se.expr;
+   }
+ else
+   tmp = gfc_index_one_node;
+ gfc_add_block_to_block (block2, &se.pre);
+ tree lbound = gfc_evaluate_now (tmp, block2);
+ gfc_add_block_to_block (block2, &se.post);
+ set_gfc_dimension_from_cfi (block2, gfc_desc, cfi, gfc_rank_cst[i],
+ lbound, offset, stride, do_copy_inout);
+   }
+}
   else
-lbound = gfc_conv_descriptor_lbound_get (gfc_desc, idx);
+{
+  /* Loop: for (i = 0; i < rank; ++i).  */
+  tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
 
-  set_gfc_dimension_from_cfi (&loop_body, gfc_desc, cfi, idx, lbound, offset,
- stride, do_copy_inout);
+  /* Loop body.  */
+  stmtblock_t loop_body;
+  gfc_init_block (&loop_body);
+  /* gfc->dim[i].lbound = ... */
+  tree lbound;
+  if (sym->attr.pointer || sym->attr.allocatable)
+   lbound = gfc_get_cfi_dim_lbound (cfi, idx);
+  else if (sym->as->rank < 0)
+   lbound = gfc_index_one_node;
+  else
+   gcc_unreachable ();
 
-  /* Generate loop.  */
-  gfc_simple_for_loop (block2, idx, build_zero_cst (TREE_TYPE (idx)),
-  rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
-  gfc_finish_block (&loop_body));
+  set_gfc_dimension_from_cfi (&loop_body, gfc_desc, cfi, idx, lbound, 
offset,
+ stride, do_copy_inout);
+
+  /* Generate loop.  */
+  gfc_simple_for_loop (block2, idx, build_zero_cst (TREE_TYPE (idx)),
+  rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
+  gfc_finish_block (&loop_body));
+}
 
   gfc_conv_descriptor_offset_set (block2, gfc_desc, offset);
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction gfc_set_gfc_from_cfi

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:be565a7a832f44d519574651565b2292a008

commit be565a7a832f44d519574651565b2292a008
Author: Mikael Morin 
Date:   Tue Jul 22 12:17:50 2025 +0200

Extraction gfc_set_gfc_from_cfi

Diff:
---
 gcc/fortran/trans-descriptor.cc | 99 +
 gcc/fortran/trans-descriptor.h  |  3 ++
 gcc/fortran/trans-expr.cc   | 92 +-
 3 files changed, 103 insertions(+), 91 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 28031526ad76..c8352f46c6c7 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -1793,3 +1793,102 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree 
desc, tree ptr,
   gfc_array_index_type, offset));
   gfc_conv_descriptor_offset_set (block, desc, offset);
 }
+
+
+void
+gfc_set_gfc_from_cfi (stmtblock_t *block, tree gfc, gfc_expr *e, tree rank,
+ tree gfc_strlen, tree cfi, gfc_symbol *fsym)
+{
+  stmtblock_t block2;
+  gfc_init_block (&block2);
+  if (e->rank == 0)
+{
+  tree tmp = gfc_get_cfi_desc_base_addr (cfi);
+  gfc_add_modify (block, gfc, fold_convert (TREE_TYPE (gfc), tmp));
+}
+  else
+{
+  tree tmp = gfc_get_cfi_desc_base_addr (cfi);
+  gfc_conv_descriptor_data_set (block, gfc, tmp);
+
+  if (fsym->attr.allocatable)
+   {
+ /* gfc->span = cfi->elem_len.  */
+ tmp = fold_convert (gfc_array_index_type,
+ gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]));
+   }
+  else
+   {
+ /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len)
+ ? cfi->dim[0].sm : cfi->elem_len).  */
+ tmp = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]);
+ tree tmp2 = fold_convert (gfc_array_index_type,
+   gfc_get_cfi_desc_elem_len (cfi));
+ tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
+gfc_array_index_type, tmp, tmp2);
+ tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
+tmp, gfc_index_zero_node);
+ tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, 
tmp,
+   gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]), tmp2);
+   }
+  gfc_conv_descriptor_span_set (&block2, gfc, tmp);
+
+  /* Calculate offset + set lbound, ubound and stride.  */
+  gfc_conv_descriptor_offset_set (&block2, gfc, gfc_index_zero_node);
+  /* Loop: for (i = 0; i < rank; ++i).  */
+  tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
+  /* Loop body.  */
+  stmtblock_t loop_body;
+  gfc_init_block (&loop_body);
+  /* gfc->dim[i].lbound = ... */
+  tmp = gfc_get_cfi_dim_lbound (cfi, idx);
+  gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp);
+
+  /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+gfc_conv_descriptor_lbound_get (gfc, idx),
+gfc_index_one_node);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+gfc_get_cfi_dim_extent (cfi, idx), tmp);
+  gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp);
+
+  /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
+  tmp = gfc_get_cfi_dim_sm (cfi, idx);
+  tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
+gfc_array_index_type, tmp,
+fold_convert (gfc_array_index_type,
+  gfc_get_cfi_desc_elem_len (cfi)));
+  gfc_conv_descriptor_stride_set (&loop_body, gfc, idx, tmp);
+
+  /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
+  tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
+gfc_conv_descriptor_stride_get (gfc, idx),
+gfc_conv_descriptor_lbound_get (gfc, idx));
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+gfc_conv_descriptor_offset_get (gfc), tmp);
+  gfc_conv_descriptor_offset_set (&loop_body, gfc, tmp);
+  /* Generate loop.  */
+  gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
+  rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
+  gfc_finish_block (&loop_body));
+}
+
+  if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
+{
+  tree tmp = fold_convert (gfc_charlen_type_node,
+  gfc_get_cfi_desc_elem_len (cfi));
+  if (e->ts.kind != 1)
+   tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
+  gfc_charlen_type_node, tmp,
+  buil

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Calcul offset sans passer par le descripteur

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:eca4e7206cae71925ee023879a19b8b11eb3dacc

commit eca4e7206cae71925ee023879a19b8b11eb3dacc
Author: Mikael Morin 
Date:   Sat Aug 16 16:17:52 2025 +0200

Calcul offset sans passer par le descripteur

Diff:
---
 gcc/fortran/trans-descriptor.cc | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index ae387b684e8c..c0961ee1ab89 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -1425,7 +1425,7 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, 
int dest_rank,
 
   /* Copy offset but adjust it such that it would correspond
  to a lbound of zero.  */
-  gfc_conv_descriptor_offset_set (block, dest, gfc_index_zero_node);
+  tree offset = gfc_index_zero_node;
 
   /* Set the bounds as declared for the LHS and calculate strides as
  well as another offset update accordingly.  */
@@ -1476,17 +1476,15 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree 
dest, int dest_rank,
   gfc_conv_descriptor_stride_set (block, dest, gfc_rank_cst[dim], stride);
 
   /* Update offset.  */
-  tree offs = gfc_conv_descriptor_offset_get (dest);
   tree tmp = fold_build2_loc (input_location, MULT_EXPR,
  gfc_array_index_type, lbound, stride);
-  offs = fold_build2_loc (input_location, MINUS_EXPR,
- gfc_array_index_type, offs, tmp);
-  offs = gfc_evaluate_now (offs, block);
-  gfc_conv_descriptor_offset_set (block, dest, offs);
+  offset = fold_build2_loc (input_location, MINUS_EXPR,
+   gfc_array_index_type, offset, tmp);
 
   /* Update stride.  */
   tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
   stride = fold_build2_loc (input_location, MULT_EXPR,
gfc_array_index_type, stride, tmp);
 }
+  gfc_conv_descriptor_offset_set (block, dest, offset);
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Factorisation gfc_set_contiguous_descriptor

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:973ef63a1220686e93ee0aac23e95989f914

commit 973ef63a1220686e93ee0aac23e95989f914
Author: Mikael Morin 
Date:   Fri Jan 17 17:25:59 2025 +0100

Factorisation gfc_set_contiguous_descriptor

Factorisation set_contiguous_array

Diff:
---
 gcc/fortran/trans-array.cc  | 54 +++--
 gcc/fortran/trans-descriptor.cc | 18 ++
 gcc/fortran/trans-descriptor.h  |  1 +
 3 files changed, 33 insertions(+), 40 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 65f80c4dd9fd..31ed8a7d3079 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -9466,32 +9466,6 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, 
tree dest,
  ubound = build_int_cst (gfc_array_index_type, 1);
}
 
- /* Treat strings like arrays.  Or the other way around, do not
-  * generate an additional array layer for scalar components.  */
- if (attr->dimension || c->ts.type == BT_CHARACTER)
-   {
- cdesc = gfc_get_array_type_bounds (tmp, 1, 0, &gfc_index_one_node,
-&ubound, 1,
-GFC_ARRAY_ALLOCATABLE, false);
-
- cdesc = gfc_create_var (cdesc, "cdesc");
- DECL_ARTIFICIAL (cdesc) = 1;
-
- gfc_conv_descriptor_dtype_set (&tmpblock, cdesc,
-gfc_get_dtype_rank_type (1, tmp));
- gfc_conv_descriptor_lbound_set (&tmpblock, cdesc,
- gfc_index_zero_node,
- gfc_index_one_node);
- gfc_conv_descriptor_stride_set (&tmpblock, cdesc,
- gfc_index_zero_node,
- gfc_index_one_node);
- gfc_conv_descriptor_ubound_set (&tmpblock, cdesc,
- gfc_index_zero_node, ubound);
-   }
- else
-   /* Prevent warning.  */
-   cdesc = NULL_TREE;
-
  if (attr->dimension)
{
  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)))
@@ -9514,13 +9488,23 @@ structure_alloc_comps (gfc_symbol * der_type, tree 
decl, tree dest,
  gfc_add_block_to_block (&tmpblock, &se.pre);
}
 
+ /* Treat strings like arrays.  Or the other way around, do not
+  * generate an additional array layer for scalar components.  */
  if (attr->dimension || c->ts.type == BT_CHARACTER)
-   gfc_conv_descriptor_data_set (&tmpblock, cdesc, comp);
+   {
+ cdesc = gfc_get_array_type_bounds (tmp, 1, 0, &gfc_index_one_node,
+&ubound, 1,
+GFC_ARRAY_ALLOCATABLE, false);
+
+ cdesc = gfc_create_var (cdesc, "cdesc");
+ DECL_ARTIFICIAL (cdesc) = 1;
+
+ gfc_set_contiguous_descriptor (&tmpblock, cdesc, ubound, comp);
+   }
  else
cdesc = comp;
 
  tree fndecl;
-
  fndecl = build_call_expr_loc (input_location,
gfor_fndecl_co_broadcast, 5,
gfc_build_addr_expr 
(pvoid_type_node,cdesc),
@@ -9668,21 +9652,11 @@ structure_alloc_comps (gfc_symbol * der_type, tree 
decl, tree dest,
  cdesc = gfc_create_var (cdesc, "cdesc");
  DECL_ARTIFICIAL (cdesc) = 1;
 
- gfc_conv_descriptor_dtype_set (&dealloc_block, cdesc,
-gfc_get_dtype_rank_type (1, tmp));
- gfc_conv_descriptor_lbound_set (&dealloc_block, cdesc,
- gfc_index_zero_node,
- gfc_index_one_node);
- gfc_conv_descriptor_stride_set (&dealloc_block, cdesc,
- gfc_index_zero_node,
- gfc_index_one_node);
- gfc_conv_descriptor_ubound_set (&dealloc_block, cdesc,
- gfc_index_zero_node, ubound);
-
  if (attr->dimension)
comp = gfc_conv_descriptor_data_get (comp);
 
- gfc_conv_descriptor_data_set (&dealloc_block, cdesc, comp);
+ gfc_set_contiguous_descriptor (&dealloc_block, cdesc, ubound,
+comp);
 
  /* Now call the deallocator.  */
  vtab = gfc_find_vtab (&c->ts);
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index ab2e33f87d83..761eb57e4ea2 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -1658,3 +1658,21 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree 
src, 

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Modification initialisation stride

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c4de21a09340c7fa959164ebf4531ab452fe2eb6

commit c4de21a09340c7fa959164ebf4531ab452fe2eb6
Author: Mikael Morin 
Date:   Sat Aug 16 15:42:30 2025 +0200

Modification initialisation stride

Revert "Suppression argument inutilisé"

This reverts commit eaf4e13d38467b15714bbc36a49bda4460ebabab.

Revert "Suppression warning argument inutilisé"

This reverts commit ff23b550241409fcd70380c28c82ef19fc47bc75.

Revert "Revert partiel initialisation stride"

This reverts commit 0af062cb83c70fea79c98f76ca45b13376e567d7.

Diff:
---
 gcc/fortran/trans-descriptor.cc | 9 +++--
 gcc/fortran/trans-descriptor.h  | 2 +-
 gcc/fortran/trans-expr.cc   | 4 ++--
 3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 641874104fab..ae387b684e8c 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -1400,7 +1400,7 @@ gfc_copy_descriptor (stmtblock_t *block, tree dest, tree 
src, tree ptr,
 
 void
 gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, int dest_rank,
-  tree src, gfc_array_ref *ar)
+  tree src, bool contiguous_src, gfc_array_ref *ar)
 {
   /* Set dtype.  */
   gfc_conv_descriptor_dtype_set (block, dest,
@@ -1429,7 +1429,12 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree 
dest, int dest_rank,
 
   /* Set the bounds as declared for the LHS and calculate strides as
  well as another offset update accordingly.  */
-  tree stride = gfc_conv_descriptor_stride_get (src, gfc_rank_cst[0]);
+  tree stride;
+  if (contiguous_src)
+stride = gfc_index_one_node;
+  else
+stride = gfc_conv_descriptor_stride_get (src, gfc_rank_cst[0]);
+
   for (int dim = 0; dim < dest_rank; ++dim)
 {
   gfc_se lower_se;
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index c6a079036902..85926234f832 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -113,7 +113,7 @@ void gfc_copy_descriptor (stmtblock_t *, tree, tree, tree, 
int, gfc_ss *);
 void gfc_copy_descriptor (stmtblock_t *, tree, tree, bool);
 void gfc_copy_descriptor (stmtblock_t *, tree, tree, int);
 
-void gfc_conv_remap_descriptor (stmtblock_t *, tree, int, tree,
+void gfc_conv_remap_descriptor (stmtblock_t *, tree, int, tree, bool,
gfc_array_ref *);
 
 void gfc_set_descriptor_from_scalar_class (stmtblock_t *, tree, tree, gfc_expr 
*);
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 7196fd59c40c..536bbe543e8a 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -11066,8 +11066,8 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, 
gfc_expr * expr2)
  /* Do rank remapping.  We already have the RHS's descriptor
 converted in rse and now have to build the correct LHS
 descriptor for it.  */
- gfc_conv_remap_descriptor (&block, desc, expr1->rank,
-rse.expr, &remap->u.ar);
+ gfc_conv_remap_descriptor (&block, desc, expr1->rank, rse.expr,
+expr2->rank != 1, &remap->u.ar);
}
  else
/* Bounds remapping.  Just shift the lower bounds.  */


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Correction quotation macros m4

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:df00d010f4696f1fffc24c6fa9d3cb1d5161ec3b

commit df00d010f4696f1fffc24c6fa9d3cb1d5161ec3b
Author: Mikael Morin 
Date:   Mon Sep 8 14:41:36 2025 +0200

Correction quotation macros m4

Diff:
---
 libgfortran/m4/ifindloc0.m4 | 28 +++
 libgfortran/m4/ifindloc1.m4 | 22 +--
 libgfortran/m4/ifindloc2.m4 | 26 +++---
 libgfortran/m4/iforeach-s.m4| 26 +++---
 libgfortran/m4/iforeach-s2.m4   | 32 +--
 libgfortran/m4/iforeach.m4  | 40 -
 libgfortran/m4/ifunction-s.m4   | 34 ++--
 libgfortran/m4/ifunction-s2.m4  | 44 ++---
 libgfortran/m4/ifunction.m4 | 38 
 libgfortran/m4/ifunction_logical.m4 |  8 +++
 libgfortran/m4/iparm.m4 |  4 ++--
 libgfortran/m4/maxloc0.m4   | 12 +-
 libgfortran/m4/maxloc1.m4   | 12 +-
 libgfortran/m4/maxval.m4| 14 ++--
 libgfortran/m4/maxval1s.m4  |  4 ++--
 libgfortran/m4/minloc0.m4   |  6 ++---
 libgfortran/m4/minloc1.m4   | 20 -
 libgfortran/m4/minval.m4| 14 ++--
 18 files changed, 192 insertions(+), 192 deletions(-)

diff --git a/libgfortran/m4/ifindloc0.m4 b/libgfortran/m4/ifindloc0.m4
index 47f311f84d78..c484342f3cb9 100644
--- a/libgfortran/m4/ifindloc0.m4
+++ b/libgfortran/m4/ifindloc0.m4
@@ -79,7 +79,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 
   if (back)
 {
-  base = array->base_addr + (sz - 1) * 'base_mult`'`;
+  base = array->base_addr + (sz - 1) * 'base_mult`;
 
   while (1)
 {
@@ -92,7 +92,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 
  return;
}
- base -= sstride[0] * 'base_mult`'`;
+ base -= sstride[0] * 'base_mult`;
} while(++count[0] != extent[0]);
 
  n = 0;
@@ -103,14 +103,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
  count[n] = 0;
  /* We could precalculate these products, but this is a less
 frequently used path so probably not worth it.  */
- base += sstride[n] * extent[n] * 'base_mult`'`;
+ base += sstride[n] * extent[n] * 'base_mult`;
  n++;
  if (n >= rank)
return;
  else
{
  count[n]++;
- base -= sstride[n] * 'base_mult`'`;
+ base -= sstride[n] * 'base_mult`;
}
} while (count[n] == extent[n]);  
}
@@ -129,7 +129,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
  return;
}
- base += sstride[0] * 'base_mult`'`;
+ base += sstride[0] * 'base_mult`;
} while(++count[0] != extent[0]);
 
  n = 0;
@@ -140,14 +140,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
  count[n] = 0;
  /* We could precalculate these products, but this is a less
 frequently used path so probably not worth it.  */
- base -= sstride[n] * extent[n] * 'base_mult`'`;
+ base -= sstride[n] * extent[n] * 'base_mult`;
  n++;
  if (n >= rank)
return;
  else
{
  count[n]++;
- base += sstride[n] * 'base_mult`'`;
+ base += sstride[n] * 'base_mult`;
}
} while (count[n] == extent[n]);
}
@@ -228,7 +228,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
   if (back)
 {
-  base = array->base_addr + (sz - 1) * 'base_mult`'`;
+  base = array->base_addr + (sz - 1) * 'base_mult`;
   mbase = mbase + (sz - 1) * mask_kind;
   while (1)
 {
@@ -241,7 +241,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
  return;
}
- base -= sstride[0] * 'base_mult`'`;
+ base -= sstride[0] * 'base_mult`;
  mbase -= mstride[0];
} while(++count[0] != extent[0]);
 
@@ -253,7 +253,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
  count[n] = 0;
  /* We could precalculate these products, but this is a less
 frequently used path so probably not worth it.  */
- base += sstride[n] * extent[n] * 'base_mult`'`;
+ base += sstride[n] * extent[n] * 'base_mult`;
  mbase -= mstride[n] * extent[n];
  n++;
  if (n >= rank)
@@ -261,7 +261,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If 

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Refactor set_dimension_fields set_empty_descriptor

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:6b00d5f55c9d79937281c6e94cc629bbc81bebd8

commit 6b00d5f55c9d79937281c6e94cc629bbc81bebd8
Author: Mikael Morin 
Date:   Sat Aug 16 19:17:56 2025 +0200

Refactor set_dimension_fields set_empty_descriptor

Diff:
---
 gcc/fortran/trans-descriptor.cc | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 1b08120e74a3..9b296f17ed14 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -2952,15 +2952,10 @@ gfc_descriptor_init_count (tree descriptor, int rank, 
int corank,
 void
 gfc_set_empty_descriptor_bounds (stmtblock_t *block, tree descr, int rank)
 {
+  tree offset = gfc_index_zero_node;
   for (int n = 0; n < rank; n++)
-{
-  gfc_conv_descriptor_lbound_set (block, descr, gfc_rank_cst[n],
- gfc_index_one_node);
-  gfc_conv_descriptor_ubound_set (block, descr, gfc_rank_cst[n],
- gfc_index_zero_node);
-  gfc_conv_descriptor_stride_set (block, descr, gfc_rank_cst[n],
- gfc_index_zero_node);
-}
+set_dimension_fields (block, descr, gfc_rank_cst[n], gfc_index_one_node,
+ gfc_index_zero_node, gfc_index_zero_node, &offset);
 
   gfc_conv_descriptor_offset_set (block, descr, gfc_index_zero_node);
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Introduction gfc_conv_descriptor_extent_get

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:b9cb2239e58ba0191b0a1dce20a4c80bc2300556

commit b9cb2239e58ba0191b0a1dce20a4c80bc2300556
Author: Mikael Morin 
Date:   Sat Sep 6 16:34:11 2025 +0200

Introduction gfc_conv_descriptor_extent_get

Modif implémentation descriptor_extent_get

Correction motif bind_c_array_params_2

Ajout motif dump coarray_lock_7

Correction dump intrinsic_size_3

Mise à jour motif dump pr48636

Correction motif dump intrinsic_size_3

Correction motif dump bind_c_array_params_2

Correction motif dump coarray_lock_7

Diff:
---
 gcc/fortran/trans-array.cc | 20 ++---
 gcc/fortran/trans-decl.cc  |  6 +---
 gcc/fortran/trans-descriptor.cc| 34 +++---
 gcc/fortran/trans-descriptor.h |  1 +
 gcc/fortran/trans-expr.cc  |  9 ++
 gcc/fortran/trans-intrinsic.cc | 30 +--
 gcc/fortran/trans-openmp.cc| 34 --
 gcc/fortran/trans-stmt.cc  | 10 +++
 .../gfortran.dg/bind_c_array_params_2.f90  |  2 +-
 gcc/testsuite/gfortran.dg/coarray_lock_7.f90   |  4 +--
 gcc/testsuite/gfortran.dg/intrinsic_size_3.f90 |  2 +-
 gcc/testsuite/gfortran.dg/pr48636.f90  |  2 +-
 12 files changed, 46 insertions(+), 108 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 885f7440f3a2..92680c4b0fb0 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -7972,13 +7972,8 @@ gfc_tree_array_size (stmtblock_t *block, tree desc, 
gfc_expr *expr, tree dim)
 {
   if (!dim)
dim = gfc_index_zero_node;
-  tree ubound = gfc_conv_descriptor_ubound_get (desc, dim);
-  tree lbound = gfc_conv_descriptor_lbound_get (desc, dim);
 
-  size = fold_build2_loc (input_location, MINUS_EXPR,
- gfc_array_index_type, ubound, lbound);
-  size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
- size, gfc_index_one_node);
+  size = gfc_conv_descriptor_extent_get (desc, dim);
   /* if (!allocatable && !pointer && assumed rank)
   size = (idx == rank && ubound[rank-1] == -1 ? -1 : size;
 else
@@ -8039,11 +8034,7 @@ gfc_tree_array_size (stmtblock_t *block, tree desc, 
gfc_expr *expr, tree dim)
   cond = fold_build2_loc (input_location, TRUTH_AND_EXPR, 
boolean_type_node,
  cond, tmp);
 }
-  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-gfc_conv_descriptor_ubound_get (desc, idx),
-gfc_conv_descriptor_lbound_get (desc, idx));
-  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
-tmp, gfc_index_one_node);
+  tmp = gfc_conv_descriptor_extent_get (desc, idx);
   gfc_add_modify (&cond_block, extent, tmp);
   tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
 extent, gfc_index_zero_node);
@@ -8610,12 +8601,7 @@ gfc_full_array_size (stmtblock_t *block, tree decl, int 
rank)
 idx = gfc_conv_descriptor_rank_get (decl);
   else
 idx = gfc_rank_cst[rank - 1];
-  nelems = gfc_conv_descriptor_ubound_get (decl, idx);
-  tmp = gfc_conv_descriptor_lbound_get (decl, idx);
-  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-nelems, tmp);
-  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
-tmp, gfc_index_one_node);
+  tmp = gfc_conv_descriptor_extent_get (decl, idx);
   tmp = gfc_evaluate_now (tmp, block);
 
   nelems = gfc_conv_descriptor_stride_get (decl, idx);
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 9f5200f34d33..64ca5d76e6c8 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -7621,11 +7621,7 @@ done:
   gfc_add_modify (&loop_body, gfc_get_cfi_dim_lbound (cfi, idx),
  gfc_conv_descriptor_lbound_get (gfc_desc, idx));
   /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1.  */
-  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-gfc_conv_descriptor_ubound_get (gfc_desc, idx),
-gfc_conv_descriptor_lbound_get (gfc_desc, idx));
-  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, tmp,
-gfc_index_one_node);
+  tmp = gfc_conv_descriptor_extent_get (gfc_desc, idx);
   gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp);
   /* d->dim[n].sm = gfc->dim[i].stride  * gfc->span); */
   tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 9b296f17ed14..556a749fad

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Renseignement dtype initialisation statique

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:5f77e19d0e1fa23ee177cca7f3b7829b500956c9

commit 5f77e19d0e1fa23ee177cca7f3b7829b500956c9
Author: Mikael Morin 
Date:   Mon Aug 11 19:59:55 2025 +0200

Renseignement dtype initialisation statique

Diff:
---
 gcc/fortran/trans-descriptor.cc | 234 +++-
 gcc/fortran/trans-descriptor.h  |   2 +-
 2 files changed, 163 insertions(+), 73 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index a173530cbc70..d16127cf3ed7 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -727,7 +727,8 @@ enum descriptor_write_case
   POINTER_NULLIFY,
   RESULT_INIT,
   ABSENT_ARG_INIT,
-  STATIC_INIT
+  STATIC_INIT,
+  NONSTATIC_INIT
 };
 
 
@@ -797,6 +798,44 @@ struct descriptor_write
 };
 
 
+struct value_source
+{
+  const descriptor_write_case type;
+
+  union u
+  {
+struct nsi
+{
+  gfc_symbol * const sym;
+  gfc_expr * const expr;
+  tree string_length;
+
+  nsi (gfc_symbol *s, gfc_expr *e, tree sl)
+ : sym (s), expr (e), string_length (sl) {}
+}
+nonstatic_init;
+
+struct si
+{
+  gfc_symbol * const sym;
+
+  si (gfc_symbol *s) : sym (s) {}
+}
+static_init;
+
+u () {}
+u (gfc_symbol *s) : static_init (s) {}
+u (gfc_symbol *s, gfc_expr *e, tree sl) : nonstatic_init (s, e, sl) {}
+  }
+  u;
+
+  value_source (descriptor_write_case t) : type (t), u () {}
+  value_source (gfc_symbol *s) : type (STATIC_INIT), u (s) {}
+  value_source (gfc_symbol *s, gfc_expr *e, tree sl)
+  : type (NONSTATIC_INIT), u (s, e, sl) {}
+};
+
+
 static void
 set_descriptor_field (descriptor_write &dest, descriptor_field field, tree 
value)
 {
@@ -814,10 +853,117 @@ set_descriptor_field (descriptor_write &dest, 
descriptor_field field, tree value
 }
 
 
+static tree
+get_descriptor_data_value (const value_source &src)
+{
+  if (src.type == NONSTATIC_INIT)
+{
+  gfc_symbol *sym = src.u.nonstatic_init.sym;
+
+  symbol_attribute attr = gfc_symbol_attr (sym);
+  if (!attr.save
+ && (attr.allocatable
+ || (attr.pointer && (gfc_option.rtcheck & GFC_RTCHECK_POINTER
+   return null_pointer_node;
+  else
+   return NULL_TREE;
+}
+  else
+return null_pointer_node;
+}
+
+
+static tree
+get_descriptor_dtype_value (tree descr, const value_source &src)
+{
+  if (src.type == NONSTATIC_INIT)
+{
+  gfc_symbol *sym = src.u.nonstatic_init.sym;
+  gfc_expr *expr = src.u.nonstatic_init.expr;
+  tree string_length = src.u.nonstatic_init.string_length;
+
+  gfc_array_spec *as;
+  if (sym->ts.type == BT_CLASS)
+   as = CLASS_DATA (sym)->as;
+  else
+   as = sym->as;
+
+  int rank;
+  if (as == nullptr)
+   rank = 0;
+  else if (as->type != AS_ASSUMED_RANK)
+   rank = as->rank;
+  else if (expr)
+   rank = expr->rank;
+  else
+   rank = -1;
+
+  tree etype = gfc_get_element_type (TREE_TYPE (descr));
+  return gfc_get_dtype_rank_type_slen (rank, etype, string_length);
+}
+  else if (src.type == STATIC_INIT)
+{
+  gfc_symbol *sym = src.u.nonstatic_init.sym;
+
+  gfc_array_spec *as;
+  if (sym->ts.type == BT_CLASS)
+   as = CLASS_DATA (sym)->as;
+  else
+   as = sym->as;
+
+  int rank;
+  if (as == nullptr)
+   rank = 0;
+  else if (as->type != AS_ASSUMED_RANK)
+   rank = as->rank;
+  else
+   rank = -1;
+
+  tree etype = gfc_get_element_type (TREE_TYPE (descr));
+  return gfc_get_dtype_rank_type (rank, etype);
+}
+
+  return NULL_TREE;
+}
+
+
+static tree
+get_descriptor_offset_value (const value_source &src)
+{
+  if (src.type == NONSTATIC_INIT)
+{
+  gfc_symbol *sym = src.u.nonstatic_init.sym;
+
+  symbol_attribute attr = gfc_symbol_attr (sym);
+  if ((attr.allocatable
+  || attr.optional
+  || (attr.pointer && (gfc_option.rtcheck & GFC_RTCHECK_POINTER)))
+ && attr.codimension)
+   return null_pointer_node;
+}
+
+  return NULL_TREE;
+}
+
+
 static void
-set_descriptor (descriptor_write &dest)
+set_descriptor (descriptor_write &dest, const value_source &src)
 {
-  set_descriptor_field (dest, DATA_FIELD, null_pointer_node);
+  tree data_value = get_descriptor_data_value (src);
+  if (data_value != NULL_TREE)
+set_descriptor_field (dest, DATA_FIELD, data_value);
+
+  tree dtype_value = get_descriptor_dtype_value (dest.ref, src);
+  if (dtype_value != NULL_TREE)
+set_descriptor_field (dest, DTYPE_FIELD, dtype_value);
+
+  if (flag_coarray == GFC_FCOARRAY_LIB)
+{
+  tree offset_value = get_descriptor_offset_value (src);
+  if (offset_value != NULL_TREE)
+   set_descriptor_field (dest, OFFSET_FIELD, offset_value);
+}
+
   if (dest.type == descriptor_write::STATIC_INIT)
 {
   tree decl = dest.ref;
@@ -936,103 +1082,47 @@ void
 gfc_nullify_descriptor (stmtblock_t *block, tree de

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Refactoring nullifcations descripteur

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c877f3484854b0016d04865d8d170a6d04ab9da9

commit c877f3484854b0016d04865d8d170a6d04ab9da9
Author: Mikael Morin 
Date:   Sun Aug 10 18:30:59 2025 +0200

Refactoring nullifcations descripteur

Revert partiel

Diff:
---
 gcc/fortran/trans-descriptor.cc | 104 ++--
 1 file changed, 101 insertions(+), 3 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index ad07726d52bc..d0ef2baf9966 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -722,6 +722,103 @@ gfc_get_dtype_rank_type (int rank, tree etype)
 }
 
 
+class constructor_elements
+{
+  vec *values;
+  bool constant;
+
+public:
+  constructor_elements () : values (nullptr), constant (true) {}
+  void add_value (tree elt, tree val);
+  tree build (tree type);
+};
+
+
+void
+constructor_elements::add_value (tree elt, tree val)
+{
+  CONSTRUCTOR_APPEND_ELT (values, elt, val);
+  if (!TREE_CONSTANT (val))
+constant = false;
+}
+
+
+tree
+constructor_elements::build (tree type)
+{
+  tree cstr = build_constructor (type, values);
+  if (constant)
+TREE_CONSTANT (cstr) = 1;
+
+  return cstr;
+}
+
+
+struct write_destination
+{
+  enum write_type
+  {
+STATIC_INIT,
+REGULAR_ASSIGN
+  }
+  type;
+
+  tree ref;
+
+  union u
+  {
+struct rw
+{
+  stmtblock_t *block;
+
+  rw (stmtblock_t *b) : block(b) {}
+}
+regular_assign;
+
+constructor_elements static_init;
+
+u(stmtblock_t *block) : regular_assign (block) {}
+u() : static_init () {}
+  }
+  u;
+
+  write_destination (tree r, stmtblock_t *b)
+  : type (REGULAR_ASSIGN), ref (r), u (b) {}
+  write_destination (tree d) : type (STATIC_INIT), ref (d), u () {}
+};
+
+
+static void
+set_descriptor_field (write_destination &dest, descriptor_field field, tree 
value)
+{
+  if (dest.type == write_destination::STATIC_INIT)
+{
+  tree field_decl = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dest.ref)),
+  field);
+  dest.u.static_init.add_value (field_decl, value);
+}
+  else
+{
+  tree comp_ref = get_ref_comp (dest.ref, field);
+  set_value (dest.u.regular_assign.block, comp_ref, value);
+}
+}
+
+
+static void
+set_descriptor (write_destination &dest)
+{
+  set_descriptor_field (dest, DATA_FIELD, null_pointer_node);
+  if (dest.type == write_destination::STATIC_INIT)
+{
+  tree decl = dest.ref;
+  tree type = TREE_TYPE (decl);
+  tree cstr = dest.u.static_init.build (type);
+  DECL_INITIAL (decl) = cstr;
+}
+}
+
+
 /* Build a null array descriptor constructor.  */
 
 tree
@@ -829,21 +926,22 @@ gfc_conv_descriptor_cosize (tree desc, int rank, int 
corank)
 void
 gfc_nullify_descriptor (stmtblock_t *block, tree descr)
 {
-  gfc_conv_descriptor_data_set (block, descr, null_pointer_node); 
+  write_destination dest(descr, block);
+  set_descriptor (dest);
 }
 
 
 void
 gfc_init_descriptor_result (stmtblock_t *block, tree descr)
 {
-  gfc_conv_descriptor_data_set (block, descr, null_pointer_node);
+  gfc_nullify_descriptor (block, descr);
 }
 
 
 void
 gfc_init_absent_descriptor (stmtblock_t *block, tree descr)
 {
-  gfc_conv_descriptor_data_set (block, descr, null_pointer_node);
+  gfc_nullify_descriptor (block, descr);
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Refactoring descriptor_write

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:35ddc625836a82d312e678b1c820f560c00b9ef3

commit 35ddc625836a82d312e678b1c820f560c00b9ef3
Author: Mikael Morin 
Date:   Mon Aug 11 21:52:36 2025 +0200

Refactoring descriptor_write

Diff:
---
 gcc/fortran/trans-descriptor.cc | 31 ---
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index d0ef2baf9966..a173530cbc70 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -722,6 +722,15 @@ gfc_get_dtype_rank_type (int rank, tree etype)
 }
 
 
+enum descriptor_write_case
+{
+  POINTER_NULLIFY,
+  RESULT_INIT,
+  ABSENT_ARG_INIT,
+  STATIC_INIT
+};
+
+
 class constructor_elements
 {
   vec *values;
@@ -754,22 +763,22 @@ constructor_elements::build (tree type)
 }
 
 
-struct write_destination
+struct descriptor_write
 {
-  enum write_type
+  const enum write_type
   {
 STATIC_INIT,
 REGULAR_ASSIGN
   }
   type;
 
-  tree ref;
+  const tree ref;
 
   union u
   {
 struct rw
 {
-  stmtblock_t *block;
+  stmtblock_t * const block;
 
   rw (stmtblock_t *b) : block(b) {}
 }
@@ -782,16 +791,16 @@ struct write_destination
   }
   u;
 
-  write_destination (tree r, stmtblock_t *b)
+  descriptor_write (tree r, stmtblock_t *b)
   : type (REGULAR_ASSIGN), ref (r), u (b) {}
-  write_destination (tree d) : type (STATIC_INIT), ref (d), u () {}
+  descriptor_write (tree d) : type (STATIC_INIT), ref (d), u () {}
 };
 
 
 static void
-set_descriptor_field (write_destination &dest, descriptor_field field, tree 
value)
+set_descriptor_field (descriptor_write &dest, descriptor_field field, tree 
value)
 {
-  if (dest.type == write_destination::STATIC_INIT)
+  if (dest.type == descriptor_write::STATIC_INIT)
 {
   tree field_decl = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dest.ref)),
   field);
@@ -806,10 +815,10 @@ set_descriptor_field (write_destination &dest, 
descriptor_field field, tree valu
 
 
 static void
-set_descriptor (write_destination &dest)
+set_descriptor (descriptor_write &dest)
 {
   set_descriptor_field (dest, DATA_FIELD, null_pointer_node);
-  if (dest.type == write_destination::STATIC_INIT)
+  if (dest.type == descriptor_write::STATIC_INIT)
 {
   tree decl = dest.ref;
   tree type = TREE_TYPE (decl);
@@ -926,7 +935,7 @@ gfc_conv_descriptor_cosize (tree desc, int rank, int corank)
 void
 gfc_nullify_descriptor (stmtblock_t *block, tree descr)
 {
-  write_destination dest(descr, block);
+  descriptor_write dest(descr, block);
   set_descriptor (dest);
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Factorisation set_dimension_bounds/shift_dimension_bounds gfc_set_descriptor_for_assign_realloc

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:77ed1d831b6dbf07984e906dcf51852c4a28ee88

commit 77ed1d831b6dbf07984e906dcf51852c4a28ee88
Author: Mikael Morin 
Date:   Sun Aug 17 17:05:28 2025 +0200

Factorisation set_dimension_bounds/shift_dimension_bounds 
gfc_set_descriptor_for_assign_realloc

Revert partiel

Diff:
---
 gcc/fortran/trans-descriptor.cc | 39 +++
 1 file changed, 11 insertions(+), 28 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index f2fbe4e77045..510fc984de34 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -2492,38 +2492,21 @@ gfc_set_descriptor_for_assign_realloc (stmtblock_t 
*block, gfc_loopinfo *loop,
   tree tmp = fold_build2_loc (input_location, MINUS_EXPR,
  gfc_array_index_type,
  loop->to[n], loop->from[n]);
-  tmp = fold_build2_loc (input_location, PLUS_EXPR,
-gfc_array_index_type,
-tmp, gfc_index_one_node);
-
-  tree lbound = gfc_index_one_node;
-  tree ubound = tmp;
+  tree ubound = fold_build2_loc (input_location, PLUS_EXPR,
+gfc_array_index_type,
+tmp, gfc_index_one_node);
 
   if (as)
-   {
- tree lbd = get_std_lbound (expr2, desc2, n,
-as->type == AS_ASSUMED_SIZE);
- ubound = fold_build2_loc (input_location,
-   MINUS_EXPR,
-   gfc_array_index_type,
-   ubound, lbound);
- ubound = fold_build2_loc (input_location,
-   PLUS_EXPR,
-   gfc_array_index_type,
-   ubound, lbd);
- lbound = lbd;
-   }
+   shift_dimension_fields (block, desc, gfc_rank_cst[n],
+   get_std_lbound (expr2, desc2, n,
+   as->type == AS_ASSUMED_SIZE),
+   gfc_index_one_node, ubound, size1, &offset);
+  else
+   set_dimension_fields (block, desc, gfc_rank_cst[n], gfc_index_one_node,
+ ubound, size1, &offset);
 
-  gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[n], lbound);
-  gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[n], ubound);
-  gfc_conv_descriptor_stride_set (block, desc, gfc_rank_cst[n], size1);
-  lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
-  tree tmp2 = fold_build2_loc (input_location, MULT_EXPR, 
gfc_array_index_type,
-  lbound, size1);
-  offset = fold_build2_loc (input_location, MINUS_EXPR,
-   gfc_array_index_type, offset, tmp2);
   size1 = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
-  tmp, size1);
+  ubound, size1);
 }
 
   /* Set the lhs descriptor and scalarizer offsets.  For rank > 1,


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Déplacement gfc_array_init_count -> gfc_descriptor_init_count

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:6d9ca3056a95456cb8b796818bde13a789525341

commit 6d9ca3056a95456cb8b796818bde13a789525341
Author: Mikael Morin 
Date:   Thu Jul 31 16:51:20 2025 +0200

Déplacement gfc_array_init_count -> gfc_descriptor_init_count

Diff:
---
 gcc/fortran/trans-array.cc  | 301 ++--
 gcc/fortran/trans-descriptor.cc | 283 +
 gcc/fortran/trans-descriptor.h  |   5 +
 3 files changed, 297 insertions(+), 292 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index ea2723064cd4..a0ab5a284015 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -5817,289 +5817,6 @@ get_array_memory_size (tree element_size, tree 
elements_count,
 }
 
 
-/* Fills in an array descriptor, and returns the size of the array.
-   The size will be a simple_val, ie a variable or a constant.  Also
-   calculates the offset of the base.  The pointer argument overflow,
-   which should be of integer type, will increase in value if overflow
-   occurs during the size calculation.  Returns the size of the array.
-   {
-stride = 1;
-offset = 0;
-for (n = 0; n < rank; n++)
-  {
-   a.lbound[n] = specified_lower_bound;
-   offset = offset + a.lbond[n] * stride;
-   size = 1 - lbound;
-   a.ubound[n] = specified_upper_bound;
-   a.stride[n] = stride;
-   size = size >= 0 ? ubound + size : 0; //size = ubound + 1 - lbound
-   overflow += size == 0 ? 0: (MAX/size < stride ? 1: 0);
-   stride = stride * size;
-  }
-for (n = rank; n < rank+corank; n++)
-  (Set lcobound/ucobound as above.)
-element_size = sizeof (array element);
-if (!rank)
-  return element_size
-stride = (size_t) stride;
-overflow += element_size == 0 ? 0: (MAX/element_size < stride ? 1: 0);
-stride = stride * element_size;
-return (stride);
-   }  */
-/*GCC ARRAYS*/
-
-static tree
-gfc_array_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower,
- gfc_expr ** upper, stmtblock_t * pblock,
- stmtblock_t * descriptor_block, tree * overflow,
- tree expr3_elem_size, gfc_expr *expr3, tree expr3_desc,
- bool e3_has_nodescriptor, gfc_expr *expr,
- tree element_size, bool explicit_ts,
- tree *empty_array_cond)
-{
-  tree type;
-  tree tmp;
-  tree size;
-  tree offset;
-  tree stride;
-  tree cond;
-  gfc_expr *ubound;
-  gfc_se se;
-  int n;
-
-  type = TREE_TYPE (descriptor);
-
-  stride = gfc_index_one_node;
-  offset = gfc_index_zero_node;
-
-  /* Set the dtype before the alloc, because registration of coarrays needs
- it initialized.  */
-  if (expr->ts.type == BT_CHARACTER
-  && expr->ts.deferred
-  && VAR_P (expr->ts.u.cl->backend_decl))
-{
-  type = gfc_typenode_for_spec (&expr->ts);
-  gfc_conv_descriptor_dtype_set (pblock, descriptor,
-gfc_get_dtype_rank_type (rank, type));
-}
-  else if (expr->ts.type == BT_CHARACTER
-  && expr->ts.deferred
-  && TREE_CODE (descriptor) == COMPONENT_REF)
-{
-  /* Deferred character components have their string length tucked away
-in a hidden field of the derived type. Obtain that and use it to
-set the dtype. The charlen backend decl is zero because the field
-type is zero length.  */
-  gfc_ref *ref;
-  tmp = NULL_TREE;
-  for (ref = expr->ref; ref; ref = ref->next)
-   if (ref->type == REF_COMPONENT
-   && gfc_deferred_strlen (ref->u.c.component, &tmp))
- break;
-  gcc_assert (tmp != NULL_TREE);
-  tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp),
-TREE_OPERAND (descriptor, 0), tmp, NULL_TREE);
-  tmp = fold_convert (gfc_charlen_type_node, tmp);
-  type = gfc_get_character_type_len (expr->ts.kind, tmp);
-  gfc_conv_descriptor_dtype_set (pblock, descriptor,
-gfc_get_dtype_rank_type (rank, type));
-}
-  else if (expr3_desc && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (expr3_desc)))
-gfc_conv_descriptor_dtype_set (pblock, descriptor,
-  gfc_conv_descriptor_dtype_get (expr3_desc));
-  else if (expr->ts.type == BT_CLASS && !explicit_ts
-  && expr3 && expr3->ts.type != BT_CLASS
-  && expr3_elem_size != NULL_TREE && expr3_desc == NULL_TREE)
-gfc_conv_descriptor_elem_len_set (pblock, descriptor, expr3_elem_size);
-  else
-gfc_conv_descriptor_dtype_set (pblock, descriptor, gfc_get_dtype (type));
-
-  tree empty_cond = logical_false_node;
-
-  for (n = 0; n < rank; n++)
-{
-  tree conv_lbound;
-  tree conv_ubound;
-
-  /* We have 3 possibilities for determining the size of the array:
-lower == NULL=> lbound = 1, ubound = upper[n]
-upper[n] = NULL  => lbound = 1, ubound 

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Simplification initialisation offset remap descriptor

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:238146e371b8a6c067d8f4edf1b106c8fa069219

commit 238146e371b8a6c067d8f4edf1b106c8fa069219
Author: Mikael Morin 
Date:   Sat Aug 16 15:13:04 2025 +0200

Simplification initialisation offset remap descriptor

Modif initialisation stride

Revert partiel initialisation stride

Suppression warning argument inutilisé

Suppression argument inutilisé

Diff:
---
 gcc/fortran/trans-descriptor.cc | 20 ++--
 gcc/fortran/trans-descriptor.h  |  2 +-
 gcc/fortran/trans-expr.cc   |  2 +-
 3 files changed, 4 insertions(+), 20 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 3df958c4ec86..641874104fab 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -1400,7 +1400,7 @@ gfc_copy_descriptor (stmtblock_t *block, tree dest, tree 
src, tree ptr,
 
 void
 gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, int dest_rank,
-  tree src, int src_rank, gfc_array_ref *ar)
+  tree src, gfc_array_ref *ar)
 {
   /* Set dtype.  */
   gfc_conv_descriptor_dtype_set (block, dest,
@@ -1425,23 +1425,7 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree 
dest, int dest_rank,
 
   /* Copy offset but adjust it such that it would correspond
  to a lbound of zero.  */
-  if (src_rank == -1)
-gfc_conv_descriptor_offset_set (block, dest,
-   gfc_index_zero_node);
-  else
-{
-  tree offs = gfc_conv_descriptor_offset_get (src);
-  for (int dim = 0; dim < src_rank; ++dim)
-   {
- tree stride = gfc_conv_descriptor_stride_get (src, gfc_rank_cst[dim]);
- tree lbound = gfc_conv_descriptor_lbound_get (src, gfc_rank_cst[dim]);
- tree tmp = fold_build2_loc (input_location, MULT_EXPR,
- gfc_array_index_type, stride, lbound);
- offs = fold_build2_loc (input_location, PLUS_EXPR,
- gfc_array_index_type, offs, tmp);
-   }
-  gfc_conv_descriptor_offset_set (block, dest, offs);
-}
+  gfc_conv_descriptor_offset_set (block, dest, gfc_index_zero_node);
 
   /* Set the bounds as declared for the LHS and calculate strides as
  well as another offset update accordingly.  */
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index 35f50c144304..c6a079036902 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -113,7 +113,7 @@ void gfc_copy_descriptor (stmtblock_t *, tree, tree, tree, 
int, gfc_ss *);
 void gfc_copy_descriptor (stmtblock_t *, tree, tree, bool);
 void gfc_copy_descriptor (stmtblock_t *, tree, tree, int);
 
-void gfc_conv_remap_descriptor (stmtblock_t *, tree, int, tree, int,
+void gfc_conv_remap_descriptor (stmtblock_t *, tree, int, tree,
gfc_array_ref *);
 
 void gfc_set_descriptor_from_scalar_class (stmtblock_t *, tree, tree, gfc_expr 
*);
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 2c513303af5c..7196fd59c40c 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -11067,7 +11067,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, 
gfc_expr * expr2)
 converted in rse and now have to build the correct LHS
 descriptor for it.  */
  gfc_conv_remap_descriptor (&block, desc, expr1->rank,
-rse.expr, expr2->rank, &remap->u.ar);
+rse.expr, &remap->u.ar);
}
  else
/* Bounds remapping.  Just shift the lower bounds.  */


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Déplacement initialisation dernière borne sup assumed size

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:7069cc75f0e5ecc9ff7213316377849b30877436

commit 7069cc75f0e5ecc9ff7213316377849b30877436
Author: Mikael Morin 
Date:   Sun Aug 10 11:13:41 2025 +0200

Déplacement initialisation dernière borne sup assumed size

Diff:
---
 gcc/fortran/trans-array.cc | 37 ++---
 gcc/fortran/trans-expr.cc  | 32 
 2 files changed, 22 insertions(+), 47 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index c31a66d0e8d6..885f7440f3a2 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -7826,21 +7826,28 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
expr->ts.u.cl->backend_decl = tmp;
}
 
-  /* If we have an array section, are assigning  or passing an array
-section argument make sure that the lower bound is 1.  References
-to the full array should otherwise keep the original bounds.  */
-  if (!info->ref || info->ref->u.ar.type != AR_FULL)
-   for (dim = 0; dim < loop.dimen; dim++)
- if (!integer_onep (loop.from[dim]))
-   {
- tmp = fold_build2_loc (input_location, MINUS_EXPR,
-gfc_array_index_type, gfc_index_one_node,
-loop.from[dim]);
- loop.to[dim] = fold_build2_loc (input_location, PLUS_EXPR,
- gfc_array_index_type,
- loop.to[dim], tmp);
- loop.from[dim] = gfc_index_one_node;
-   }
+  if (info->ref && info->ref->u.ar.type == AR_FULL)
+   {
+ if (info->ref->u.ar.as->type == AS_ASSUMED_SIZE)
+   loop.to[loop.dimen - 1] = build_int_cst (gfc_array_index_type, -1);
+   }
+  else
+   {
+ /* If we have an array section, are assigning  or passing an array
+section argument make sure that the lower bound is 1.  References
+to the full array should otherwise keep the original bounds.  */
+ for (dim = 0; dim < loop.dimen; dim++)
+   if (!integer_onep (loop.from[dim]))
+ {
+   tmp = fold_build2_loc (input_location, MINUS_EXPR,
+  gfc_array_index_type, gfc_index_one_node,
+  loop.from[dim]);
+   loop.to[dim] = fold_build2_loc (input_location, PLUS_EXPR,
+   gfc_array_index_type,
+   loop.to[dim], tmp);
+   loop.from[dim] = gfc_index_one_node;
+ }
+   }
 
   desc = info->descriptor;
   if (se->direct_byref && !se->byref_noassign)
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 20387351485c..50d260cdd0ef 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -7606,38 +7606,6 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
}
}
}
-  /* Special case for an assumed-rank dummy argument. */
-  if (!sym->attr.is_bind_c && e && fsym && e->rank > 0
- && (fsym->ts.type == BT_CLASS
- ? (CLASS_DATA (fsym)->as
-&& CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
- : (fsym->as && fsym->as->type == AS_ASSUMED_RANK))
- && !(fsym->ts.type == BT_CLASS
-  ? (CLASS_DATA (fsym)->attr.class_pointer
- || CLASS_DATA (fsym)->attr.allocatable)
-  : (fsym->attr.pointer || fsym->attr.allocatable))
- && e->expr_type == EXPR_VARIABLE
- && e->symtree->n.sym->attr.dummy
- && (e->ts.type == BT_CLASS
- ? (e->ref && e->ref->next
-&& e->ref->next->type == REF_ARRAY
-&& e->ref->next->u.ar.type == AR_FULL
-&& e->ref->next->u.ar.as->type == AS_ASSUMED_SIZE)
- : (e->ref && e->ref->type == REF_ARRAY
-&& e->ref->u.ar.type == AR_FULL
-&& e->ref->u.ar.as->type == AS_ASSUMED_SIZE)))
-   {
- /* Assumed-size actual to assumed-rank dummy requires
-dim[rank-1].ubound = -1. */
- tree minus_one;
- tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
- if (fsym->ts.type == BT_CLASS)
-   tmp = gfc_class_data_get (tmp);
- minus_one = build_int_cst (gfc_array_index_type, -1);
- gfc_conv_descriptor_ubound_set (&parmse.pre, tmp,
- gfc_rank_cst[e->rank - 1],
- minus_one);
-   }
 
   /* The case with fsym->attr.optional is that of a user subroutine
 with an interface indicating an optional argument.  When we call


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction get_array_memory_size

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:d594ecbd50ef3c2087090582cf442c4b9204a2e2

commit d594ecbd50ef3c2087090582cf442c4b9204a2e2
Author: Mikael Morin 
Date:   Wed Jul 23 22:21:15 2025 +0200

Extraction get_array_memory_size

Diff:
---
 gcc/fortran/trans-array.cc | 155 -
 1 file changed, 84 insertions(+), 71 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index abf311351e25..aee0351667fd 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -5784,6 +5784,63 @@ descriptor_element_size (tree descriptor, tree 
expr3_elem_size,
 }
 
 
+static tree
+get_array_memory_size (tree element_size, tree elements_count,
+  tree empty_array_cond, stmtblock_t *pblock,
+  tree *overflow)
+{
+  elements_count = fold_convert (size_type_node, elements_count);
+
+  /* First check for overflow. Since an array of type character can
+ have zero element_size, we must check for that before
+ dividing.  */
+  tree tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
+ size_type_node, TYPE_MAX_VALUE (size_type_node),
+ element_size);
+  tree cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR,
+logical_type_node, tmp,
+elements_count),
+   PRED_FORTRAN_OVERFLOW);
+  tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
+integer_one_node, integer_zero_node);
+  cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR,
+   logical_type_node, element_size,
+   build_int_cst (size_type_node, 0)),
+  PRED_FORTRAN_SIZE_ZERO);
+  tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
+integer_zero_node, tmp);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
+*overflow, tmp);
+  *overflow = gfc_evaluate_now (tmp, pblock);
+
+  tree size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
+  elements_count, element_size);
+
+  if (integer_zerop (empty_array_cond))
+return size;
+  if (integer_onep (empty_array_cond))
+return build_int_cst (size_type_node, 0);
+
+  tree var = gfc_create_var (TREE_TYPE (size), "size");
+
+  stmtblock_t thenblock;
+  gfc_start_block (&thenblock);
+  gfc_add_modify (&thenblock, var, build_int_cst (size_type_node, 0));
+  tree thencase = gfc_finish_block (&thenblock);
+
+  stmtblock_t elseblock;
+  gfc_start_block (&elseblock);
+  gfc_add_modify (&elseblock, var, size);
+  tree elsecase = gfc_finish_block (&elseblock);
+
+  tmp = gfc_evaluate_now (empty_array_cond, pblock);
+  tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
+  gfc_add_expr_to_block (pblock, tmp);
+
+  return var;
+}
+
+
 /* Fills in an array descriptor, and returns the size of the array.
The size will be a simple_val, ie a variable or a constant.  Also
calculates the offset of the base.  The pointer argument overflow,
@@ -5816,25 +5873,20 @@ descriptor_element_size (tree descriptor, tree 
expr3_elem_size,
 /*GCC ARRAYS*/
 
 static tree
-gfc_array_init_size (tree descriptor, int rank, int corank, gfc_expr ** lower,
-gfc_expr ** upper, stmtblock_t * pblock,
-stmtblock_t * descriptor_block, tree * overflow,
-tree expr3_elem_size, gfc_expr *expr3, tree expr3_desc,
-bool e3_has_nodescriptor, gfc_expr *expr,
-tree element_size, bool explicit_ts)
+gfc_array_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower,
+ gfc_expr ** upper, stmtblock_t * pblock,
+ stmtblock_t * descriptor_block, tree * overflow,
+ tree expr3_elem_size, gfc_expr *expr3, tree expr3_desc,
+ bool e3_has_nodescriptor, gfc_expr *expr,
+ tree element_size, bool explicit_ts,
+ tree *empty_array_cond)
 {
   tree type;
   tree tmp;
   tree size;
   tree offset;
   tree stride;
-  tree or_expr;
-  tree thencase;
-  tree elsecase;
   tree cond;
-  tree var;
-  stmtblock_t thenblock;
-  stmtblock_t elseblock;
   gfc_expr *ubound;
   gfc_se se;
   int n;
@@ -5886,7 +5938,7 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, gfc_expr ** lower,
   else
 gfc_conv_descriptor_dtype_set (pblock, descriptor, gfc_get_dtype (type));
 
-  or_expr = logical_false_node;
+  tree empty_cond = logical_false_node;
 
   for (n = 0; n < rank; n++)
 {
@@ -5982,7 +6034,7 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, gfc_expr ** lower,
  gfc_rank_cst[n], stride);
 
   /* Calculate size and check whether extent i

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction gfc_set_pdt_array_descriptor

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:680ce9db24c39f5799c3f22db93f1ecb4cc5f1d9

commit 680ce9db24c39f5799c3f22db93f1ecb4cc5f1d9
Author: Mikael Morin 
Date:   Thu Jul 31 12:34:22 2025 +0200

Extraction gfc_set_pdt_array_descriptor

Diff:
---
 gcc/fortran/trans-array.cc  | 62 +
 gcc/fortran/trans-descriptor.cc | 50 +
 gcc/fortran/trans-descriptor.h  |  2 ++
 3 files changed, 59 insertions(+), 55 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 10a661e76260..9036c318a1af 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -10154,56 +10154,9 @@ structure_alloc_comps (gfc_symbol * der_type, tree 
decl, tree dest,
 
  if (c->attr.pdt_array)
{
- gfc_se tse;
- int i;
- tree size = gfc_index_one_node;
- tree offset = gfc_index_zero_node;
- tree lower, upper;
- gfc_expr *e;
-
- /* This chunk takes the expressions for 'lower' and 'upper'
-in the arrayspec and substitutes in the expressions for
-the parameters from 'pdt_param_list'. The descriptor
-fields can then be filled from the values so obtained.  */
- gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)));
- for (i = 0; i < c->as->rank; i++)
-   {
- gfc_init_se (&tse, NULL);
- e = gfc_copy_expr (c->as->lower[i]);
- gfc_insert_parameter_exprs (e, pdt_param_list);
- gfc_conv_expr_type (&tse, e, gfc_array_index_type);
- gfc_free_expr (e);
- lower = tse.expr;
- gfc_conv_descriptor_lbound_set (&fnblock, comp,
- gfc_rank_cst[i],
- lower);
- e = gfc_copy_expr (c->as->upper[i]);
- gfc_insert_parameter_exprs (e, pdt_param_list);
- gfc_conv_expr_type (&tse, e, gfc_array_index_type);
- gfc_free_expr (e);
- upper = tse.expr;
- gfc_conv_descriptor_ubound_set (&fnblock, comp,
- gfc_rank_cst[i],
- upper);
- gfc_conv_descriptor_stride_set (&fnblock, comp,
- gfc_rank_cst[i],
- size);
- size = gfc_evaluate_now (size, &fnblock);
- offset = fold_build2_loc (input_location,
-   MINUS_EXPR,
-   gfc_array_index_type,
-   offset, size);
- offset = gfc_evaluate_now (offset, &fnblock);
- tmp = fold_build2_loc (input_location, MINUS_EXPR,
-gfc_array_index_type,
-upper, lower);
- tmp = fold_build2_loc (input_location, PLUS_EXPR,
-gfc_array_index_type,
-tmp, gfc_index_one_node);
- size = fold_build2_loc (input_location, MULT_EXPR,
- gfc_array_index_type, size, tmp);
-   }
- gfc_conv_descriptor_offset_set (&fnblock, comp, offset);
+ tree nelts = gfc_set_pdt_array_descriptor (&fnblock, comp, c->as,
+pdt_param_list);
+
  if (c->ts.type == BT_CLASS)
{
  tmp = gfc_get_vptr_from_expr (comp);
@@ -10214,18 +10167,17 @@ structure_alloc_comps (gfc_symbol * der_type, tree 
decl, tree dest,
  else
tmp = TYPE_SIZE_UNIT (gfc_get_element_type (ctype));
  tmp = fold_convert (gfc_array_index_type, tmp);
- size = fold_build2_loc (input_location, MULT_EXPR,
- gfc_array_index_type, size, tmp);
+ tree size = fold_build2_loc (input_location, MULT_EXPR,
+  gfc_array_index_type, nelts, tmp);
  size = gfc_evaluate_now (size, &fnblock);
  tmp = gfc_call_malloc (&fnblock, NULL, size);
  gfc_conv_descriptor_data_set (&fnblock, comp, tmp);
- gfc_conv_descriptor_dtype_set (&fnblock, comp,
-gfc_get_dtype (ctype));
 
  if (c->initializer && c->initializer->rank)
{
+ gfc_se tse;
  gfc_init_se (&tse, NULL);
- e = gfc_copy_expr (c->initializer);
+ gfc_expr *e = gfc_copy_expr (c->initializer);
  gfc_insert_parameter_exprs (e, pdt_param_lis

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Suppression déclarations inutiles

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:97d3534ea819eb2339461e118a887e21e62c7099

commit 97d3534ea819eb2339461e118a887e21e62c7099
Author: Mikael Morin 
Date:   Wed Aug 6 21:38:11 2025 +0200

Suppression déclarations inutiles

Diff:
---
 gcc/fortran/trans-descriptor.h | 4 
 1 file changed, 4 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index 40e1586ce5f7..0881f0367316 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -61,14 +61,10 @@ tree gfc_conv_descriptor_sm_get (tree desc, tree dim);
 
 void gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value);
 void gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value);
-void gfc_conv_descriptor_offset_set (stmtblock_t *block, tree desc, tree 
value);
 void gfc_conv_descriptor_dtype_set (stmtblock_t *block, tree desc, tree value);
 void gfc_conv_descriptor_version_set (stmtblock_t *block, tree desc, tree 
value);
 void gfc_conv_descriptor_rank_set (stmtblock_t *block, tree desc, tree value);
 void gfc_conv_descriptor_rank_set (stmtblock_t *block, tree desc, int value);
-void gfc_conv_descriptor_dimension_set (stmtblock_t *block, tree desc, tree 
dim, tree value);
-void gfc_conv_descriptor_dimension_set (stmtblock_t *block, tree desc, int 
dim, tree value);
-void gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree desc, tree dim, 
tree value);
 void gfc_conv_descriptor_token_set (stmtblock_t *block, tree desc, tree value);
 
 tree gfc_build_null_descriptor (tree type);


[gcc(refs/users/meissner/heads/work221-sha)] Add ChangeLog.sha and update REVISION.

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:f3ef743e930a3264f9b3f3851a8d4e77d2356dbc

commit f3ef743e930a3264f9b3f3851a8d4e77d2356dbc
Author: Michael Meissner 
Date:   Mon Sep 8 14:02:24 2025 -0400

Add ChangeLog.sha and update REVISION.

2025-09-08  Michael Meissner  

gcc/

* ChangeLog.sha: New file for branch.
* REVISION: Update.

Diff:
---
 gcc/ChangeLog.sha | 14 ++
 gcc/REVISION  |  2 +-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/ChangeLog.sha b/gcc/ChangeLog.sha
new file mode 100644
index ..0af4cdd11faf
--- /dev/null
+++ b/gcc/ChangeLog.sha
@@ -0,0 +1,14 @@
+ Branch work221-sha, baseline 
+
+2025-09-08   Michael Meissner  
+
+Add ChangeLog.sha and update REVISION.
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   * ChangeLog.sha: New file for branch.
+   * REVISION: Update.
+
+   Clone branch
diff --git a/gcc/REVISION b/gcc/REVISION
index 0c170cfe7d4e..fa018d185c45 100644
--- a/gcc/REVISION
+++ b/gcc/REVISION
@@ -1 +1 @@
-work221 branch
+work221-sha branch


[gcc r16-3672] libstdc++: Fix docs for --enable-vtable-verify [PR120698]

2025-09-08 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:d199a9c7c5034d0eddb3380a58342a5bcbe6febd

commit r16-3672-gd199a9c7c5034d0eddb3380a58342a5bcbe6febd
Author: Jonathan Wakely 
Date:   Wed Jun 18 15:46:24 2025 +0100

libstdc++: Fix docs for --enable-vtable-verify [PR120698]

libstdc++-v3/ChangeLog:

PR libstdc++/120698
* doc/xml/manual/configure.xml: Do not claim that vtv is enabled
by default.
* doc/html/manual/configure.html: Regenerate.

Diff:
---
 libstdc++-v3/doc/html/manual/configure.html | 2 +-
 libstdc++-v3/doc/xml/manual/configure.xml   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/configure.html 
b/libstdc++-v3/doc/html/manual/configure.html
index 3564b0c409f0..eb4d42117100 100644
--- a/libstdc++-v3/doc/html/manual/configure.html
+++ b/libstdc++-v3/doc/html/manual/configure.html
@@ -268,7 +268,7 @@
 operations (e.g. the library is configured for armv7 and then code
 is compiled with -march=armv5t) then the 
program
 might rely on support in libgcc to provide the atomics.
---enable-vtable-verify[default]Use -fvtable-verify=std to compile the C++
+--enable-vtable-verifyUse -fvtable-verify=std to compile the C++
 runtime with instrumentation for vtable verification. All virtual
 functions in the standard library will be verified at runtime.
 Types impacted include locale and
diff --git a/libstdc++-v3/doc/xml/manual/configure.xml 
b/libstdc++-v3/doc/xml/manual/configure.xml
index cd5f44458a2e..460b994009da 100644
--- a/libstdc++-v3/doc/xml/manual/configure.xml
+++ b/libstdc++-v3/doc/xml/manual/configure.xml
@@ -438,7 +438,7 @@
 
  
 
- --enable-vtable-verify[default]
+ --enable-vtable-verify
  
 Use -fvtable-verify=std to compile the C++
 runtime with instrumentation for vtable verification. All virtual


[gcc r14-12009] libstdc++: Fix docs for --enable-vtable-verify [PR120698]

2025-09-08 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:2d6e59fa8b2893cb6eb6238169d6a20b58605545

commit r14-12009-g2d6e59fa8b2893cb6eb6238169d6a20b58605545
Author: Jonathan Wakely 
Date:   Wed Jun 18 15:46:24 2025 +0100

libstdc++: Fix docs for --enable-vtable-verify [PR120698]

libstdc++-v3/ChangeLog:

PR libstdc++/120698
* doc/xml/manual/configure.xml: Do not claim that vtv is enabled
by default.
* doc/html/manual/configure.html: Regenerate.

(cherry picked from commit d199a9c7c5034d0eddb3380a58342a5bcbe6febd)

Diff:
---
 libstdc++-v3/doc/html/manual/configure.html | 2 +-
 libstdc++-v3/doc/xml/manual/configure.xml   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/configure.html 
b/libstdc++-v3/doc/html/manual/configure.html
index 346b5d345cd1..08477aa12ee5 100644
--- a/libstdc++-v3/doc/html/manual/configure.html
+++ b/libstdc++-v3/doc/html/manual/configure.html
@@ -268,7 +268,7 @@
 operations (e.g. the library is configured for armv7 and then code
 is compiled with -march=armv5t) then the 
program
 might rely on support in libgcc to provide the atomics.
---enable-vtable-verify[default]Use -fvtable-verify=std to compile the C++
+--enable-vtable-verifyUse -fvtable-verify=std to compile the C++
 runtime with instrumentation for vtable verification. All virtual
 functions in the standard library will be verified at runtime.
 Types impacted include locale and
diff --git a/libstdc++-v3/doc/xml/manual/configure.xml 
b/libstdc++-v3/doc/xml/manual/configure.xml
index 0a477ab85e59..e4746bfe514a 100644
--- a/libstdc++-v3/doc/xml/manual/configure.xml
+++ b/libstdc++-v3/doc/xml/manual/configure.xml
@@ -438,7 +438,7 @@
 
  
 
- --enable-vtable-verify[default]
+ --enable-vtable-verify
  
 Use -fvtable-verify=std to compile the C++
 runtime with instrumentation for vtable verification. All virtual


[gcc r13-9875] libstdc++: Fix docs for --enable-vtable-verify [PR120698]

2025-09-08 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:d01494e8cf0be5e2cde9f87f7fcaa0e77979957d

commit r13-9875-gd01494e8cf0be5e2cde9f87f7fcaa0e77979957d
Author: Jonathan Wakely 
Date:   Wed Jun 18 15:46:24 2025 +0100

libstdc++: Fix docs for --enable-vtable-verify [PR120698]

libstdc++-v3/ChangeLog:

PR libstdc++/120698
* doc/xml/manual/configure.xml: Do not claim that vtv is enabled
by default.
* doc/html/manual/configure.html: Regenerate.

(cherry picked from commit d199a9c7c5034d0eddb3380a58342a5bcbe6febd)

Diff:
---
 libstdc++-v3/doc/html/manual/configure.html | 2 +-
 libstdc++-v3/doc/xml/manual/configure.xml   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/configure.html 
b/libstdc++-v3/doc/html/manual/configure.html
index 346b5d345cd1..08477aa12ee5 100644
--- a/libstdc++-v3/doc/html/manual/configure.html
+++ b/libstdc++-v3/doc/html/manual/configure.html
@@ -268,7 +268,7 @@
 operations (e.g. the library is configured for armv7 and then code
 is compiled with -march=armv5t) then the 
program
 might rely on support in libgcc to provide the atomics.
---enable-vtable-verify[default]Use -fvtable-verify=std to compile the C++
+--enable-vtable-verifyUse -fvtable-verify=std to compile the C++
 runtime with instrumentation for vtable verification. All virtual
 functions in the standard library will be verified at runtime.
 Types impacted include locale and
diff --git a/libstdc++-v3/doc/xml/manual/configure.xml 
b/libstdc++-v3/doc/xml/manual/configure.xml
index 0a477ab85e59..e4746bfe514a 100644
--- a/libstdc++-v3/doc/xml/manual/configure.xml
+++ b/libstdc++-v3/doc/xml/manual/configure.xml
@@ -438,7 +438,7 @@
 
  
 
- --enable-vtable-verify[default]
+ --enable-vtable-verify
  
 Use -fvtable-verify=std to compile the C++
 runtime with instrumentation for vtable verification. All virtual


[gcc(refs/users/meissner/heads/work221-sha)] PR target/117251: Improve vector orc to vector xor fusion

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:82cf2a201e5193eff9e8e4221eb53d0c8316c131

commit 82cf2a201e5193eff9e8e4221eb53d0c8316c131
Author: Michael Meissner 
Date:   Mon Sep 8 15:37:43 2025 -0400

PR target/117251: Improve vector orc to vector xor fusion

See the following post for a complete explanation of what the patches
for PR target/117251:

 * https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686474.html

This is patch #30 of 45 to generate the 'XXEVAL' instruction on power10
and power11 instead of using the Altivec 'VORC' instruction feeding
into 'VXOR'.  The 'XXEVAL' instruction can use all 64 vector registers,
instead of the 32 registers that traditional Altivec vector
instructions use.  By allowing all of the vector registers to be used,
it reduces the amount of spilling that a large benchmark generated.

Currently the following code:

vector int a, b, c, d;
a = (c | ~ d) ^ b;

Generates:

vorc   t,c,d
vxor   a,t,b

Now in addition with this patch, if the arguments or result is
allocated to a traditional FPR register, the GCC compiler will now
generate the following code instead of adding vector move instructions:

xxeval a,b,c,180

Since fusion using 2 Altivec instructions is slightly faster than using
the 'XXEVAL' instruction we prefer to generate the Altivec instructions
if we can.  In addition, because 'XXEVAL' is a prefixed instruction, it
possibly might generate an extra NOP instruction to align the 'XXEVAL'
instruction.

I have tested these patches on both big endian and little endian
PowerPC servers, with no regressions.  Can I check these patchs into
the trunk?

2025-09-08  Michael Meissner  

gcc/

PR target/117251
* config/rs6000/fusion.md: Regenerate.
* config/rs6000/genfusion.pl (gen_logical_addsubf): Add support
to generate vector orc => xor fusion if XXEVAL is supported.

Diff:
---
 gcc/config/rs6000/fusion.md| 15 +--
 gcc/config/rs6000/genfusion.pl |  1 +
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
index cb1ad8b4c0cc..3d7e6502b027 100644
--- a/gcc/config/rs6000/fusion.md
+++ b/gcc/config/rs6000/fusion.md
@@ -3071,20 +3071,23 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vorc -> vxor
 (define_insn "*fuse_vorc_vxor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-(xor:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-  (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
- (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+(xor:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+  (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+ (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
vorc %3,%1,%0\;vxor %3,%3,%2
vorc %3,%1,%0\;vxor %3,%3,%2
vorc %3,%1,%0\;vxor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,180
vorc %4,%1,%0\;vxor %3,%4,%2"
   [(set_attr "type" "fused_vector")
(set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vxor -> vxor
diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index 9400aed267a6..15f931baad33 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -244,6 +244,7 @@ sub gen_logical_addsubf
   "vxor_vnor"   => 144,
   "veqv_vxor"   => 150,
   "veqv_vor"=> 159,
+  "vorc_vxor"   => 180,
 );
 
 KIND: foreach $kind ('scalar','vector') {


[gcc(refs/users/meissner/heads/work221-sha)] PR target/117251: Improve vector andc to vector xor fusion

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:9da087096b1375a21f12cae21e0376ef09cc8fe0

commit 9da087096b1375a21f12cae21e0376ef09cc8fe0
Author: Michael Meissner 
Date:   Mon Sep 8 15:20:07 2025 -0400

PR target/117251: Improve vector andc to vector xor fusion

See the following post for a complete explanation of what the patches
for PR target/117251:

 * https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686474.html

This is patch #13 of 45 to generate the 'XXEVAL' instruction on power10
and power11 instead of using the Altivec 'VANDC' instruction feeding
into 'VXOR'.  The 'XXEVAL' instruction can use all 64 vector registers,
instead of the 32 registers that traditional Altivec vector
instructions use.  By allowing all of the vector registers to be used,
it reduces the amount of spilling that a large benchmark generated.

Currently the following code:

vector int a, b, c, d;
a = (c & ~ d) ^ b;

Generates:

vandc  t,c,d
vxor   a,t,b

Now in addition with this patch, if the arguments or result is
allocated to a traditional FPR register, the GCC compiler will now
generate the following code instead of adding vector move instructions:

xxeval a,b,c,45

Since fusion using 2 Altivec instructions is slightly faster than using
the 'XXEVAL' instruction we prefer to generate the Altivec instructions
if we can.  In addition, because 'XXEVAL' is a prefixed instruction, it
possibly might generate an extra NOP instruction to align the 'XXEVAL'
instruction.

I have tested these patches on both big endian and little endian
PowerPC servers, with no regressions.  Can I check these patchs into
the trunk?

2025-09-08  Michael Meissner  

gcc/

PR target/117251
* config/rs6000/fusion.md: Regenerate.
* config/rs6000/genfusion.pl (gen_logical_addsubf): Add support
to generate vector andc => xor fusion if XXEVAL is supported.

Diff:
---
 gcc/config/rs6000/fusion.md| 15 +--
 gcc/config/rs6000/genfusion.pl |  1 +
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
index fccea39d0aae..6e5c88b81b44 100644
--- a/gcc/config/rs6000/fusion.md
+++ b/gcc/config/rs6000/fusion.md
@@ -2933,20 +2933,23 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vandc -> vxor
 (define_insn "*fuse_vandc_vxor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-(xor:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-  (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
- (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+(xor:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+  (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+ (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
vandc %3,%1,%0\;vxor %3,%3,%2
vandc %3,%1,%0\;vxor %3,%3,%2
vandc %3,%1,%0\;vxor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,45
vandc %4,%1,%0\;vxor %3,%4,%2"
   [(set_attr "type" "fused_vector")
(set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector veqv -> vxor
diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index ab714b10f622..d15208a4ad3e 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -227,6 +227,7 @@ sub gen_logical_addsubf
   "vnand_vnor"  =>  16,
   "vand_vxor"   =>  30,
   "vand_vor"=>  31,
+  "vandc_vxor"  =>  45,
 );
 
 KIND: foreach $kind ('scalar','vector') {


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction gfc_set_empty_descriptor_bounds

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:35967a139e4d7e3ff9468cd4504848034f28ba0d

commit 35967a139e4d7e3ff9468cd4504848034f28ba0d
Author: Mikael Morin 
Date:   Thu Jul 31 17:47:15 2025 +0200

Extraction gfc_set_empty_descriptor_bounds

Diff:
---
 gcc/fortran/trans-array.cc  | 18 ++
 gcc/fortran/trans-descriptor.cc | 17 +
 gcc/fortran/trans-descriptor.h  |  1 +
 3 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index a0ab5a284015..7449670d2f52 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -10396,7 +10396,6 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo 
*loop,
   stmtblock_t realloc_block;
   stmtblock_t alloc_block;
   stmtblock_t fblock;
-  stmtblock_t loop_pre_block;
   gfc_ref *ref;
   gfc_ss *rss;
   gfc_ss *lss;
@@ -10495,22 +10494,9 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo 
*loop,
   tree guard = gfc_create_var (logical_type_node, 
"unallocated_init_guard");
   gfc_add_modify (&unalloc_init_block, guard, logical_false_node);
 
+  stmtblock_t loop_pre_block;
   gfc_start_block (&loop_pre_block);
-  for (n = 0; n < expr1->rank; n++)
-   {
- gfc_conv_descriptor_lbound_set (&loop_pre_block, desc,
- gfc_rank_cst[n],
- gfc_index_one_node);
- gfc_conv_descriptor_ubound_set (&loop_pre_block, desc,
- gfc_rank_cst[n],
- gfc_index_zero_node);
- gfc_conv_descriptor_stride_set (&loop_pre_block, desc,
- gfc_rank_cst[n],
- gfc_index_zero_node);
-   }
-
-  gfc_conv_descriptor_offset_set (&loop_pre_block, desc,
- gfc_index_zero_node);
+  gfc_set_empty_descriptor_bounds (&loop_pre_block, desc, expr1->rank);
 
   tmp = fold_build2_loc (input_location, EQ_EXPR,
 logical_type_node, array1,
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 867daf831f53..048184afb76b 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -2790,3 +2790,20 @@ gfc_descriptor_init_count (tree descriptor, int rank, 
int corank,
   return stride;
 }
 
+
+void
+gfc_set_empty_descriptor_bounds (stmtblock_t *block, tree descr, int rank)
+{
+  for (int n = 0; n < rank; n++)
+{
+  gfc_conv_descriptor_lbound_set (block, descr, gfc_rank_cst[n],
+ gfc_index_one_node);
+  gfc_conv_descriptor_ubound_set (block, descr, gfc_rank_cst[n],
+ gfc_index_zero_node);
+  gfc_conv_descriptor_stride_set (block, descr, gfc_rank_cst[n],
+ gfc_index_zero_node);
+}
+
+  gfc_conv_descriptor_offset_set (block, descr, gfc_index_zero_node);
+}
+
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index c3b33f3d5c2f..381389b826ad 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -153,5 +153,6 @@ gfc_descriptor_init_count (tree, int, int, gfc_expr **, 
gfc_expr **,
   stmtblock_t * pblock, stmtblock_t *, tree *,
   tree, gfc_expr *, tree, bool, gfc_expr *, tree,
   bool, tree *);
+void gfc_set_empty_descriptor_bounds (stmtblock_t *, tree, int);
 
 #endif /* GFC_TRANS_DESCRIPTOR_H */


[gcc r16-3647] strlen: Handle empty constructor as memset for combining with malloc to calloc [PR87900]

2025-09-08 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:ed264541c353866cedf46ad873f2e2c46cf62839

commit r16-3647-ged264541c353866cedf46ad873f2e2c46cf62839
Author: Andrew Pinski 
Date:   Sat Apr 19 09:14:54 2025 -0700

strlen: Handle empty constructor as memset for combining with malloc to 
calloc [PR87900]

This was noticed when turning memset (with constant size) into a store of 
an empty constructor
but can be reproduced without that.
In this case we have the following IR:
```
  p_3 = __builtin_malloc (4096);
  *p_3 = {};
```

Which we can treat the store as a memset.
So this patch adds the similar optimization as memset/malloc now for 
malloc/constructor.
This patch is on top of 
https://gcc.gnu.org/pipermail/gcc-patches/2025-April/681439.html
(it calls allow_memset_malloc_to_calloc but that can be removed if that 
patch is rejected).

Changes since v1:
* v2: Correctly return false from handle_assign after removing stmt.

Bootstrapped and tested on x86_64-linux-gnu.

PR tree-optimization/87900

gcc/ChangeLog:

* tree-ssa-strlen.cc  (strlen_pass::handle_assign): Add RHS 
argument.
For empty constructor RHS, see if can combine with a previous 
malloc into
a calloc.
(strlen_pass::check_and_optimize_call): Update call to 
handle_assign;
passing NULL_TREE for RHS.
(strlen_pass::check_and_optimize_stmt): Update call to 
handle_assign.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/calloc-10.c: New test.
* gcc.dg/tree-ssa/calloc-11.c: New test.
* gcc.dg/tree-ssa/calloc-12.c: New test.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/calloc-10.c | 19 +++
 gcc/testsuite/gcc.dg/tree-ssa/calloc-11.c | 21 
 gcc/testsuite/gcc.dg/tree-ssa/calloc-12.c | 20 +++
 gcc/tree-ssa-strlen.cc| 56 ---
 4 files changed, 111 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/calloc-10.c 
b/gcc/testsuite/gcc.dg/tree-ssa/calloc-10.c
new file mode 100644
index ..6d91563dc15f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/calloc-10.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+/* PR tree-optimization/87900 */
+
+/* zeroing out via a CONSTRUCTOR should be treated similarly as a msmet and
+   be combined with the malloc below.  */
+
+struct S { int a[1024]; };
+struct S *foo ()
+{
+  struct S *p = (struct S *)__builtin_malloc (sizeof (struct S));
+  *p = (struct S){};
+  return p;
+}
+
+/* { dg-final { scan-tree-dump-times "calloc " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "malloc " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "memset " "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/calloc-11.c 
b/gcc/testsuite/gcc.dg/tree-ssa/calloc-11.c
new file mode 100644
index ..397d7fa1fe80
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/calloc-11.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+/* PR tree-optimization/87900 */
+
+/* zeroing out via a CONSTRUCTOR should be treated similarly as a msmet and
+   be combined with the malloc below.  */
+typedef int type;
+
+#define size (1025)
+type *foo ()
+{
+  type *p = (type *)__builtin_malloc (size*sizeof(type));
+  type tmp[size] = {};
+  __builtin_memcpy(p,tmp,sizeof(tmp));
+  return p;
+}
+
+/* { dg-final { scan-tree-dump-times "calloc " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "malloc " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "memset " "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/calloc-12.c 
b/gcc/testsuite/gcc.dg/tree-ssa/calloc-12.c
new file mode 100644
index ..ef3b6322157a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/calloc-12.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+/* PR tree-optimization/87900 */
+
+/* zeroing out via a CONSTRUCTOR should be treated similarly as a msmet and
+   be combined with the malloc below.  */
+
+struct S { int a[1024]; };
+struct S *foo ()
+{
+  struct S *p = (struct S *)__builtin_malloc (sizeof (struct S));
+  if (p)
+*p = (struct S){};
+  return p;
+}
+
+/* { dg-final { scan-tree-dump-times "calloc " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "malloc " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "memset " "optimized" } } */
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index 39e12fd222d7..bb6561cde039 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -249,7 +249,7 @@ public:
 
   bool check_and_optimize_stmt (bool *cleanup_eh);
   bool check_and_optimize_call (bool *zero_write);
-  bool handle_assign (tree lhs, bool *zero_write);
+  bool handle_assign (tree lhs, tree rhs, bool *zero_write);
   bool ha

[gcc r16-3649] libstdc++: Implement constant_wrapper, cw from P2781R9.

2025-09-08 Thread Tomasz Kaminski via Gcc-cvs
https://gcc.gnu.org/g:c440b585ba374b6348ef223e4891a717a1f6660c

commit r16-3649-gc440b585ba374b6348ef223e4891a717a1f6660c
Author: Luc Grosheintz 
Date:   Thu Sep 4 14:20:28 2025 +0200

libstdc++: Implement constant_wrapper, cw from P2781R9.

This is a partial implementation of P2781R9. It adds std::cw and
std::constant_wrapper, but doesn't modify __integral_constant_like for
span/mdspan.

libstdc++-v3/ChangeLog:

* include/bits/version.def (constant_wrapper): Add.
* include/bits/version.h: Regenerate.
* include/std/type_traits (_CwFixedValue): New class.
(_IndexSequence): New struct.
(_BuildIndexSequence): New struct.
(_ConstExprParam): New concept.
(_CwOperators): New struct.
(constant_wrapper): New struct.
(cw): New global constant.
* src/c++23/std.cc.in (constant_wrapper): Add.
(cw): Add.
* testsuite/20_util/constant_wrapper/adl.cc: New test.
* testsuite/20_util/constant_wrapper/ex.cc: New test.
* testsuite/20_util/constant_wrapper/generic.cc: New test.
* testsuite/20_util/constant_wrapper/instantiate.cc: New test.
* testsuite/20_util/constant_wrapper/op_comma_neg.cc: New test.
* testsuite/20_util/constant_wrapper/version.cc: New test.

Reviewed-by: Jonathan Wakely 
Co-authored-by: Tomasz Kamiński 
Signed-off-by: Luc Grosheintz 
Signed-off-by: Tomasz Kamiński 

Diff:
---
 libstdc++-v3/include/bits/version.def  |   8 +
 libstdc++-v3/include/bits/version.h|  10 +
 libstdc++-v3/include/std/type_traits   | 371 +
 libstdc++-v3/src/c++23/std.cc.in   |   4 +
 .../testsuite/20_util/constant_wrapper/adl.cc  |  86 +++
 .../testsuite/20_util/constant_wrapper/ex.cc   |  39 ++
 .../testsuite/20_util/constant_wrapper/generic.cc  | 391 ++
 .../20_util/constant_wrapper/instantiate.cc| 575 +
 .../20_util/constant_wrapper/op_comma_neg.cc   |  14 +
 .../20_util/constant_wrapper/other_wrappers.cc |  75 +++
 .../testsuite/20_util/constant_wrapper/version.cc  |  11 +
 11 files changed, 1584 insertions(+)

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index 8707a123109f..65b9a278776a 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -393,6 +393,14 @@ ftms = {
   };
 };
 
+ftms = {
+  name = constant_wrapper;
+  values = {
+v = 202506;
+cxxmin = 26;
+  };
+};
+
 ftms = {
   name = has_unique_object_representations;
   values = {
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index c7569f42773c..b05249857d27 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -430,6 +430,16 @@
 #endif /* !defined(__cpp_lib_byte) && defined(__glibcxx_want_byte) */
 #undef __glibcxx_want_byte
 
+#if !defined(__cpp_lib_constant_wrapper)
+# if (__cplusplus >  202302L)
+#  define __glibcxx_constant_wrapper 202506L
+#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_constant_wrapper)
+#   define __cpp_lib_constant_wrapper 202506L
+#  endif
+# endif
+#endif /* !defined(__cpp_lib_constant_wrapper) && 
defined(__glibcxx_want_constant_wrapper) */
+#undef __glibcxx_want_constant_wrapper
+
 #if !defined(__cpp_lib_has_unique_object_representations)
 # if (__cplusplus >= 201703L) && 
(defined(_GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP))
 #  define __glibcxx_has_unique_object_representations 201606L
diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 4636457eb5a4..26cbbb4fd5ba 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -41,6 +41,7 @@
 
 #define __glibcxx_want_bool_constant
 #define __glibcxx_want_bounded_array_traits
+#define __glibcxx_want_constant_wrapper
 #define __glibcxx_want_has_unique_object_representations
 #define __glibcxx_want_integral_constant_callable
 #define __glibcxx_want_is_aggregate
@@ -4302,6 +4303,376 @@ template
 };
 #endif // C++11
 
+#ifdef __cpp_lib_constant_wrapper // C++ >= 26
+  template
+struct _CwFixedValue
+{
+  using _S_type = _Tp;
+
+  constexpr
+  _CwFixedValue(_S_type __v) noexcept
+  : _M_data(__v) { }
+
+  _S_type _M_data;
+};
+
+  template
+struct _CwFixedValue<_Tp[_Extent]>
+{
+  using _S_type = _Tp[_Extent];
+
+  constexpr
+  _CwFixedValue(_Tp (&__arr)[_Extent]) noexcept
+: _CwFixedValue(__arr, typename _Build_index_tuple<_Extent>::__type())
+  { }
+
+  template
+   constexpr
+   _CwFixedValue(_Tp (&__arr)[_Extent], _Index_tuple<_Indices...>) noexcept
+ : _M_data{__arr[_Indices]...}
+   { }
+
+  _Tp _M_data[_Extent];
+};
+
+  template
+_CwFixedValue(_Tp (&)[_Extent

[gcc r16-3650] libstdc++: Adjust span/mdspan CTAD for P2781R9.

2025-09-08 Thread Tomasz Kaminski via Libstdc++-cvs
https://gcc.gnu.org/g:71711f8ac3af615fec197e4eb71d0bee8ef44a23

commit r16-3650-g71711f8ac3af615fec197e4eb71d0bee8ef44a23
Author: Luc Grosheintz 
Date:   Thu Sep 4 14:20:29 2025 +0200

libstdc++: Adjust span/mdspan CTAD for P2781R9.

A usecase for P2781R9 is more ergonomic creation of span and mdspan with
mixed static and dynamic extents, e.g.:

span(ptr, cw<3>)
extents(cw<3>, 5, cw<7>)
mdspan(ptr, cw<3>, 5, cw<7>)

should be deduced as:
span<..., 3>
extents<..., 3, dyn, 7>
mdspan<..., extents<..., 3, dyn, 7>>

The change required is to strip cv-qualifiers and references from
`_Tp::value`, because of:

template<_CwFixedValue _X, typename>
  struct constant_wrapper : _CwOperators
  {
static constexpr const auto& value = _X._M_data;

libstdc++-v3/ChangeLog:

* include/std/span (__integral_constant_like): Allow the member
`value` of a constant wrapping type to be a const reference of
an integer.
* testsuite/23_containers/mdspan/extents/misc.cc: Add test for
cw and constant_wrapper.
* testsuite/23_containers/mdspan/mdspan.cc: Ditto.
* testsuite/23_containers/span/deduction.cc: Ditto.

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

Diff:
---
 libstdc++-v3/include/std/span  |  3 ++-
 .../testsuite/23_containers/mdspan/extents/misc.cc | 22 +++--
 .../testsuite/23_containers/mdspan/mdspan.cc   | 23 +++---
 .../testsuite/23_containers/span/deduction.cc  | 20 ++-
 4 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index 44f9b36a7efe..f9aa3c77e8e1 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -480,7 +480,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   namespace __detail
   {
 template
-  concept __integral_constant_like = is_integral_v
+  concept __integral_constant_like =
+   is_integral_v>
&& !is_same_v>
&& convertible_to<_Tp, decltype(_Tp::value)>
&& equality_comparable_with<_Tp, decltype(_Tp::value)>
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
index 8a43a682004d..94086653a745 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
@@ -98,7 +98,7 @@ test_deduction(Extents... exts)
 }
 
 constexpr bool
-test_integral_constant_deduction()
+test_deduction_from_constant()
 {
   auto verify = [](auto actual, auto expected)
 {
@@ -106,13 +106,23 @@ test_integral_constant_deduction()
   VERIFY(actual == expected);
 };
 
-  constexpr auto c1 = std::integral_constant{};
-  constexpr auto c2 = std::integral_constant{};
+  constexpr auto i1 = std::integral_constant{};
+  constexpr auto i2 = std::integral_constant{};
 
   verify(std::extents(1), std::extents{1});
-  verify(std::extents(c1), std::extents{});
+  verify(std::extents(i1), std::extents{});
+  verify(std::extents(i2), std::extents{});
+  verify(std::extents(std::true_type{}, 2), std::dextents{1, 2});
+  verify(std::extents(std::false_type{}, 2), std::dextents{0, 2});
+
+#if __glibcxx_constant_wrapper
+  constexpr auto c2 = std::constant_wrapper<2>{};
+  verify(std::extents(c2), std::extents{});
+  verify(std::extents(1, c2), std::extents{1});
   verify(std::extents(c2), std::extents{});
-  verify(std::extents(c1, 2), std::extents{2});
+  verify(std::extents(1, c2), std::extents{1});
+  verify(std::extents(std::cw, c2), std::extents{});
+#endif
   return true;
 }
 
@@ -123,7 +133,7 @@ test_deduction_all()
   test_deduction<1>(1);
   test_deduction<2>(1.0, 2.0f);
   test_deduction<3>(int(1), short(2), size_t(3));
-  test_integral_constant_deduction();
+  test_deduction_from_constant();
   return true;
 }
 
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
index bdfc6ebcf561..ca100b4f314a 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
@@ -280,7 +280,7 @@ test_from_pointer_and_shape()
 }
 
 constexpr bool
-test_from_pointer_and_integral_constant()
+test_from_pointer_and_constant()
 {
   std::array buffer{};
   double * ptr = buffer.data();
@@ -292,12 +292,21 @@ test_from_pointer_and_integral_constant()
   VERIFY(actual.extents() == expected.extents());
 };
 
-  auto c3 = std::integral_constant{};
-  auto c6 = std::integral_constant{};
+  auto i3 = std::integral_constant{};
+  auto i6 = std::integral_constant{};
 
   verify(std::mdspan(ptr, 6), std::extents(6));
-  verify(std::mdspan(ptr, c6), std::extents(c6));
-  verify(std::mdsp

[gcc r16-3651] compare_tests: Report non-unique test names

2025-09-08 Thread Christophe Lyon via Gcc-cvs
https://gcc.gnu.org/g:750346a763df2573ea4c8a8dde8cddced64f69a5

commit r16-3651-g750346a763df2573ea4c8a8dde8cddced64f69a5
Author: Christophe Lyon 
Date:   Mon Sep 1 09:32:34 2025 +

compare_tests: Report non-unique test names

Test "names" (the string after 'PASS:' or 'FAIL:' etc...  is expected
to be unique, otherwise this will confuse comparison scripts.

This patch displays the lists of non-unique test names in the 'before'
and in the 'now' results.

contrib/ChangeLog:

* compare_tests: Report non-unique test names.

Diff:
---
 contrib/compare_tests | 26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/contrib/compare_tests b/contrib/compare_tests
index e09fc4f113a3..152957bc3247 100755
--- a/contrib/compare_tests
+++ b/contrib/compare_tests
@@ -41,6 +41,8 @@ tmp1=$TMPDIR/$tool-testing.$$a
 tmp2=$TMPDIR/$tool-testing.$$b
 now_s=$TMPDIR/$tool-testing.$$d
 before_s=$TMPDIR/$tool-testing.$$e
+now_u=$TMPDIR/$tool-uniq.$$d
+before_u=$TMPDIR/$tool-uniq.$$e
 lst1=$TMPDIR/$tool-lst1.$$
 lst2=$TMPDIR/$tool-lst2.$$
 lst3=$TMPDIR/$tool-lst3.$$
@@ -48,7 +50,7 @@ lst4=$TMPDIR/$tool-lst4.$$
 lst5=$TMPDIR/$tool-lst5.$$
 sum1=$TMPDIR/$tool-sum1.$$
 sum2=$TMPDIR/$tool-sum2.$$
-tmps="$tmp1 $tmp2 $now_s $before_s $lst1 $lst2 $lst3 $lst4 $lst5 $sum1 $sum2"
+tmps="$tmp1 $tmp2 $now_s $before_s $now_u $before_u $lst1 $lst2 $lst3 $lst4 
$lst5 $sum1 $sum2"
 
 [ "$1" = "-strict" ] && strict=$1 && shift
 [ "$1" = "-?" ] && usage
@@ -124,6 +126,28 @@ fi
 sort -t ':' $skip1 "$now" > "$now_s"
 sort -t ':' $skip1 "$before" > "$before_s"
 
+# Report non-unique test names, but print the two lists only if they
+# are different.
+sed '/^$/d' "$now_s"| uniq -cd > "$now_u"
+sed '/^$/d' "$before_s" | uniq -cd > "$before_u"
+
+same_uniq=" now"
+cmp -s "$before_u" "$now_u" && same_uniq=""
+
+if [ -s "$now_u" ]; then
+echo "Non-unique test names$same_uniq: (Eeek!)"
+cat "$now_u"
+echo
+exit_status=1
+fi
+
+if [ -s "$before_u" -a "x$same_uniq" != "x" ]; then
+echo "Non-unique test names before: (Eeek!)"
+cat "$before_u"
+echo
+exit_status=1
+fi
+
 grep '^FAIL:' "$now_s" | sed 's/^[^:]*:[   ]//' >$tmp1
 grep '^PASS' "$before_s" | sed 's/^[^:]*:[ ]//' | comm -12 $tmp1 - >$tmp2


[gcc r16-3660] [AutoFDO] Check count initialization to fix ICE with AutoFDO

2025-09-08 Thread Kugan Vivekanandarajah via Gcc-cvs
https://gcc.gnu.org/g:80b453d5e4b423730033fd15bc26075347dfd5ba

commit r16-3660-g80b453d5e4b423730033fd15bc26075347dfd5ba
Author: Kugan Vivekanandarajah 
Date:   Mon Sep 8 19:10:44 2025 +1000

[AutoFDO] Check count initialization to fix ICE with AutoFDO

Fix ICE with AutoFDO by adding initialization check
before accessing IPA counts to avoid issues with uninitialized profile
counts in self-recursive clone processing.

gcc/ChangeLog:

2025-09-08  Kugan Vivekanandarajah  

* ipa-cp.cc (gather_count_of_non_rec_edges): Check count
initialization before adding to total.

Signed-off-by: Kugan Vivekanandarajah 

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

diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 480cf48786c7..4f2030a8d8cb 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -4555,7 +4555,8 @@ gather_count_of_non_rec_edges (cgraph_node *node, void 
*data)
   gather_other_count_struct *desc = (gather_other_count_struct *) data;
   for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
 if (cs->caller != desc->orig && cs->caller->clone_of != desc->orig)
-  desc->other_count += cs->count.ipa ();
+  if (cs->count.ipa ().initialized_p ())
+   desc->other_count += cs->count.ipa ();
   return false;
 }


[gcc r16-3659] RISC-V: Add pattern for vector-scalar single-width floating-point reverse sub

2025-09-08 Thread Paul-Antoine Arras via Gcc-cvs
https://gcc.gnu.org/g:c2048dae34104a9e172eec6747ab59f4404fba2f

commit r16-3659-gc2048dae34104a9e172eec6747ab59f4404fba2f
Author: Paul-Antoine Arras 
Date:   Fri Sep 5 16:37:17 2025 +0200

RISC-V: Add pattern for vector-scalar single-width floating-point reverse 
sub

This pattern enables the combine pass (or late-combine, depending on the 
case)
to merge a vec_duplicate into a minus RTL instruction. The vec_duplicate is 
the
minuend operand.

Before this patch, we have two instructions, e.g.:
  vfmv.v.f   v2,fa0
  vfsub.vv   v1,v2,v1

After, we get only one:
  vfrsub.vf  v1,v1,fa0

gcc/ChangeLog:

* config/riscv/autovec-opt.md (*vfrsub_vf_): New pattern to
combine vec_duplicate + vfsub.vv into vfrsub.vf.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c: Add vfrsub.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_binop_data.h: Add data for
vfrsub.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfrsub-run-1-f16.c: New 
test.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfrsub-run-1-f32.c: New 
test.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfrsub-run-1-f64.c: New 
test.

Diff:
---
 gcc/config/riscv/autovec-opt.md|  20 +++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c  |   2 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c  |   1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c  |   1 +
 .../riscv/rvv/autovec/vx_vf/vf_binop_data.h| 147 +
 .../riscv/rvv/autovec/vx_vf/vf_vfrsub-run-1-f16.c  |  19 +++
 .../riscv/rvv/autovec/vx_vf/vf_vfrsub-run-1-f32.c  |  15 +++
 .../riscv/rvv/autovec/vx_vf/vf_vfrsub-run-1-f64.c  |  15 +++
 17 files changed, 234 insertions(+)

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index f4d13ca35684..1c1cf76995b4 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -2207,3 +2207,23 @@
   }
   [(set_attr "type" "vfalu")]
 )
+
+;; vfrsub.vf
+(define_insn_and_split "*vfrsub_vf_"
+  [(set (match_operand:V_VLSF 0 "register_operand")
+(minus:V_VLSF
+  (vec_duplicate:V_VLSF
+(match_operand: 2 "register_operand"))
+  (match_operand:V_VLSF 1 "register_operand")))]
+  "TARGET_VECTOR && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
+  {
+riscv_vector::emit_vlmax_insn (code_for_pred_reverse_scalar (MINUS,
+mode),
+  riscv_vector::BINARY_OP_FRM_DYN, operands);
+DONE;
+  }
+  [(set_attr "type" "vfalu")]
+)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
index 002d091c3adc..53969931032e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
@@ -20,6 +20,7 @@ DEF_VF_BINOP_CASE_0 (_Float16, *, mul)
 DEF_VF_BINOP_CASE_0 (_Float16, +, add)
 DEF_VF_BINOP_CASE_0 (_Float16, -, sub)
 DEF_VF_BINOP_REVERSE_CASE_0 (_Float16, /, rdiv)
+DEF_VF_BINOP_REVERSE_CASE_0 (_Float16, -, rsub)
 DEF_VF_BINOP_CASE_2_WRAP (_Float16, MIN_FUNC_0_WRAP (_Float16), min)
 DEF_VF_BINOP_CASE_2_WRAP (_Float16, MIN_FUNC_1_WRAP (_Float16), min)
 DEF_VF_BINOP_CASE_2_WRAP (_Float16, MAX_FUNC_0_WRAP (_Float16), max)
@@ -42,6 +43,7 @@ DEF_VF_BINOP_WIDEN_CASE_0 (_Float16, float, *, mul)
 /* { dg-final { scan-assembler-times {vfadd.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfsub.vf} 1 } } */
 /* { dg-final { scan-assembler-times

[gcc r16-3652] doc: Remove references to Binutils 2.7 requirements

2025-09-08 Thread Gerald Pfeifer via Gcc-cvs
https://gcc.gnu.org/g:e394c5d84b314803e0160570b8e7a422dc3c1935

commit r16-3652-ge394c5d84b314803e0160570b8e7a422dc3c1935
Author: Gerald Pfeifer 
Date:   Sun Sep 7 01:40:06 2025 +0200

doc: Remove references to Binutils 2.7 requirements

GNU Binutils 2.7 was released in 1996, no realistic need to point it
out as a minimal requirement.

gcc:
* doc/extend.texi (SH Function Attributes): Remove reference to
GNU Binutils 2.7 requirement.
(H8/300 Variable Attributes): Ditto.

Diff:
---
 gcc/doc/extend.texi | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 3c11928fd764..2922d9e9839f 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -5904,8 +5904,7 @@ accordingly to point to the start of the vector table 
before any functions with
 this attribute are invoked.  Usually a good place to do the initialization is
 the startup routine.  The TBR relative vector table can have at max 256 
function
 entries.  The jumps to these functions are generated using a SH2A specific,
-non delayed branch instruction JSR/N @@(disp8,TBR).  You must use GAS and GLD
-from GNU binutils version 2.7 or later for this attribute to work correctly.
+non delayed branch instruction JSR/N @@(disp8,TBR).
 
 In an application, for a function being called once, this attribute
 saves at least 8 bytes of code; and if other successive calls are being
@@ -7925,9 +7924,6 @@ The compiler generates more efficient code for certain 
operations
 on data in the eight-bit data area.  Note the eight-bit data area is limited to
 256 bytes of data.
 
-You must use GAS and GLD from GNU binutils version 2.7 or later for
-this attribute to work correctly.
-
 @cindex @code{tiny_data} variable attribute, H8/300
 @cindex tiny data section on the H8/300H and H8S
 @item tiny_data


[gcc r16-3665] RISC-V: Add pattern for vector-scalar widening floating-point add

2025-09-08 Thread Paul-Antoine Arras via Gcc-cvs
https://gcc.gnu.org/g:2abfcc6cfc9cd82fbbef47f2b03ee7595277023e

commit r16-3665-g2abfcc6cfc9cd82fbbef47f2b03ee7595277023e
Author: Paul-Antoine Arras 
Date:   Fri Sep 5 18:49:24 2025 +0200

RISC-V: Add pattern for vector-scalar widening floating-point add

This pattern enables the combine pass (or late-combine, depending on the 
case)
to merge a float_extend'ed vec_duplicate into a plus RTL instruction.

Before this patch, we have four instructions, e.g.:
  fcvt.d.sfa0,fa0
  vsetvli a5,zero,e64,m1,ta,ma
  vfmv.v.fv3,fa0
  vfwadd.wv   v1,v3,v2

After, we get only one:
  vfwadd.vf   v1,v2,fa0

gcc/ChangeLog:

* config/riscv/autovec-opt.md (*vfwadd_vf_): New pattern to
combine float_extend + vec_duplicate + vfwadd.vv into vfwadd.vf.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c: Add vfwadd.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h
(DEF_VF_BINOP_WIDEN_CASE_0): Fix OP.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f16.c: New 
test.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f32.c: New 
test.

Diff:
---
 gcc/config/riscv/autovec-opt.md| 23 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c  |  3 ++-
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c  |  3 ++-
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c  |  1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c  |  1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h  |  2 +-
 .../riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f16.c  | 20 +++
 .../riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f32.c  | 16 +++
 12 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index 1c1cf76995b4..dbbade34dce3 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -2170,6 +2170,29 @@
   [(set_attr "type" "vfwmul")]
 )
 
+;; vfwadd.vf
+(define_insn_and_split "*vfwadd_vf_"
+  [(set (match_operand:VWEXTF 0 "register_operand")
+(plus:VWEXTF
+  (float_extend:VWEXTF
+   (match_operand: 1 "register_operand"))
+  (vec_duplicate:VWEXTF
+   (float_extend:
+ (match_operand: 2 "register_operand")]
+  "TARGET_VECTOR && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
+  {
+riscv_vector::emit_vlmax_insn (code_for_pred_dual_widen_scalar (PLUS,
+   mode),
+  riscv_vector::BINARY_OP_FRM_DYN, operands);
+
+DONE;
+  }
+  [(set_attr "type" "vfwalu")]
+)
+
 ;; vfadd.vf
 (define_insn_and_split "*vfadd_vf_"
   [(set (match_operand:V_VLSF 0 "register_operand")
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
index 53969931032e..696b75080659 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
@@ -26,6 +26,7 @@ DEF_VF_BINOP_CASE_2_WRAP (_Float16, MIN_FUNC_1_WRAP 
(_Float16), min)
 DEF_VF_BINOP_CASE_2_WRAP (_Float16, MAX_FUNC_0_WRAP (_Float16), max)
 DEF_VF_BINOP_CASE_2_WRAP (_Float16, MAX_FUNC_1_WRAP (_Float16), max)
 DEF_VF_BINOP_WIDEN_CASE_0 (_Float16, float, *, mul)
+DEF_VF_BINOP_WIDEN_CASE_0 (_Float16, float, +, add)
 
 /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */
@@ -47,3 +48,4 @@ DEF_VF_BINOP_WIDEN_CASE_0 (_Float16, float, *, mul)
 /* { dg-final { scan-assembler-times {vfmin.vf} 2 } } */
 /* { dg-final { scan-assembler-times {vfmax.vf} 2 } } */
 /* { dg-final { scan-assembler-times {vfwmul.vf} 1 } } */
+/* { dg-final { scan-assembler-times {vfwadd.vf} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c
index 9756184347b4..7f746d8eb6aa 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c
@@ -26,6 +26,7 @@

[gcc r16-3668] libstdc++: Make syncbuf _S_get_mutex definition extern.

2025-09-08 Thread Nathan Myers via Gcc-cvs
https://gcc.gnu.org/g:4eb12ddd32d53ef55c2bd9bb03db057f096fff8f

commit r16-3668-g4eb12ddd32d53ef55c2bd9bb03db057f096fff8f
Author: Nathan Myers 
Date:   Thu Aug 28 13:11:57 2025 -0400

libstdc++: Make syncbuf _S_get_mutex definition extern.

This patch creates a global function __syncbuf_get_mutex, gated by
_GLIBCXX_HAS_GTHREADS, replacing a static instantiated member
_S_get_mutex used in syncbuf<> construction, and makes the global
symbol visible. A static local table of 16 mutexes is shared among
all specializations of syncbuf<>, chosen on construction by a hash
of the wrapped streambuf's address.

It detaches the implementation of _S_get_mutex from the C++20 ABI.

libstdc++-v3/ChangeLog:
* include/std/syncstream: (syncbuf<>::__mutex) Remove _S_get_mutex,
use extern function instead.
* src/c++20/syncbuf.cc: Define global __syncbuf_get_mutex.
* src/c++20/Makefile.am: Mention syncbuf.cc.
* src/c++20/Makefile.in: Regenerate.
* config/abi/pre/gnu.ver: Mention mangled __syncbuf_get_mutex.

Diff:
---
 libstdc++-v3/config/abi/pre/gnu.ver |  3 +++
 libstdc++-v3/include/std/syncstream | 22 +-
 libstdc++-v3/src/c++20/Makefile.am  |  2 +-
 libstdc++-v3/src/c++20/Makefile.in  |  2 +-
 libstdc++-v3/src/c++20/syncbuf.cc   | 45 +
 5 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver 
b/libstdc++-v3/config/abi/pre/gnu.ver
index e1601dc39d25..2e48241d51f9 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -2559,6 +2559,9 @@ GLIBCXX_3.4.35 {
 _ZNSt6chrono9gps_clock3nowEv;
 _ZNSt6chrono9tai_clock3nowEv;
 
+# mutex& __syncbuf_get_mutex(void*)
+_ZSt19__syncbuf_get_mutexPv;
+
 # __gnu_debug::_Safe_iterator_base and _Safe_sequence_base const
 
_ZN11__gnu_debug19_Safe_iterator_base9_M_attachEPKNS_19_Safe_sequence_baseEb;
 
_ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPKNS_19_Safe_sequence_baseEb;
diff --git a/libstdc++-v3/include/std/syncstream 
b/libstdc++-v3/include/std/syncstream
index e2b5a199ec93..92fbbdc760e7 100644
--- a/libstdc++-v3/include/std/syncstream
+++ b/libstdc++-v3/include/std/syncstream
@@ -46,7 +46,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -199,11 +198,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   struct __mutex
   {
 #if _GLIBCXX_HAS_GTHREADS
-   mutex* _M_mtx;
+   mutex* _M_mtx = nullptr;
 
-   __mutex(void* __t)
- : _M_mtx(__t ? &_S_get_mutex(__t) : nullptr)
-   { }
+   __mutex(void* __t)  // __t is the underlying sbuf, as hash seed.
+   { 
+ extern mutex& __syncbuf_get_mutex(void*);  // in src/c++20/syncbuf.cc
+ if (__t) _M_mtx = &__syncbuf_get_mutex(__t);
+   }
 
void
swap(__mutex& __other) noexcept
@@ -220,17 +221,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
  _M_mtx->unlock();
}
-
-   // FIXME: This should be put in the .so
-   static mutex&
-   _S_get_mutex(void* __t)
-   {
- const unsigned char __mask = 0xf;
- static mutex __m[__mask + 1];
-
- auto __key = _Hash_impl::hash(__t) & __mask;
- return __m[__key];
-   }
 #else
__mutex(void*) { }
void swap(__mutex&&) noexcept { }
diff --git a/libstdc++-v3/src/c++20/Makefile.am 
b/libstdc++-v3/src/c++20/Makefile.am
index 736558ff24a7..384990aed776 100644
--- a/libstdc++-v3/src/c++20/Makefile.am
+++ b/libstdc++-v3/src/c++20/Makefile.am
@@ -36,7 +36,7 @@ else
 inst_sources =
 endif
 
-sources = tzdb.cc format.cc atomic.cc clock.cc
+sources = tzdb.cc format.cc atomic.cc clock.cc syncbuf.cc
 
 vpath % $(top_srcdir)/src/c++20
 
diff --git a/libstdc++-v3/src/c++20/Makefile.in 
b/libstdc++-v3/src/c++20/Makefile.in
index 3cb6d6fea5f3..1e005ae3c14e 100644
--- a/libstdc++-v3/src/c++20/Makefile.in
+++ b/libstdc++-v3/src/c++20/Makefile.in
@@ -432,7 +432,7 @@ headers =
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@  sstream-inst.cc
 
-sources = tzdb.cc format.cc atomic.cc clock.cc
+sources = tzdb.cc format.cc atomic.cc clock.cc syncbuf.cc
 @GLIBCXX_HOSTED_FALSE@libc__20convenience_la_SOURCES = 
 @GLIBCXX_HOSTED_TRUE@libc__20convenience_la_SOURCES = $(sources)  
$(inst_sources)
 
diff --git a/libstdc++-v3/src/c++20/syncbuf.cc 
b/libstdc++-v3/src/c++20/syncbuf.cc
new file mode 100644
index ..150ba5e3ce4d
--- /dev/null
+++ b/libstdc++-v3/src/c++20/syncbuf.cc
@@ -0,0 +1,45 @@
+// Explicit instantiation file.
+
+// Copyright (C) 2020-2025 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3,

[gcc r16-3662] tree-optimization/121829 - bogus CFG with asm goto

2025-09-08 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:a632becefad29206a980cc080eee74ed808f9cd3

commit r16-3662-ga632becefad29206a980cc080eee74ed808f9cd3
Author: Richard Biener 
Date:   Mon Sep 8 12:40:30 2025 +0200

tree-optimization/121829 - bogus CFG with asm goto

When the vectorizer removes a forwarder created earlier by split_edge
it uses redirect_edge_pred for convenience and efficiency.  That breaks
down when the edge split is originating from an asm goto as that is
a jump that needs adjustments from redirect_edge_and_branch.  The
following factores a simple vect_remove_forwarder handling this
situation appropriately.

PR tree-optimization/121829
* tree-vect-loop-manip.cc (vect_remove_forwarder): New
function.
(slpeel_tree_duplicate_loop_to_edge_cfg): Use it.

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

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr121829.c | 21 +
 gcc/tree-vect-loop-manip.cc | 33 ++---
 2 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr121829.c 
b/gcc/testsuite/gcc.dg/torture/pr121829.c
new file mode 100644
index ..afcf7595a73d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr121829.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+int a[1][1];
+int *b(int *);
+int c() {
+  int *d[4];
+  int **e = &d[3];
+  int f;
+  for (; f; f++)
+d[f] = &a[1][0];
+  b(*e);
+}
+int *b(int *g) {
+  asm goto("" : : : : h);
+  int i[9];
+h:
+  int f;
+  for (f = 0; f < 9; f++)
+i[f] = 1;
+  *g = i[4];
+}
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 20141dbc2e54..7af70a51335f 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -1459,6 +1459,21 @@ get_live_virtual_operand_on_edge (edge e)
   while (1);
 }
 
+/* Remove the single succ/pred forwarder block BB.  */
+
+static void
+vect_remove_forwarder (basic_block bb)
+{
+  edge pred = single_pred_edge (bb);
+  edge succ = single_succ_edge (bb);
+  basic_block to = single_succ (bb);
+  edge e = redirect_edge_and_branch (pred, to);
+  gcc_assert  (e == pred);
+  copy_phi_arg_into_existing_phi (succ, e);
+  delete_basic_block (bb);
+  set_immediate_dominator (CDI_DOMINATORS, to, pred->src);
+}
+
 /* Given LOOP this function generates a new copy of it and puts it
on E which is either the entry or exit of LOOP.  If SCALAR_LOOP is
non-NULL, assume LOOP and SCALAR_LOOP are equivalent and copy the
@@ -1858,11 +1873,7 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop 
*loop, edge loop_exit,
 
   /* And remove the non-necessary forwarder again.  Keep the other
  one so we have a proper pre-header for the loop at the exit edge.  */
-  redirect_edge_pred (single_succ_edge (preheader),
- single_pred (preheader));
-  delete_basic_block (preheader);
-  set_immediate_dominator (CDI_DOMINATORS, scalar_loop->header,
-  loop_preheader_edge (scalar_loop)->src);
+  vect_remove_forwarder (preheader);
 
   /* Finally after wiring the new epilogue we need to update its main exit
 to the original function exit we recorded.  Other exits are already
@@ -1920,11 +1931,7 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop 
*loop, edge loop_exit,
   if (scalar_loop != loop)
{
  /* Remove the non-necessary forwarder of scalar_loop again.  */
- redirect_edge_pred (single_succ_edge (preheader),
- single_pred (preheader));
- delete_basic_block (preheader);
- set_immediate_dominator (CDI_DOMINATORS, scalar_loop->header,
-  loop_preheader_edge (scalar_loop)->src);
+ vect_remove_forwarder (preheader);
  preheader = split_edge (loop_preheader_edge (loop));
  entry_e = single_pred_edge (preheader);
}
@@ -1939,11 +1946,7 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop 
*loop, edge loop_exit,
 
   /* And remove the non-necessary forwarder again.  Keep the other
  one so we have a proper pre-header for the loop at the exit edge.  */
-  redirect_edge_pred (single_succ_edge (new_preheader),
- single_pred (new_preheader));
-  delete_basic_block (new_preheader);
-  set_immediate_dominator (CDI_DOMINATORS, new_loop->header,
-  loop_preheader_edge (new_loop)->src);
+  vect_remove_forwarder (new_preheader);
 
   /* Update dominators for multiple exits.  */
   if (multiple_exits_p)


[gcc r16-3664] RISC-V: Adjust tt-ascalon-d8 branch cost

2025-09-08 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:11171cb98098e0a6438a5c2f964f5d45f2127b76

commit r16-3664-g11171cb98098e0a6438a5c2f964f5d45f2127b76
Author: Anton Blanchard 
Date:   Mon Sep 8 07:36:39 2025 -0600

RISC-V: Adjust tt-ascalon-d8 branch cost

If-conversion isn't being applied to this nbench code:

 #include 
 #define INTERNAL_FPF_PRECISION 4
 typedef uint16_t u16;

 void ShiftMantLeft1(u16 *carry, u16 *mantissa)
 {
 int i;
 int new_carry;
 u16 accum;

 for(i=INTERNAL_FPF_PRECISION-1;i>=0;i--)
 {   accum=mantissa[i];
 new_carry=accum & 0x8000;
 accum=accum<<1;
 if(*carry)
 accum|=1;
 *carry=new_carry;
 mantissa[i]=accum;
 }
 return;
 }

Bumping branch_cost from 3 to 4 triggers if-conversion, improving the
nbench FP EMULATION result on Ascalon significantly. There's a risk
that more aggressive use of conditional zero instructions will negatively
impact workloads that predict well, but we haven't seen anything obvious.

gcc/ChangeLog:
* config/riscv/riscv.cc (tt_ascalon_d8_tune_info): Increase 
branch_cost
from 3 to 4.

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

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 07d40f459e36..bfd43fba1013 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -659,7 +659,7 @@ static const struct riscv_tune_param 
tt_ascalon_d8_tune_info = {
   {COSTS_N_INSNS (3), COSTS_N_INSNS (3)},  /* int_mul */
   {COSTS_N_INSNS (13), COSTS_N_INSNS (13)},/* int_div */
   8,   /* issue_rate */
-  3,   /* branch_cost */
+  4,   /* branch_cost */
   4,   /* memory_cost */
   4,   /* fmv_cost */
   false,   /* slow_unaligned_access */


[gcc r16-3666] tree-optimization/121844 - IVOPTs and asm goto in latch

2025-09-08 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:00cd34b1046076a3272f8e8e85c97dc8f4d2ea44

commit r16-3666-g00cd34b1046076a3272f8e8e85c97dc8f4d2ea44
Author: Richard Biener 
Date:   Mon Sep 8 14:32:38 2025 +0200

tree-optimization/121844 - IVOPTs and asm goto in latch

When there's an asm goto in the latch of a loop we may not use
IP_END IVs since instantiating those would (need to) split the
latch edge which in turn invalidates IP_NORMAL position handling.
This is a revision of the PR107997 fix.

PR tree-optimization/107997
PR tree-optimization/121844
* tree-ssa-loop-ivopts.cc (allow_ip_end_pos_p): Do not allow
IP_END for latches ending with a control stmt.
(create_new_iv): Do not split the latch edge, instead assert
that's not necessary.

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

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr121844.c | 16 
 gcc/tree-ssa-loop-ivopts.cc | 13 +++--
 2 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr121844.c 
b/gcc/testsuite/gcc.dg/torture/pr121844.c
new file mode 100644
index ..149d5eaab642
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr121844.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+typedef unsigned long a;
+int b[] = {};
+int **c;
+short d(a *e, int f)
+{
+  *c = &f;
+  for (;;)
+asm goto("" : : : : g);
+  for (; f; f--) {
+asm goto("" : : : : g);
+  g:
+*e ^= b[f + 1];
+  }
+}
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index 2fe2655220b7..ba727adc808d 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -3200,6 +3200,12 @@ add_candidate_1 (struct ivopts_data *data, tree base, 
tree step, bool important,
 static bool
 allow_ip_end_pos_p (class loop *loop)
 {
+  /* Do not allow IP_END when creating the IV would need to split the
+ latch edge as that makes all IP_NORMAL invalid.  */
+  auto pos = gsi_last_bb (ip_end_pos (loop));
+  if (!gsi_end_p (pos) && stmt_ends_bb_p (*pos))
+return false;
+
   if (!ip_normal_pos (loop))
 return true;
 
@@ -7222,12 +7228,7 @@ create_new_iv (struct ivopts_data *data, struct iv_cand 
*cand)
 case IP_END:
   incr_pos = gsi_last_bb (ip_end_pos (data->current_loop));
   after = true;
-  if (!gsi_end_p (incr_pos) && stmt_ends_bb_p (gsi_stmt (incr_pos)))
-   {
- edge e = find_edge (gsi_bb (incr_pos), data->current_loop->header);
- incr_pos = gsi_after_labels (split_edge (e));
- after = false;
-   }
+  gcc_assert (gsi_end_p (incr_pos) || !stmt_ends_bb_p (*incr_pos));
   break;
 
 case IP_AFTER_USE:


[gcc r15-10297] RISC-V: Check if we can vec_extract [PR121510].

2025-09-08 Thread Robin Dapp via Gcc-cvs
https://gcc.gnu.org/g:1c824f038848870219105a5fa16c48a2e0746643

commit r15-10297-g1c824f038848870219105a5fa16c48a2e0746643
Author: Robin Dapp 
Date:   Fri Sep 5 09:35:46 2025 +0200

RISC-V: Check if we can vec_extract [PR121510].

For Zvfhmin a vector mode exists but the corresponding vec_extract does
not.  This patch checks that a vec_extract is available and otherwise
falls back to standard handling.

PR target/121510

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_legitimize_move): Check if we can
vec_extract.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/pr121510.c: New test.

(cherry picked from commit a6bf07653cd272add46a2218ec141c95d7f02427)

Diff:
---
 gcc/config/riscv/riscv.cc |  3 ++-
 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr121510.c | 18 ++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 031584a437a9..472c2e60d9f5 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3596,7 +3596,8 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx 
src)
   /* This test can fail if (for example) we want a HF and Z[v]fh is
 not enabled.  In that case we just want to let the standard
 expansion path run.  */
-  if (riscv_vector::get_vector_mode (smode, nunits).exists (&vmode))
+  if (riscv_vector::get_vector_mode (smode, nunits).exists (&vmode)
+ && convert_optab_handler (vec_extract_optab, vmode, smode))
{
  rtx v = gen_lowpart (vmode, SUBREG_REG (src));
  rtx int_reg = dest;
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr121510.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr121510.c
new file mode 100644
index ..8e1728608d3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr121510.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3" } */
+
+long *print_bfloat_block;
+void ftoastr(float);
+void print_bfloat() {
+  for (;;) {
+long j;
+union {
+  _Float16 x;
+  char b[]
+} u;
+j = 0;
+for (; j < sizeof 0; j++)
+  u.b[j] = print_bfloat_block[j];
+ftoastr(u.x);
+  }
+}


[gcc r16-3654] libstdc++: Fix up [PR121827]

2025-09-08 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:592bafb26eb1fd50979f6cdf2176897c4a02c281

commit r16-3654-g592bafb26eb1fd50979f6cdf2176897c4a02c281
Author: Jakub Jelinek 
Date:   Mon Sep 8 11:49:58 2025 +0200

libstdc++: Fix up  [PR121827]

During the tests mentioned in
https://gcc.gnu.org/pipermail/gcc-patches/2025-August/692482.html
(but dunno why I haven't noticed it back in August but only when testing
https://gcc.gnu.org/pipermail/gcc-patches/2025-September/694527.html )
I've noticed two ext header problems.
One is that #include  got broken with the
r13-3037-g18f176d0b25591e28 change and since then is no longer
self-contained, as it includes iosfwd only if _GLIBCXX_HOSTED is defined
but doesn't actually include bits/c++config.h to make sure it is defined,
then includes a bunch of headers which do include bits/c++config.h and
finally uses in #if _GLIBCXX_HOSTED guarded code what is declared in iosfwd.
The other problem is that ext/cast.h is also not a self-contained header,
but that one has
/** @file ext/cast.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{ext/pointer.h}
 */
comment, so I think we just shouldn't include it in extc++.h and let
ext/pointer.h include it.

2025-09-08  Jakub Jelinek  

PR libstdc++/121827
* include/precompiled/extc++.h: Don't include ext/cast.h which is an
internal header.
* include/ext/pointer.h: Include bits/c++config.h before
#if _GLIBCXX_HOSTED.

Diff:
---
 libstdc++-v3/include/ext/pointer.h| 1 +
 libstdc++-v3/include/precompiled/extc++.h | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/ext/pointer.h 
b/libstdc++-v3/include/ext/pointer.h
index 700c9a1685af..5feb9f052344 100644
--- a/libstdc++-v3/include/ext/pointer.h
+++ b/libstdc++-v3/include/ext/pointer.h
@@ -40,6 +40,7 @@
 #pragma GCC system_header
 #endif
 
+#include 
 #if _GLIBCXX_HOSTED
 #  include 
 #endif
diff --git a/libstdc++-v3/include/precompiled/extc++.h 
b/libstdc++-v3/include/precompiled/extc++.h
index cc6e5e52a642..9d41656f2803 100644
--- a/libstdc++-v3/include/precompiled/extc++.h
+++ b/libstdc++-v3/include/precompiled/extc++.h
@@ -37,7 +37,6 @@
 #endif
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 


[gcc r16-3667] testsuite: Another fixup for fixed-point/bitint-1.c test

2025-09-08 Thread Xi Ruoyao via Gcc-cvs
https://gcc.gnu.org/g:cdb76f4bee2943fdc7d1c00545fe396f90cbca64

commit r16-3667-gcdb76f4bee2943fdc7d1c00545fe396f90cbca64
Author: Xi Ruoyao 
Date:   Mon Sep 8 21:46:56 2025 +0800

testsuite: Another fixup for fixed-point/bitint-1.c test

Besides r16-3595, there's another bug in this test: with -std=c23 the
token _Sat isn't recognized as a keyword at all, thus an error massage
different from the expected will be outputted.

Fix it by using -std=gnu23 instead.

gcc/testsuite:

* gcc.dg/fixed-point/bitint-1.c (dg-options): Use -std=gnu23
instead of -std=c23.

Diff:
---
 gcc/testsuite/gcc.dg/fixed-point/bitint-1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/fixed-point/bitint-1.c 
b/gcc/testsuite/gcc.dg/fixed-point/bitint-1.c
index d87c125f4d65..dc843ff5b6b7 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/bitint-1.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/bitint-1.c
@@ -1,6 +1,6 @@
 /* PR c/102989 */
 /* { dg-do compile { target bitint } } */
-/* { dg-options "-std=c23" } */
+/* { dg-options "-std=gnu23" } */
 
 void
 foo (void)


[gcc r16-3655] RISC-V: Add patterns for vector-scalar IEEE floating-point max

2025-09-08 Thread Paul-Antoine Arras via Gcc-cvs
https://gcc.gnu.org/g:f8a1436462abb212e8de0d5bc5ccc0d9f9e0b974

commit r16-3655-gf8a1436462abb212e8de0d5bc5ccc0d9f9e0b974
Author: Paul-Antoine Arras 
Date:   Mon Sep 1 15:54:26 2025 +0200

RISC-V: Add patterns for vector-scalar IEEE floating-point max

These patterns enable the combine pass (or late-combine, depending on the 
case)
to merge a vec_duplicate into an unspec_vfmax RTL instruction.

Before this patch, we have two instructions, e.g.:
  vfmv.v.f   v2,fa0
  vfmax.vv   v1,v2,v1

After, we get only one:
  vfmax.vf   v1,v1,fa0

In some cases, it also shaves off one vsetvli.

gcc/ChangeLog:

* config/riscv/autovec-opt.md (*vfmin_vf_ieee_): Rename 
into...
(*v_vf_): New pattern to combine 
vec_duplicate +
vf{max,min}.vv (unspec) into vf{max,min}.vf.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/vx_vf/vf-5-f16.c: Add vfmax.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-5-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-5-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-6-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-6-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-6-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-7-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-7-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-7-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-8-f16.c: Add vfmax. Also add
missing -fno-fast-math.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-8-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-8-f64.c: Likewise.

Diff:
---
 gcc/config/riscv/autovec-opt.md| 14 --
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-5-f16.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-5-f32.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-5-f64.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-6-f16.c  |  1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-6-f32.c  |  1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-6-f64.c  |  1 +
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-7-f16.c  |  6 +-
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-7-f32.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-7-f64.c  |  2 ++
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-8-f16.c  |  3 ++-
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-8-f32.c  |  3 ++-
 .../gcc.target/riscv/rvv/autovec/vx_vf/vf-8-f64.c  |  3 ++-
 13 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index 328ee0e096fe..d2a89a5d63b4 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -2107,38 +2107,40 @@
   [(set_attr "type" "vfminmax")]
 )
 
-(define_insn_and_split "*vfmin_vf_ieee_"
+(define_insn_and_split "*v_vf_"
   [(set (match_operand:V_VLSF 0 "register_operand")
 (unspec:V_VLSF [
   (vec_duplicate:V_VLSF
(match_operand: 2 "register_operand"))
   (match_operand:V_VLSF 1 "register_operand")
-  ] UNSPEC_VFMIN))]
+  ] UNSPEC_VFMAXMIN))]
   "TARGET_VECTOR && !HONOR_SNANS (mode) && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
   {
-riscv_vector::emit_vlmax_insn (code_for_pred_scalar (UNSPEC_VFMIN, 
mode),
+riscv_vector::emit_vlmax_insn (code_for_pred_scalar (,
+mode),
   riscv_vector::BINARY_OP, operands);
 DONE;
   }
   [(set_attr "type" "vfminmax")]
 )
 
-(define_insn_and_split "*vfmin_vf_ieee_"
+(define_insn_and_split "*v_vf_"
   [(set (match_operand:V_VLSF 0 "register_operand")
 (unspec:V_VLSF [
   (match_operand:V_VLSF 1 "register_operand")
   (vec_duplicate:V_VLSF
(match_operand: 2 "register_operand"))
-  ] UNSPEC_VFMIN))]
+  ] UNSPEC_VFMAXMIN))]
   "TARGET_VECTOR && !HONOR_SNANS (mode) && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
   {
-riscv_vector::emit_vlmax_insn (code_for_pred_scalar (UNSPEC_VFMIN, 
mode),
+riscv_vector::emit_vlmax_insn (code_for_pred_scalar (,
+mode),
   riscv_vector::BINARY_OP, operands);
 DONE;
   }
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-5-f16.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-5-f16.c
index 1a20ee78536b..ba8eec0bb7ce 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-5-f16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-5-f16.c
@@ -4,5 +4,7 @@
 #include "vf_binop.h"
 
 DEF_VF_BINOP_CASE_2_WRAP (_Float16, __builtin_fminf16, min)
+DEF_VF_BINOP_CASE_2_WRAP (_Float16, __builtin_fmaxf1

[gcc r16-3653] libstdc++: Update link to "Tunables" in Glibc manual

2025-09-08 Thread Gerald Pfeifer via Gcc-cvs
https://gcc.gnu.org/g:f6ff531d907d5de5a47d6eca503715b32962c966

commit r16-3653-gf6ff531d907d5de5a47d6eca503715b32962c966
Author: Gerald Pfeifer 
Date:   Mon Sep 8 11:07:25 2025 +0200

libstdc++: Update link to "Tunables" in Glibc manual

libstdc++-v3:
* doc/xml/manual/using_exceptions.xml: Update link to "Tunables"
section in the Glibc manual.
* doc/html/manual/using_exceptions.html: Regenerate.

Diff:
---
 libstdc++-v3/doc/html/manual/using_exceptions.html | 2 +-
 libstdc++-v3/doc/xml/manual/using_exceptions.xml   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/using_exceptions.html 
b/libstdc++-v3/doc/html/manual/using_exceptions.html
index 2da86be00f91..67b4365fbbc8 100644
--- a/libstdc++-v3/doc/html/manual/using_exceptions.html
+++ b/libstdc++-v3/doc/html/manual/using_exceptions.html
@@ -366,7 +366,7 @@ is called.
   GCC Bug 25191: exception_defines.h #defines try/catch

   . 
-   https://www.gnu.org/software/libc/manual/html_node/Tunables.html"; 
target="_top">
+   https://sourceware.org/glibc/manual/latest/html_mono/libc.html#Tunables"; 
target="_top">
   Tunables, The GNU C Library

   . Prev Up NextConcurrency Home Debugging 
Support
\ No newline at end of file
diff --git a/libstdc++-v3/doc/xml/manual/using_exceptions.xml 
b/libstdc++-v3/doc/xml/manual/using_exceptions.xml
index 3b4280298ebb..784c90c4a29f 100644
--- a/libstdc++-v3/doc/xml/manual/using_exceptions.xml
+++ b/libstdc++-v3/doc/xml/manual/using_exceptions.xml
@@ -622,7 +622,7 @@ is called.
   
   
http://www.w3.org/1999/xlink";
- 
xlink:href="https://www.gnu.org/software/libc/manual/html_node/Tunables.html";>
+ 
xlink:href="https://sourceware.org/glibc/manual/latest/html_mono/libc.html#Tunables";>
   Tunables, The GNU C Library

   


[gcc(refs/users/meissner/heads/work221-sha)] Update ChangeLog.*

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:440276a1e1117e1ce26b39e6d28b2e07b584d1b9

commit 440276a1e1117e1ce26b39e6d28b2e07b584d1b9
Author: Michael Meissner 
Date:   Mon Sep 8 16:05:57 2025 -0400

Update ChangeLog.*

Diff:
---
 gcc/ChangeLog.sha | 2426 +
 1 file changed, 2426 insertions(+)

diff --git a/gcc/ChangeLog.sha b/gcc/ChangeLog.sha
index 0af4cdd11faf..2629fb9271e2 100644
--- a/gcc/ChangeLog.sha
+++ b/gcc/ChangeLog.sha
@@ -1,3 +1,2429 @@
+ Branch work221-sha, patch #445 
+
+PR target/117251: Add tests
+
+This is patch #45 of 45 to generate the 'XXEVAL' instruction on power10
+and power11 instead of using the Altivec 'VAND' instruction feeding
+into 'VNAND'.  The 'XXEVAL' instruction can use all 64 vector
+registers, instead of the 32 registers that traditional Altivec vector
+instructions use.  By allowing all of the vector registers to be used,
+it reduces the amount of spilling that a large benchmark generated.
+
+This patch adds the tests for generating 'XXEVAL' to the testsuite.
+
+I have tested these patches on both big endian and little endian
+PowerPC servers, with no regressions.  Can I check these patchs into
+the trunk?
+
+2025-09-08  Michael Meissner  
+
+gcc/testsuite/
+
+   PR target/117251
+   * gcc.target/powerpc/p10-vector-fused-1.c: New test.
+   * gcc.target/powerpc/p10-vector-fused-2.c: Likewise.
+
+ Branch work221-sha, patch #444 
+
+PR target/117251: Improve vector and to vector nand fusion
+
+See the following post for a complete explanation of what the patches
+for PR target/117251:
+
+ * https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686474.html
+
+This is patch #44 of 45 to generate the 'XXEVAL' instruction on power10
+and power11 instead of using the Altivec 'VAND' instruction feeding
+into 'VNAND'.  The 'XXEVAL' instruction can use all 64 vector
+registers, instead of the 32 registers that traditional Altivec vector
+instructions use.  By allowing all of the vector registers to be used,
+it reduces the amount of spilling that a large benchmark generated.
+
+Currently the following code:
+
+   vector int a, b, c, d;
+   a = ~ ((c & d) & b);
+
+Generates:
+
+   vand   t,c,d
+   vnand  a,t,b
+
+Now in addition with this patch, if the arguments or result is
+allocated to a traditional FPR register, the GCC compiler will now
+generate the following code instead of adding vector move instructions:
+
+   xxeval a,b,c,254
+
+Since fusion using 2 Altivec instructions is slightly faster than using
+the 'XXEVAL' instruction we prefer to generate the Altivec instructions
+if we can.  In addition, because 'XXEVAL' is a prefixed instruction, it
+possibly might generate an extra NOP instruction to align the 'XXEVAL'
+instruction.
+
+I have tested these patches on both big endian and little endian
+PowerPC servers, with no regressions.  Can I check these patchs into
+the trunk?
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   PR target/117251
+   * config/rs6000/fusion.md: Regenerate.
+   * config/rs6000/genfusion.pl (gen_logical_addsubf): Add support
+   to generate vector and => nand fusion if XXEVAL is supported.
+
+ Branch work221-sha, patch #443 
+
+PR target/117251: Improve vector andc to vector nand fusion
+
+See the following post for a complete explanation of what the patches
+for PR target/117251:
+
+ * https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686474.html
+
+This is patch #43 of 45 to generate the 'XXEVAL' instruction on power10
+and power11 instead of using the Altivec 'VANDC' instruction feeding
+into 'VNAND'.  The 'XXEVAL' instruction can use all 64 vector
+registers, instead of the 32 registers that traditional Altivec vector
+instructions use.  By allowing all of the vector registers to be used,
+it reduces the amount of spilling that a large benchmark generated.
+
+Currently the following code:
+
+   vector int a, b, c, d;
+   a = ~ ((c & ~ d) & b);
+
+Generates:
+
+   vandc  t,c,d
+   vnand  a,t,b
+
+Now in addition with this patch, if the arguments or result is
+allocated to a traditional FPR register, the GCC compiler will now
+generate the following code instead of adding vector move instructions:
+
+   xxeval a,b,c,253
+
+Since fusion using 2 Altivec instructions is slightly faster than using
+the 'XXEVAL' instruction we prefer to generate the Altivec instructions
+if we can.  In addition, because 'XXEVAL' is a prefixed instruction, it
+possibly might generate an extra NOP instruction to align the 'XXEVAL'
+instruction.
+
+I have tested these patches on both big endian and little endian
+PowerPC servers, with no regressions.  Can I check these patchs into
+the trunk?
+
+2025-09-08  Michael Meissner  
+
+gcc/
+
+   PR target/117251
+   * config/rs6000/fusion.md: Regenerate.
+   * config/rs6000/genfusion.pl (gen_logical_ad

[gcc(refs/users/meissner/heads/work221-sha)] PR target/117251: Improve vector and to vector or fusion

2025-09-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:58896353b55ca7c4ff7e0029cd4c65bc57519726

commit 58896353b55ca7c4ff7e0029cd4c65bc57519726
Author: Michael Meissner 
Date:   Mon Sep 8 15:19:20 2025 -0400

PR target/117251: Improve vector and to vector or fusion

See the following post for a complete explanation of what the patches
for PR target/117251:

 * https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686474.html

This is patch #12 of 45 to generate the 'XXEVAL' instruction on power10
and power11 instead of using the Altivec 'VAND' instruction feeding
into 'VOR'.  The 'XXEVAL' instruction can use all 64 vector registers,
instead of the 32 registers that traditional Altivec vector
instructions use.  By allowing all of the vector registers to be used,
it reduces the amount of spilling that a large benchmark generated.

Currently the following code:

vector int a, b, c, d;
a = (c & d) | b;

Generates:

vand   t,c,d
vora,t,b

Now in addition with this patch, if the arguments or result is
allocated to a traditional FPR register, the GCC compiler will now
generate the following code instead of adding vector move instructions:

xxeval a,b,c,31

Since fusion using 2 Altivec instructions is slightly faster than using
the 'XXEVAL' instruction we prefer to generate the Altivec instructions
if we can.  In addition, because 'XXEVAL' is a prefixed instruction, it
possibly might generate an extra NOP instruction to align the 'XXEVAL'
instruction.

I have tested these patches on both big endian and little endian
PowerPC servers, with no regressions.  Can I check these patchs into
the trunk?

2025-09-08  Michael Meissner  

gcc/

PR target/117251
* config/rs6000/fusion.md: Regenerate.
* config/rs6000/genfusion.pl (gen_logical_addsubf): Add support
to generate vector and => or fusion if XXEVAL is supported.

Diff:
---
 gcc/config/rs6000/fusion.md| 15 +--
 gcc/config/rs6000/genfusion.pl |  1 +
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
index 789a4d592419..fccea39d0aae 100644
--- a/gcc/config/rs6000/fusion.md
+++ b/gcc/config/rs6000/fusion.md
@@ -2621,20 +2621,23 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vand -> vor
 (define_insn "*fuse_vand_vor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-(ior:VM (and:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-  (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
- (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+(ior:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+  (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+ (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
vand %3,%1,%0\;vor %3,%3,%2
vand %3,%1,%0\;vor %3,%3,%2
vand %3,%1,%0\;vor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,31
vand %4,%1,%0\;vor %3,%4,%2"
   [(set_attr "type" "fused_vector")
(set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vandc -> vor
diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index e6d44d430b3a..ab714b10f622 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -226,6 +226,7 @@ sub gen_logical_addsubf
   "vnand_vand"  =>  14,
   "vnand_vnor"  =>  16,
   "vand_vxor"   =>  30,
+  "vand_vor"=>  31,
 );
 
 KIND: foreach $kind ('scalar','vector') {


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Sauvegarde/restoration cfun

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:e010ae370a6dfbd43531a7821b2d24da96b6fbf9

commit e010ae370a6dfbd43531a7821b2d24da96b6fbf9
Author: Mikael Morin 
Date:   Tue Jul 8 13:13:25 2025 +0200

Sauvegarde/restoration cfun

Correction bootstrap

Correction bootstrap

Correction bootstrap

Diff:
---
 gcc/gimple-simulate.cc | 8 
 1 file changed, 8 insertions(+)

diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc
index a85e6f63cc92..09491076e95d 100644
--- a/gcc/gimple-simulate.cc
+++ b/gcc/gimple-simulate.cc
@@ -4720,7 +4720,9 @@ simul_scope_evaluate_tests ()
   DECL_CONTEXT (result) = func;
   DECL_RESULT (func) = result;
 
+  push_cfun (nullptr);
   init_lowered_empty_function (func, true, profile_count::one ());
+  pop_cfun ();
 
   tree def_var = create_var (integer_type_node, "def_var");
   DECL_CONTEXT (def_var) = func;
@@ -6482,8 +6484,10 @@ simul_scope_simulate_call_tests ()
   DECL_CONTEXT (result) = my_int_func;
   DECL_RESULT (my_int_func) = result;
 
+  push_cfun (nullptr);
   basic_block bb = init_lowered_empty_function (my_int_func, true,
profile_count::one ());
+  pop_cfun ();
   gimple_stmt_iterator gsi = gsi_last_bb (bb);
   greturn *ret_stmt = gimple_build_return (cst6);
   gsi_insert_after (&gsi, ret_stmt, GSI_CONTINUE_LINKING);
@@ -6534,8 +6538,10 @@ simul_scope_simulate_call_tests ()
   DECL_ARGUMENTS (int_func_with_arg) = arg;
   layout_decl (arg, 0);
 
+  push_cfun (nullptr);
   basic_block bb2 = init_lowered_empty_function (int_func_with_arg, true,
 profile_count::one ());
+  pop_cfun ();
   gimple_stmt_iterator gsi2 = gsi_last_bb (bb2);
   greturn *ret_stmt2 = gimple_build_return (arg);
   gsi_insert_after (&gsi2, ret_stmt2, GSI_CONTINUE_LINKING);
@@ -6618,7 +6624,9 @@ simul_scope_simulate_call_tests ()
   DECL_CONTEXT (void_result) = simple_func;
   DECL_RESULT (simple_func) = void_result;
 
+  push_cfun (nullptr);
   init_lowered_empty_function (simple_func, true, profile_count::one ());
+  pop_cfun ();
 
   gcall * simple_call = gimple_build_call (simple_func, 0);


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: Prise en charge VIEW_CONVERT_EXPR

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:3f34601b09e865a4918c863da974456794f16bef

commit 3f34601b09e865a4918c863da974456794f16bef
Author: Mikael Morin 
Date:   Tue Jul 29 11:06:05 2025 +0200

gimple-simulate: Prise en charge VIEW_CONVERT_EXPR

Diff:
---
 gcc/gimple-simulate.cc | 49 +
 1 file changed, 49 insertions(+)

diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc
index 910e75ace858..1f7492fae06a 100644
--- a/gcc/gimple-simulate.cc
+++ b/gcc/gimple-simulate.cc
@@ -2289,6 +2289,9 @@ simul_scope::decompose_ref (tree data_ref, data_storage * 
& storage,
  parent_data_ref = TREE_OPERAND (data_ref, 0);
  break;
 
+   case VIEW_CONVERT_EXPR:
+ return decompose_ref (TREE_OPERAND (data_ref, 0), storage, offset);
+
default:
  gcc_unreachable ();
}
@@ -6429,6 +6432,52 @@ simul_scope_simulate_assign_tests ()
   ASSERT_EQ (TREE_CODE (wi12_real), REAL_CST);
   ASSERT_TRUE (real_equal (TREE_REAL_CST_PTR (wi12_real),
   TREE_REAL_CST_PTR (val33_12)));
+
+
+  tree derived13_1 = make_node (RECORD_TYPE);
+  tree field13_1_1 = build_decl (input_location, FIELD_DECL,
+get_identifier ("field1"), integer_type_node);
+  DECL_CONTEXT (field13_1_1) = derived13_1;
+  DECL_CHAIN (field13_1_1) = NULL_TREE;
+  TYPE_FIELDS (derived13_1) = field13_1_1;
+  layout_type (derived13_1);
+
+  tree derived13_2 = make_node (RECORD_TYPE);
+  tree field13_2_1 = build_decl (input_location, FIELD_DECL,
+get_identifier ("field1"), integer_type_node);
+  DECL_CONTEXT (field13_2_1) = derived13_1;
+  DECL_CHAIN (field13_2_1) = NULL_TREE;
+  TYPE_FIELDS (derived13_2) = field13_2_1;
+  layout_type (derived13_2);
+
+  tree d13 = create_var (derived13_1, "d13");
+
+  vec decls13 {};
+  decls13.safe_push (d13);
+
+  context_builder builder13;
+  builder13.add_decls (&decls13);
+  simul_scope ctx13 = builder13.build (mem, printer);
+
+  data_storage *strg_d13 = ctx13.find_reachable_var (d13);
+  gcc_assert (strg_d13 != nullptr);
+
+  data_value d13_before = strg_d13->get_value ();
+  ASSERT_EQ (d13_before.classify (), VAL_UNDEFINED);
+
+  tree val77 = build_int_cst (integer_type_node, 77);
+
+  tree cvt13 = build1 (VIEW_CONVERT_EXPR, derived13_2, d13);
+  tree comp13 = build3 (COMPONENT_REF, integer_type_node, cvt13,
+   field13_2_1, NULL_TREE);
+  gimple *g13 = gimple_build_assign (comp13, val77);
+  ctx13.simulate (g13);
+
+  data_value d13_after = strg_d13->get_value ();
+  ASSERT_EQ (d13_after.classify (), VAL_KNOWN);
+  wide_int wi13_after = d13_after.get_known ();
+  ASSERT_PRED1 (wi::fits_shwi_p, wi13_after);
+  ASSERT_EQ (wi13_after.to_shwi (), 77);
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Prise en charge affichage TARGET_MEM_REF

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:b3fdfa76d70b532970161b370b2e3ca3656126a8

commit b3fdfa76d70b532970161b370b2e3ca3656126a8
Author: Mikael Morin 
Date:   Mon Jul 7 08:52:38 2025 +0200

Prise en charge affichage TARGET_MEM_REF

Diff:
---
 gcc/gimple-simulate.cc| 87 ---
 gcc/selftest-run-tests.cc |  2 ++
 gcc/selftest.h|  1 +
 3 files changed, 86 insertions(+), 4 deletions(-)

diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc
index aa29b68b748c..a85e6f63cc92 100644
--- a/gcc/gimple-simulate.cc
+++ b/gcc/gimple-simulate.cc
@@ -903,6 +903,9 @@ static tree
 find_mem_ref_replacement (simul_scope & context, tree data_ref,
  unsigned offset, unsigned min_size)
 {
+  gcc_assert (TREE_CODE (data_ref) == MEM_REF
+ || TREE_CODE (data_ref) == TARGET_MEM_REF);
+
   tree ptr = TREE_OPERAND (data_ref, 0);
   data_value ptr_val = context.evaluate (ptr);
   if (ptr_val.classify () != VAL_ADDRESS)
@@ -923,12 +926,30 @@ find_mem_ref_replacement (simul_scope & context, tree 
data_ref,
 {
   tree access_offset = TREE_OPERAND (data_ref, 1);
   gcc_assert (TREE_CONSTANT (access_offset));
-  gcc_assert (tree_fits_shwi_p (access_offset));
-  HOST_WIDE_INT shwi_offset = tree_to_shwi (access_offset);
-  gcc_assert (offset < UINT_MAX - shwi_offset);
-  HOST_WIDE_INT remaining_offset = shwi_offset * CHAR_BIT
+  gcc_assert (tree_fits_uhwi_p (access_offset));
+  HOST_WIDE_INT uhwi_offset = tree_to_uhwi (access_offset);
+  gcc_assert (offset < UINT_MAX - uhwi_offset);
+  HOST_WIDE_INT remaining_offset = uhwi_offset * CHAR_BIT
   + offset + ptr_address->offset;
 
+  if (TREE_CODE (data_ref) == TARGET_MEM_REF)
+   {
+ tree idx = TREE_OPERAND (data_ref, 2);
+ data_value idx_val = context.evaluate (idx);
+ gcc_assert (idx_val.classify () == VAL_KNOWN);
+ wide_int wi_idx = idx_val.get_known ();
+
+ tree step = TREE_OPERAND (data_ref, 3);
+ data_value step_val = context.evaluate (step);
+ gcc_assert (step_val.classify () == VAL_KNOWN);
+ wide_int wi_step = step_val.get_known ();
+
+ wi_idx *= wi_step;
+ gcc_assert (wi::fits_uhwi_p (wi_idx));
+ HOST_WIDE_INT idx_offset = wi_idx.to_uhwi ();
+ remaining_offset += idx_offset * CHAR_BIT;
+   }
+
   return pick_subref_at (var_ref, remaining_offset, nullptr, min_size);
 }
 }
@@ -957,6 +978,7 @@ context_printer::print_first_data_ref_part (simul_scope & 
context,
   switch (TREE_CODE (data_ref))
 {
 case MEM_REF:
+case TARGET_MEM_REF:
   {
tree mem_replacement = find_mem_ref_replacement (context, data_ref,
 offset, min_size);
@@ -4432,6 +4454,63 @@ context_printer_print_value_update_tests ()
   printer9.print_value_update (ctx9, ref9, val9_addr_i);
   const char *str9 = pp_formatted_text (&pp9);
   ASSERT_STREQ (str9, "# v17c[8B:+8B] = &i\n");
+
+
+  heap_memory mem10;
+  context_printer printer10;
+  pretty_printer & pp10 = printer10.pp;
+  pp_buffer (&pp10)->m_flush_p = false;
+
+  tree a11c_10 = build_array_type_nelts (char_type_node, 11);
+  tree v11c_10 = create_var (a11c_10, "v11c");
+  tree p_10 = create_var (ptr_type_node, "p");
+  tree i_10 = create_var (size_type_node, "i");
+
+  vec decls10{};
+  decls10.safe_push (v11c_10);
+  decls10.safe_push (p_10);
+  decls10.safe_push (i_10);
+
+  context_builder builder10;
+  builder10.add_decls (&decls10);
+  simul_scope ctx10 = builder10.build (mem10, printer10);
+
+  data_storage *strg10_v11 = ctx10.find_reachable_var (v11c_10);
+  gcc_assert (strg10_v11 != nullptr);
+  storage_address addr10_v11 (strg10_v11->get_ref (), 0);
+
+  data_value val10_addr_v11 (ptr_type_node);
+  val10_addr_v11.set_address (addr10_v11);
+
+  data_storage *strg10_p = ctx10.find_reachable_var (p_10);
+  gcc_assert (strg10_p != nullptr);
+  strg10_p->set (val10_addr_v11);
+
+  data_value val10_cst_2 (size_type_node);
+  wide_int cst2_10 = wi::uhwi (2, TYPE_PRECISION (size_type_node));
+  val10_cst_2.set_known (cst2_10);
+
+  data_storage *strg10_i = ctx10.find_reachable_var (i_10);
+  gcc_assert (strg10_i != nullptr);
+  strg10_i->set (val10_cst_2);
+
+  tree int_ptr_10 = build_pointer_type (integer_type_node);
+
+  tree ref10 = build5 (TARGET_MEM_REF, integer_type_node, p_10,
+  build_int_cst (int_ptr_10, -4), i_10,
+  build_int_cst (size_type_node, 4), NULL_TREE);
+
+  data_value val10_cst_13 (integer_type_node);
+  wide_int wi10_13 = wi::shwi (13, TYPE_PRECISION (integer_type_node));
+  val10_cst_13.set_known (wi10_13);
+
+  printer10.print_value_update (ctx10, ref10, val10_cst_13);
+  const char *str10 = pp_formatted_text (&pp10);
+  ASSERT_STREQ (str10,
+   "# v11c[4] = 13\n"
+   "# v11c[5] = 0\n"
+   "# v11c[6] = 0\n"
+  

[gcc] Created branch 'mikael/heads/refactor_descriptor_v08' in namespace 'refs/users'

2025-09-08 Thread Mikael Morin via Gcc-cvs
The branch 'mikael/heads/refactor_descriptor_v08' was created in namespace 
'refs/users' pointing to:

 8c43c3cce2a5... Régénération fichiers générés


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: prise en charge BUILTIN_REALLOC

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:5032e81841e0aa1f5ae3baf5aaff9a71b4efeeac

commit 5032e81841e0aa1f5ae3baf5aaff9a71b4efeeac
Author: Mikael Morin 
Date:   Tue Jul 29 17:43:43 2025 +0200

gimple-simulate: prise en charge BUILTIN_REALLOC

Diff:
---
 gcc/gimple-simulate.cc | 181 +
 1 file changed, 181 insertions(+)

diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc
index 1836f5d4b539..7f8c9d31b3b3 100644
--- a/gcc/gimple-simulate.cc
+++ b/gcc/gimple-simulate.cc
@@ -2526,6 +2526,39 @@ simul_scope::simulate_call (gcall *g)
 
   storage0.set (dest_val);
 }
+  else if (gimple_call_builtin_p (g, BUILT_IN_REALLOC))
+{
+  gcc_assert (lhs != NULL_TREE);
+  result.emplace (data_value (TREE_TYPE (lhs)));
+
+  gcc_assert (gimple_call_num_args (g) == 2);
+  tree arg0 = gimple_call_arg (g, 0);
+  tree arg1 = gimple_call_arg (g, 1);
+  data_value ptr0 = evaluate (arg0);
+  data_value size1 = evaluate (arg1);
+  gcc_assert (ptr0.classify () == VAL_ADDRESS);
+  gcc_assert (size1.classify () == VAL_KNOWN);
+
+  wide_int wi_size1 = size1.get_known ();
+  gcc_assert (wi::fits_uhwi_p (wi_size1));
+  HOST_WIDE_INT alloc_amount = wi_size1.to_uhwi ();
+  data_storage &storage = allocate (alloc_amount);
+
+  storage_address addr0 = *ptr0.get_address ();
+  data_storage & storage0 = addr0.storage.get ();
+  data_value src = storage0.get_value ();
+
+  wide_int wi_bitwidth = wi_size1 * CHAR_BIT;
+  gcc_assert (wi::fits_uhwi_p (wi_bitwidth));
+  HOST_WIDE_INT bitwidth = wi_bitwidth.to_uhwi ();
+  data_value dest (bitwidth);
+  dest.set_at (0, std::min (src.get_bitwidth (), dest.get_bitwidth ()),
+  src, 0);
+  storage.set (dest);
+
+  storage_address address (storage.get_ref (), 0);
+  (*result).set_address (address);
+}
   else
 {
   tree fn = gimple_call_fn (g);
@@ -6979,6 +7012,154 @@ simul_scope_simulate_call_tests ()
   wide_int wi105_after2 = val105_after2.get_known ();
   ASSERT_PRED1 (wi::fits_shwi_p, wi105_after2);
   ASSERT_EQ (wi105_after2.to_shwi (), 17);
+
+
+  tree p1_11 = create_var (ptr_type_node, "p1");
+  tree p2_11 = create_var (ptr_type_node, "p2");
+  tree c29 = build_array_type_nelts (char_type_node, 29);
+  tree ac29_11 = create_var (c29, "ac29");
+
+  vec decls11{};
+  decls11.safe_push (p1_11);
+  decls11.safe_push (p2_11);
+  decls11.safe_push (ac29_11);
+
+  heap_memory mem11;
+  context_builder builder11 {};
+  builder11.add_decls (&decls11);
+  simul_scope ctx11 = builder11.build (mem11, printer);
+
+  data_storage * storage_ac29_11 = ctx11.find_reachable_var (ac29_11);
+  gcc_assert (storage_ac29_11 != nullptr);
+
+  storage_address addr29_11 (storage_ac29_11->get_ref (), CHAR_BIT);
+  data_value val_addr29_11 (ptr_type_node);
+  val_addr29_11.set_address (addr29_11);
+
+  data_storage * storage_p2_11 = ctx11.find_reachable_var (p2_11);
+  gcc_assert (storage_p2_11 != nullptr);
+  storage_p2_11->set (val_addr29_11);
+
+  storage_address addr_p2_11 (storage_p2_11->get_ref (), 0);
+  data_value val_c29 (c29);
+  val_c29.set_address_at (addr_p2_11, HOST_BITS_PER_PTR);
+  wide_int wi23_11 = wi::shwi (23, TYPE_PRECISION (integer_type_node));
+  val_c29.set_known_at (wi23_11, 20 * CHAR_BIT);
+  storage_ac29_11->set (val_c29);
+
+  tree realloc_fn = builtin_decl_explicit (BUILT_IN_REALLOC);
+  gcall *realloc_call11 = gimple_build_call (realloc_fn, 2, p2_11,
+build_int_cst (size_type_node, 
31));
+  gimple_call_set_lhs (realloc_call11, p1_11);
+
+  data_storage * storage_p1_11 = ctx11.find_reachable_var (p1_11);
+  gcc_assert (storage_p1_11 != nullptr);
+
+  data_value val_p1_11_before = storage_p1_11->get_value ();
+  ASSERT_EQ (val_p1_11_before.classify (), VAL_UNDEFINED);
+
+  ctx11.simulate (realloc_call11);
+
+  data_value val_p1_11_after = storage_p1_11->get_value ();
+  ASSERT_EQ (val_p1_11_after.classify (), VAL_ADDRESS);
+  storage_address * addr_p1_11 = val_p1_11_after.get_address ();
+  storage_ref storage_ref_addr_p1_11 = addr_p1_11->storage;
+  ASSERT_EQ (storage_ref_addr_p1_11.type, STRG_ALLOC);
+  data_storage & storage_addr_p1_11 = storage_ref_addr_p1_11.get ();
+  ASSERT_EQ (storage_addr_p1_11.get_type (), STRG_ALLOC);
+
+  data_value val_strg_p1_11 = storage_addr_p1_11.get_value ();
+  ASSERT_EQ (val_strg_p1_11.get_bitwidth (), 31 * CHAR_BIT);
+  ASSERT_EQ (val_strg_p1_11.classify (), VAL_MIXED);
+
+  ASSERT_EQ (val_strg_p1_11.classify (0, HOST_BITS_PER_PTR),
+VAL_UNDEFINED);
+  ASSERT_EQ (val_strg_p1_11.classify (HOST_BITS_PER_PTR, HOST_BITS_PER_PTR),
+VAL_ADDRESS);
+  ASSERT_EQ (val_strg_p1_11.classify (2 * HOST_BITS_PER_PTR, 
HOST_BITS_PER_INT),
+VAL_UNDEFINED);
+  ASSERT_EQ (val_strg_p1_11.classify (20 * CHAR_BIT, HOST_BITS_PER_INT),
+VAL_KNOWN);
+
+  data_value val_ptr_strg_p1_11 = val_strg_p1_11.get_at (HOST_BITS_PER_

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: prise en charge __builtin_alloca_with_align

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:f15f2b6559acafcf46b874d8884e01dcb17e516d

commit f15f2b6559acafcf46b874d8884e01dcb17e516d
Author: Mikael Morin 
Date:   Thu Aug 21 21:52:17 2025 +0200

gimple-simulate: prise en charge __builtin_alloca_with_align

Diff:
---
 gcc/gimple-simulate.cc | 59 --
 1 file changed, 57 insertions(+), 2 deletions(-)

diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc
index 7f8c9d31b3b3..4fc64d342089 100644
--- a/gcc/gimple-simulate.cc
+++ b/gcc/gimple-simulate.cc
@@ -2414,12 +2414,16 @@ simul_scope::simulate_call (gcall *g)
 
   tree lhs = gimple_call_lhs (g);
   optional  result;
-  if (gimple_call_builtin_p (g, BUILT_IN_MALLOC))
+  if (gimple_call_builtin_p (g, BUILT_IN_MALLOC)
+  || gimple_call_builtin_p (g, BUILT_IN_ALLOCA_WITH_ALIGN))
 {
   gcc_assert (lhs != NULL_TREE);
   result.emplace (data_value (TREE_TYPE (lhs)));
 
-  gcc_assert (gimple_call_num_args (g) == 1);
+  gcc_assert ((gimple_call_builtin_p (g, BUILT_IN_MALLOC)
+  && gimple_call_num_args (g) == 1)
+ || (gimple_call_builtin_p (g, BUILT_IN_ALLOCA_WITH_ALIGN)
+ && gimple_call_num_args (g) == 2));
   tree arg = gimple_call_arg (g, 0);
   data_value size = evaluate (arg);
   gcc_assert (size.classify () == VAL_KNOWN);
@@ -7160,6 +7164,57 @@ simul_scope_simulate_call_tests ()
   wide_int wi_known_strg_p2_12 = val_known_strg_p2_12.get_known ();
   ASSERT_PRED1 (wi::fits_shwi_p, wi_known_strg_p2_12);
   ASSERT_EQ (wi_known_strg_p2_12.to_shwi (), 18);
+
+
+  tree p13 = create_var (ptr_type_node, "p");
+
+  vec decls13{};
+  decls13.safe_push (p13);
+
+  heap_memory mem13;
+  context_builder builder13 {};
+  builder13.add_decls (&decls13);
+  simul_scope ctx13 = builder13.build (mem13, printer);
+
+  tree alloca_align_fn = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
+  tree cst12_13 = build_int_cst (size_type_node, 12);
+  tree cst32_13 = build_int_cst (size_type_node, 32);
+
+  gcall * alloca_align_call = gimple_build_call (alloca_align_fn, 2,
+cst12_13, cst32_13);
+  gimple_set_lhs (alloca_align_call, p13);
+
+  ASSERT_EQ (ctx13.find_alloc (0), nullptr);
+
+  ctx13.simulate (alloca_align_call);
+
+  data_storage *alloca_align_strg = ctx13.find_alloc (0);
+  ASSERT_NE (alloca_align_strg, nullptr);
+  data_value alloca_align_val = alloca_align_strg->get_value ();
+  ASSERT_EQ (alloca_align_val.classify (), VAL_UNDEFINED);
+  ASSERT_EQ (alloca_align_val.get_bitwidth (), 96);
+
+  data_storage *p13_strg = ctx13.find_var (p13);
+  ASSERT_NE (p13_strg, nullptr);
+  data_value p13_val = p13_strg->get_value ();
+  ASSERT_EQ (p13_val.classify (), VAL_ADDRESS);
+  ASSERT_EQ (&p13_val.get_address ()->storage.get (), alloca_align_strg);
+
+  tree cst10_13 = build_int_cst (size_type_node, 10);
+
+  gcall * alloca_align_call2 = gimple_build_call (alloca_align_fn, 2,
+ cst10_13, cst32_13);
+  gimple_set_lhs (alloca_align_call2, p13);
+
+  ASSERT_EQ (ctx13.find_alloc (1), nullptr);
+
+  ctx13.simulate (alloca_align_call2);
+
+  data_storage *alloca_align_strg2 = ctx13.find_alloc (1);
+  ASSERT_NE (alloca_align_strg2, nullptr);
+  data_value alloca_align_val2 = alloca_align_strg2->get_value ();
+  ASSERT_EQ (alloca_align_val2.classify (), VAL_UNDEFINED);
+  ASSERT_EQ (alloca_align_val2.get_bitwidth (), 80);
 }
 
 void


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: Affichage des arguments à l'appel de fonction

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:af133b12e3c2b1601890e9b7b627f50a63d745e0

commit af133b12e3c2b1601890e9b7b627f50a63d745e0
Author: Mikael Morin 
Date:   Tue Jul 29 11:45:38 2025 +0200

gimple-simulate: Affichage des arguments à l'appel de fonction

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

diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc
index 1f7492fae06a..1836f5d4b539 100644
--- a/gcc/gimple-simulate.cc
+++ b/gcc/gimple-simulate.cc
@@ -2838,6 +2838,7 @@ simulate (struct function * func, simul_scope & caller,
   data_storage *storage = ctx.find_reachable_var (arg);
   gcc_assert (storage != nullptr);
   storage->set (value);
+  printer.print_value_update (ctx, arg, value);
 
   arg = TREE_CHAIN (arg);
   i++;


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: Correction ICE évaluation adresse

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c84be8eeefb2881ebf1fa8c3ccd810c9e823fddf

commit c84be8eeefb2881ebf1fa8c3ccd810c9e823fddf
Author: Mikael Morin 
Date:   Fri Aug 29 17:10:53 2025 +0200

gimple-simulate: Correction ICE évaluation adresse

Diff:
---
 gcc/gimple-simulate.cc | 26 --
 gcc/tree-dfa.cc|  1 +
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc
index 247b3829c3c6..e0cf25eb97aa 100644
--- a/gcc/gimple-simulate.cc
+++ b/gcc/gimple-simulate.cc
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-pretty-print.h"
 #include "gimple-iterator.h"
 #include "gimple-ssa.h"
+#include "gimple-fold.h"
 #include "cgraph.h"
 #include "stringpool.h"
 #include "value-range.h"
@@ -1849,6 +1850,26 @@ simul_scope::get_storage (unsigned idx) const
 }
 
 
+tree
+simul_valueize (tree t)
+{
+  if (TREE_CODE (t) == SSA_NAME)
+{
+  gimple * def = SSA_NAME_DEF_STMT (t);
+
+  if (gimple_code (def) == GIMPLE_ASSIGN
+ && gimple_assign_rhs_code (def) == ADDR_EXPR)
+   return gimple_assign_rhs1 (def);
+
+  tree c = gimple_fold_stmt_to_constant (def, simul_valueize);
+  if (c != NULL_TREE)
+   return c;
+}
+
+  return t;
+}
+
+
 /* Evaluate the expression EXPR using the values currently stored in
accessible variables and allocated storages and return the resulting value.
*/
@@ -1916,8 +1937,9 @@ simul_scope::evaluate (tree expr) const
else
  {
poly_int64 offset;
-   tree var = get_addr_base_and_unit_offset (TREE_OPERAND (expr, 0),
- &offset);
+   tree var = get_addr_base_and_unit_offset_1 (TREE_OPERAND (expr, 0),
+   &offset,
+   simul_valueize);
 
HOST_WIDE_INT off;
bool is_constant = offset.is_constant (&off);
diff --git a/gcc/tree-dfa.cc b/gcc/tree-dfa.cc
index e25d5c05ca2f..a91f17ca6680 100644
--- a/gcc/tree-dfa.cc
+++ b/gcc/tree-dfa.cc
@@ -863,6 +863,7 @@ get_addr_base_and_unit_offset_1 (tree exp, poly_int64 
*poffset,
byte_offset += off.force_shwi ();
  }
exp = TREE_OPERAND (base, 0);
+   continue;
  }
goto done;
  }


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: Assouplissement type pointeur nul

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:90e802a9e89ecc694d23e5082e14305cd8233cd9

commit 90e802a9e89ecc694d23e5082e14305cd8233cd9
Author: Mikael Morin 
Date:   Fri Aug 29 15:14:32 2025 +0200

gimple-simulate: Assouplissement type pointeur nul

Diff:
---
 gcc/gimple-simulate.cc | 43 +++
 1 file changed, 43 insertions(+)

diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc
index a887bba872cf..247b3829c3c6 100644
--- a/gcc/gimple-simulate.cc
+++ b/gcc/gimple-simulate.cc
@@ -2115,6 +2115,9 @@ simul_scope::evaluate_binary (enum tree_code code, tree 
type, tree lhs,
 == TYPE_PRECISION (TREE_TYPE (rhs))
  && TYPE_UNSIGNED (TREE_TYPE (lhs))
 == TYPE_UNSIGNED (TREE_TYPE (rhs)))
+ || (TREE_CODE (TREE_TYPE (lhs)) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (rhs)) == POINTER_TYPE
+ && integer_zerop (rhs))
  || code == LSHIFT_EXPR
  || code == RSHIFT_EXPR);
   tree lval = val_lhs.to_tree (TREE_TYPE (lhs));
@@ -3688,6 +3691,17 @@ data_value_get_at_tests ()
   ASSERT_EQ (sub_val.classify (tree_to_shwi (bit_position (p2)),
   HOST_BITS_PER_PTR),
 VAL_ADDRESS);
+
+
+  heap_memory mem2;
+  simul_scope ctx2 = context_builder ().build (mem2, printer);
+
+  data_value val2 = ctx2.evaluate (boolean_true_node);
+
+  ASSERT_EQ (val2.classify (), VAL_KNOWN);
+  wide_int wi_val2 = val2.get_known ();
+  ASSERT_PRED1 (wi::fits_uhwi_p, wi_val2);
+  ASSERT_EQ (wi_val2.to_uhwi (), 1);
 }
 
 
@@ -5897,6 +5911,35 @@ simul_scope_evaluate_binary_tests ()
  i1_7, cst_i1);
 
   ASSERT_EQ (undef7_2.classify (), VAL_UNDEFINED);
+
+
+  tree pint_8 = build_pointer_type (integer_type_node);
+  tree p_8 = create_var (pint_8, "p");
+
+  vec decls8{};
+  decls8.safe_push (p_8);
+
+  context_builder builder8 {};
+  builder8.add_decls (&decls8);
+  simul_scope ctx8 = builder8.build (mem, printer);
+
+  wide_int wi_zero = wi::shwi (0, HOST_BITS_PER_PTR);
+  
+  data_value val_p8 (pint_8);
+  val_p8.set_known (wi_zero);
+
+  data_storage *strg_p8 = ctx8.find_reachable_var (p_8);
+  gcc_assert (strg_p8 != nullptr);
+  strg_p8->set (val_p8);
+
+  tree null = build_zero_cst (build_pointer_type (void_type_node));
+  data_value eq_8 = ctx8.evaluate_binary (EQ_EXPR, boolean_type_node,
+ p_8, null);
+
+  ASSERT_EQ (eq_8.classify (), VAL_KNOWN);
+  wide_int wi_eq8 = eq_8.get_known ();
+  ASSERT_PRED1 (wi::fits_uhwi_p, wi_eq8);
+  ASSERT_EQ (wi_eq8.to_uhwi (), 1);
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: sauvegarde

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:64eb5fd110ad4bff744af289763a34ef66274e59

commit 64eb5fd110ad4bff744af289763a34ef66274e59
Author: Mikael Morin 
Date:   Fri Aug 29 20:52:19 2025 +0200

gimple-simulate: sauvegarde

Diff:
---
 gcc/gimple-simulate.cc | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc
index 9333c64aa77d..3bdfd2bf6f7d 100644
--- a/gcc/gimple-simulate.cc
+++ b/gcc/gimple-simulate.cc
@@ -807,6 +807,8 @@ static tree
 pick_subref_at (tree var_ref, unsigned offset, int * ignored_bits,
unsigned min_size)
 {
+  if (ignored_bits != nullptr)
+*ignored_bits = 0;
   tree ref = var_ref;
   unsigned remaining_offset = offset;
   while (true)
@@ -953,8 +955,20 @@ find_mem_ref_replacement (tree * repl, unsigned * offset, 
simul_scope & context,
  remaining_offset += wi_idx * CHAR_BIT;
}
 
-  *repl = var_ref;
-  *offset = remaining_offset.to_shwi ();
+  int ignored_bits;
+  tree t = pick_subref_at (var_ref, remaining_offset.to_shwi (),
+  &ignored_bits,
+  get_constant_type_size (access_type));
+  if (t == NULL_TREE)
+   {
+ *repl = var_ref;
+ *offset = remaining_offset.to_shwi ();
+   }
+  else
+   {
+ *repl = t;
+ *offset = ignored_bits;
+   }
   return true;
 }
 }


[gcc] Deleted branch 'mikael/heads/refactor_descriptor_v08' in namespace 'refs/users'

2025-09-08 Thread Mikael Morin via Gcc-cvs
The branch 'mikael/heads/refactor_descriptor_v08' in namespace 'refs/users' was 
deleted.
It previously pointed to:

 91536f38b386... Régénération fichiers générés

Diff:

!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
---

  91536f3... Régénération fichiers générés
  9bd3219... Remplacement macro GFC_DIMENSION_SET -> GFC_DESCRIPTOR_DIME
  b9cb223... Introduction gfc_conv_descriptor_extent_get
  6b00d5f... Refactor set_dimension_fields set_empty_descriptor
  a54c389... Refactor set_dimension_fields descriptor_init_count
  60e0b09... Refactoring set_dimension_fields set_pdt_array_descriptor
  77ed1d8... Factorisation set_dimension_bounds/shift_dimension_bounds g
  67666ef... Factorisation shift_dimension_fields/set_dimension_fields g
  6ce6398... Factorisation set_dimension_fields gfc_set_descriptor_with_
  215eb06... Factorisation set_dimension_fields gfc_set_descriptor
  5f77e19... Renseignement dtype initialisation statique
  35ddc62... Refactoring descriptor_write
  c877f34... Refactoring nullifcations descripteur
  97d3534... Suppression déclarations inutiles
  7069cc7... Déplacement initialisation dernière borne sup assumed siz
  93dbd09... Suppression set_dtype_if_unallocated
  6a96de7... Suppression déclarations inutiles
  35967a1... Extraction gfc_set_empty_descriptor_bounds
  6d9ca30... Déplacement gfc_array_init_count -> gfc_descriptor_init_co
  66251d0... Déplacement gfc_grow_array
  b47af53... Déplacemement plus de code gfc_set_pdt_array_descriptor
  680ce9d... Extraction gfc_set_pdt_array_descriptor
  f5c0fa1... Extraction gfc_set_descriptor_for_assign_realloc
  325ea51... Suppression mise à jour offset forall
  d594ecb... Extraction get_array_memory_size
  9738042... Mise à jour offset & span dans gfc_array_init_size
  b552327... Factorisation descriptor_element_size
  6dd4da9... Extraction gfc_set_temporary_descriptor
  5243a81... Refactoring set_dimension_fields
  0e943e2... Refactor set_dimension_bounds
  a15a4f5... Déroulement boucle set_gfc_from_cfi
  ef2b995... Refactor set_gfc_from_cfi
  ea74ff4... Extraction set_gfc_from_cfi
  be565a7... Extraction gfc_set_gfc_from_cfi
  5cf798d... Refactoring gfc_conv_descriptor_sm_get
  fbe9040... Factorisation utilisation shapeval
  baad800... Reindentation retour à la ligne set_descriptor_with_shape
  616fc48... Extraction set_descriptor_with_shape
  973ef63... Factorisation gfc_set_contiguous_descriptor
  f1bc70e... Extraction gfc_set_descriptor
  eca4e72... Calcul offset sans passer par le descripteur
  c4de21a... Modification initialisation stride
  238146e... Simplification initialisation offset remap descriptor
  e1f024a... Extraction gfc_conv_remap_descriptor
  2888c8a... Déplacement copy_descriptor
  a79b1e7... Extraction gfc_copy_descriptor
  cb75a4a... Extraction gfc_copy_descriptor
  f20d1d5... Extraction gfc_copy_descriptor
  a108733... Extraction gfc_copy_sequence_descriptor
  6441e6b... Refactoring shift descriptor
  57d5e98... Initialisation shifted offset en partant de zero
  07506fe... Extraction gfc_shift_descriptor
  e2e353d... Extraction gfc_conv_shift_subarray_descriptor
  13b2631... Factorisation gfc_conv_shift_descriptor
  671cb2b... Extraction gfc_conv_shift_descriptor
  a312a4a... Appel méthode shift descriptor dans gfc_trans_pointer_assi
  877f897... Déplacement shift descriptor vers gfc_conv_array_parameter
  bce0873... Refactoring gfc_set_descriptor_from_scalar
  ff179b8... Renseignement token dans gcf_set_descriptor_from_scalar
  a3c24bc... Extraction gfc_set_descriptor_from_scalar
  9c131b3... Extraction gfc_set_descriptor_from_scalar
  53b1048... Extraction gfc_set_descriptor_from_scalar
  94d5fa0... Refactoring gfc_get_scalar_to_descriptor_type
  c61566f... Refactoring gfc_get_scalar_to_descriptor_type
  0583678... Introduction gfc_create_null_actual_descriptor
  4a85dd0... Refactoring gfc_nullify_descriptor/gfc_init_descriptor_vari
  591c369... Refactor gfc_init_descriptor_variable
  a1964fd... Modif gfc_init_descriptor_variable
  5009dd1... Introduction gfc_symbol_attr
  f0297fd... Renseignement dtype par défaut
  df4f4e5... Extraction gfc_init_descriptor_variable
  40d3e3e... Introduction enums pour les champs des structures
  7c8e4a0... Extraction gfc_init_static_descriptor
  dbebe06... Extraction gfc_init_absent_descriptor
  597fdba... Introduction gfc_init_descriptor_result
  9adca06... Extraction fonction gfc_nullify_descriptor
  0c0c143... Déplacement gfc_descriptor_size
  da541ea... Refactor set_value
  6dc370a... Ajout locations setters
  d56ee42... Refactoring getters & setters
  8fda392... Refactor get_descr_dim_comp
  14b9752... Refactoring get_dtype_comp
  81e356e... Refactoring get_type_field
  eedee58... Refactoring get_ref_comp
  4e739e5... Interdiction non-lvalue as lhs
  a30d5a7... Ajout non_lvalue getters.
  812ddeb... Utilisation gfc_conv_descriptor_token_set
  d49656e... Suppression gfc_conv_descriptor_dimension

[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Suppression gfc_conv_descriptor_elem_len compil' OK

2025-09-08 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:79eb5d69656b3615e9eae1fd21e6f14afa048e1b

commit 79eb5d69656b3615e9eae1fd21e6f14afa048e1b
Author: Mikael Morin 
Date:   Sun Jun 29 12:40:53 2025 +0200

Suppression gfc_conv_descriptor_elem_len compil' OK

Correction ICE class_allocate_21

Suppression non_lvalue elem_len_get

Ajout location elem_len_set

Suppression retour à la ligne inutile elem_len_set

Diff:
---
 gcc/fortran/trans-array.cc  |  8 ++--
 gcc/fortran/trans-decl.cc   | 10 +-
 gcc/fortran/trans-descriptor.cc | 18 --
 gcc/fortran/trans-descriptor.h  |  3 ++-
 gcc/fortran/trans-expr.cc   |  6 +++---
 gcc/fortran/trans-intrinsic.cc  |  2 +-
 gcc/fortran/trans-openmp.cc |  6 +++---
 7 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 0ffe4fda6c81..ea9bc1da516c 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -5927,11 +5927,7 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
   else if (expr->ts.type == BT_CLASS && !explicit_ts
   && expr3 && expr3->ts.type != BT_CLASS
   && expr3_elem_size != NULL_TREE && expr3_desc == NULL_TREE)
-{
-  tmp = gfc_conv_descriptor_elem_len (descriptor);
-  gfc_add_modify (pblock, tmp,
- fold_convert (TREE_TYPE (tmp), expr3_elem_size));
-}
+gfc_conv_descriptor_elem_len_set (pblock, descriptor, expr3_elem_size);
   else
 gfc_conv_descriptor_dtype_set (pblock, descriptor, gfc_get_dtype (type));
 
@@ -11301,7 +11297,7 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo 
*loop,
 {
   /* Unfortunately, the lhs vptr is set too early in many cases.
 Play it safe by using the descriptor element length.  */
-  tmp = gfc_conv_descriptor_elem_len (desc);
+  tmp = gfc_conv_descriptor_elem_len_get (desc);
   elemsize1 = fold_convert (gfc_array_index_type, tmp);
 }
   else
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 556e52502b88..5ed83d6aa0c6 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -7277,8 +7277,8 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
   if (sym->ts.type == BT_ASSUMED)
 {
   /* For type(*), take elem_len + dtype.type from the actual argument.  */
-  gfc_add_modify (&block, gfc_conv_descriptor_elem_len (gfc_desc),
- gfc_get_cfi_desc_elem_len (cfi));
+  gfc_conv_descriptor_elem_len_set (&block, gfc_desc,
+   gfc_get_cfi_desc_elem_len (cfi));
   tree cond;
   tree ctype = gfc_get_cfi_desc_type (cfi);
   ctype = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (ctype),
@@ -7508,7 +7508,7 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
   /* memcpy (lhs + idx*elem_len, rhs + shift, elem_len)  */
   tree elem_len;
   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
-   elem_len = gfc_conv_descriptor_elem_len (gfc_desc);
+   elem_len = gfc_conv_descriptor_elem_len_get (gfc_desc);
   else
elem_len = gfc_get_cfi_desc_elem_len (cfi);
   lhs = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
@@ -7546,7 +7546,7 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
   /* if do_copy_inout:  gfc->dspan = gfc->dtype.elem_len
  We use gfc instead of cfi on the RHS as this might be a constant.  */
   tmp = fold_convert (gfc_array_index_type,
- gfc_conv_descriptor_elem_len (gfc_desc));
+ gfc_conv_descriptor_elem_len_get (gfc_desc));
   if (!do_copy_inout)
 {
   /* gfc->dspan = ((cfi->dim[0].sm % gfc->elem_len)
@@ -7750,7 +7750,7 @@ done:
  /* memcpy (lhs + shift, rhs + idx*elem_len, elem_len) */
  tree elem_len;
  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
-   elem_len = gfc_conv_descriptor_elem_len (gfc_desc);
+   elem_len = gfc_conv_descriptor_elem_len_get (gfc_desc);
  else
elem_len = gfc_get_cfi_desc_elem_len (cfi);
  rhs = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 255b243d9360..8fe0e3bfaa9d 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -315,8 +315,8 @@ gfc_conv_descriptor_version (tree desc)
 
 /* Return the element length from the descriptor dtype field.  */
 
-tree
-gfc_conv_descriptor_elem_len (tree desc)
+static tree
+get_descriptor_elem_len (tree desc)
 {
   tree tmp;
   tree dtype;
@@ -330,6 +330,20 @@ gfc_conv_descriptor_elem_len (tree desc)
  dtype, tmp, NULL_TREE);
 }
 
+tree
+gfc_conv_descriptor_elem_len_get (tree desc)
+{
+  return get_descriptor_elem_len (desc);
+}
+
+void
+gfc_conv_descriptor_elem_len_set (stmtblock_t *block, tree desc, tree value)
+{
+  location_t l

  1   2   >