[gcc r16-3658] RISC-V: Add pattern for vector-scalar single-width floating-point sub
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
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
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.
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'
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.
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'
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'
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'
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'
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.
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
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.*
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.
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.
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.*
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.
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
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
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
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
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
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
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.
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.*
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
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.
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.
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.
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'
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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]
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]
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]
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
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
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
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]
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.
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.
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
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
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
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
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
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.
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
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
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
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].
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]
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
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
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
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.*
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
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
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
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
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'
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
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
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
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
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
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
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'
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
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