[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-3868] ada: Implement Super aspect and improve implementation of related features.
https://gcc.gnu.org/g:8a787f3e441c2205a651e084c905656e9d800245 commit r16-3868-g8a787f3e441c2205a651e084c905656e9d800245 Author: Steve Baird Date: Mon Aug 18 14:39:48 2025 -0700 ada: Implement Super aspect and improve implementation of related features. Implement the GNAT-defined Super aspect (which should not be confused with with the Super attribute). For a two-part constructor procedure declaration, an Initialize aspect specification is permitted on the subprogram body, and not on the subprogram specification (this reverses was what was previously implemented). Improve the implementation of the Make attribute. gcc/ada/ChangeLog: * aspects.ads: Define Super aspect; allow Initialize aspect specification on a subprogram body. * exp_attr.adb (Expand_N_Attribute_Reference): Rewrite Make attribute implementation. * exp_ch3.adb (Initialization_Control): Delete Initialization_Mode and Make_Mode_Literal (those declarations were moved to the spec). (Build_Record_Init_Proc): For a constructor type, component initialization (other than for the tag component, if any) must be performed by calling the single-argument constructor procedure. (Requires_Init_Proc): Return True for a constructor type. * exp_ch3.ads (Make_Mode_Literal, Initialization_Mode): New, moved from the body of this package. * exp_ch6.adb (Expand_N_Subprogram_Body): Declare, implement, and call a new local procedure, Prepend_Constructor_Procedure_Prologue in order to generate component initialization for a constructor procedure. * sem_attr.adb (Analyze_Attribute): Improve the error message generated for a 'Make attribute reference if GNAT extensions are not all allowed. * sem_ch13.adb (Analyze_One_Aspect): Improved implementation of aspect specifications for Initialize, Constructor, and Super aspects. For Super, there was no previous implementation. Diff: --- gcc/ada/aspects.ads | 9 +- gcc/ada/exp_attr.adb | 324 ++- gcc/ada/exp_ch3.adb | 79 +++-- gcc/ada/exp_ch3.ads | 27 + gcc/ada/exp_ch6.adb | 309 gcc/ada/sem_attr.adb | 4 +- gcc/ada/sem_ch13.adb | 109 ++--- 7 files changed, 517 insertions(+), 344 deletions(-) diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads index 88fea2e818ce..2871f318b3e5 100644 --- a/gcc/ada/aspects.ads +++ b/gcc/ada/aspects.ads @@ -158,6 +158,7 @@ package Aspects is Aspect_Stream_Size, Aspect_String_Literal, Aspect_Subprogram_Variant,-- GNAT + Aspect_Super, -- GNAT Aspect_Suppress, Aspect_Synchronization, Aspect_Test_Case, -- GNAT @@ -518,6 +519,7 @@ package Aspects is Aspect_Stream_Size=> Expression, Aspect_String_Literal => Name, Aspect_Subprogram_Variant => Expression, + Aspect_Super => Expression, Aspect_Suppress => Name, Aspect_Synchronization=> Name, Aspect_Test_Case => Expression, @@ -626,6 +628,7 @@ package Aspects is Aspect_Stream_Size => True, Aspect_String_Literal => False, Aspect_Subprogram_Variant => False, + Aspect_Super=> False, Aspect_Suppress => False, Aspect_Synchronization => False, Aspect_Test_Case=> False, @@ -842,6 +845,7 @@ package Aspects is Aspect_Stream_Size => Name_Stream_Size, Aspect_String_Literal => Name_String_Literal, Aspect_Subprogram_Variant => Name_Subprogram_Variant, + Aspect_Super=> Name_Super, Aspect_Suppress => Name_Suppress, Aspect_Suppress_Debug_Info => Name_Suppress_Debug_Info, Aspect_Suppress_Initialization => Name_Suppress_Initialization, @@ -1124,6 +1128,7 @@ package Aspects is Aspect_SPARK_Mode => Never_Delay, Aspect_Static => Never_Delay, Aspect_Subprogram_Variant => Never_Delay, + Aspect_Super=> Never_Delay, Aspect_Synchronization => Never_Delay, Aspect_Test_Case=> Never_Delay, Aspect_Unimplemented=> Never_Delay, @@ -1193,10 +1198,12 @@ package Aspects is -- Sem_Prag. Aspect_On_Body_Or_Stub_OK : constant array (Aspect_Id) of Boolean := - (Aspect_Refined_Depends => True, + (Aspect
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Réduction utilisations macro GFC_DESCRIPTOR_STRIDE
https://gcc.gnu.org/g:3191711469b60094509ae38fe068b4e88c0957df commit 3191711469b60094509ae38fe068b4e88c0957df Author: Mikael Morin Date: Sat Sep 13 16:36:23 2025 +0200 Réduction utilisations macro GFC_DESCRIPTOR_STRIDE Retour en arrière list_read.c Correction eoshift0 Correction cshift0.m4 Retour en arrière cshift0 Remodif cshift0.m4 Réapplication modifs cshift0 Correction cshift0.m4 Correction cshift0.m4 Correction cshift0.m4 Retour en arrière partiel eoshift0.c Correction matmull.m4 Retour en arrière code allocation Retour en arrière partiel random.c et reshape.m4 Retour en arrière partiel matmull.m4 Diff: --- libgfortran/intrinsics/associated.c | 4 +++- libgfortran/intrinsics/eoshift0.c | 6 +++--- libgfortran/intrinsics/is_contiguous.c| 10 +- libgfortran/intrinsics/random.c | 2 +- libgfortran/intrinsics/spread_generic.c | 3 +-- libgfortran/m4/cshift0.m4 | 14 ++--- libgfortran/m4/matmul_internal.m4 | 33 +++ libgfortran/m4/spread.m4 | 3 +-- libgfortran/runtime/ISO_Fortran_binding.c | 2 +- libgfortran/runtime/in_pack_class.c | 16 +++ libgfortran/runtime/in_pack_generic.c | 12 +-- libgfortran/runtime/in_unpack_class.c | 10 +- libgfortran/runtime/in_unpack_generic.c | 12 +-- 13 files changed, 66 insertions(+), 61 deletions(-) diff --git a/libgfortran/intrinsics/associated.c b/libgfortran/intrinsics/associated.c index 592c84c097af..182364543a0b 100644 --- a/libgfortran/intrinsics/associated.c +++ b/libgfortran/intrinsics/associated.c @@ -51,7 +51,9 @@ associated (const gfc_array_void *pointer, const gfc_array_void *target) if (extent != GFC_DESCRIPTOR_EXTENT(target,n)) return 0; - if (GFC_DESCRIPTOR_STRIDE(pointer,n) != GFC_DESCRIPTOR_STRIDE(target,n) && extent != 1) + if ((GFC_DESCRIPTOR_STRIDE_BYTES(pointer,n) + != GFC_DESCRIPTOR_STRIDE_BYTES(target,n)) + && extent != 1) return 0; if (extent <= 0) return 0; diff --git a/libgfortran/intrinsics/eoshift0.c b/libgfortran/intrinsics/eoshift0.c index 251971ecfb59..3baa966398cb 100644 --- a/libgfortran/intrinsics/eoshift0.c +++ b/libgfortran/intrinsics/eoshift0.c @@ -147,9 +147,9 @@ eoshift0 (gfc_array_char * ret, const gfc_array_char * array, bn = eoshift(a,sh*n1*n2,1) so a block move can be used for dim>1. */ - len = GFC_DESCRIPTOR_STRIDE(array, which) - * GFC_DESCRIPTOR_EXTENT(array, which); - shift *= GFC_DESCRIPTOR_STRIDE(array, which); + index_type count_low = GFC_DESCRIPTOR_STRIDE(array, which); + len = count_low * GFC_DESCRIPTOR_EXTENT(array, which); + shift *= count_low; roffset = size; soffset = size; for (dim = which + 1; dim < GFC_DESCRIPTOR_RANK (array); dim++) diff --git a/libgfortran/intrinsics/is_contiguous.c b/libgfortran/intrinsics/is_contiguous.c index 965911ac8f7f..b2c960722e00 100644 --- a/libgfortran/intrinsics/is_contiguous.c +++ b/libgfortran/intrinsics/is_contiguous.c @@ -30,18 +30,18 @@ is_contiguous0 (const array_t * const restrict array) { index_type dim; index_type n; - index_type extent, stride; + index_type size, stride; dim = GFC_DESCRIPTOR_RANK (array); - extent = 1; + size = GFC_DESCRIPTOR_SIZE (array); for (n = 0; n < dim; n++) { - stride = GFC_DESCRIPTOR_STRIDE (array, n); - if (stride != extent) + stride = GFC_DESCRIPTOR_STRIDE_BYTES (array, n); + if (stride != size) return 0; - extent *= GFC_DESCRIPTOR_EXTENT (array, n); + size *= GFC_DESCRIPTOR_EXTENT (array, n); } return 1; diff --git a/libgfortran/intrinsics/random.c b/libgfortran/intrinsics/random.c index c5e86dc45051..f102651fa441 100644 --- a/libgfortran/intrinsics/random.c +++ b/libgfortran/intrinsics/random.c @@ -975,7 +975,7 @@ arandom_m1 (gfc_array_m1 *x) for (index_type n = 0; n < dim; n++) { count[n] = 0; - stride[n] = GFC_DESCRIPTOR_STRIDE(x,n); + stride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(x,n); extent[n] = GFC_DESCRIPTOR_EXTENT(x,n); if (extent[n] <= 0) return; diff --git a/libgfortran/intrinsics/spread_generic.c b/libgfortran/intrinsics/spread_generic.c index d59533e97757..7fe818faedea 100644 --- a/libgfortran/intrinsics/spread_generic.c +++ b/libgfortran/intrinsics/spread_generic.c @@ -252,8 +252,7 @@ spread_internal_scalar (gfc_array_char *ret, const char *source, } else { - if (ncopies - 1 > (GFC_DESCRIPTOR_EXTENT(ret,0) - 1) - / GFC_DESCRIPTOR_STRIDE(ret,0)) + if (ncopies > GFC_DESCRIPTOR_EXTENT(ret,0)) runtime_error ("dim too large in spread()"); } diff --git a/libgfortran/m4/cshift0.m4 b/libgfortran/m4/cshift0
[gcc r16-3895] [analyzer] another function name that returns a pointer to errno
https://gcc.gnu.org/g:770cbd759d2dda74231349502d7283b04c0fd0df commit r16-3895-g770cbd759d2dda74231349502d7283b04c0fd0df Author: Alexandre Oliva Date: Mon Sep 15 20:14:45 2025 -0300 [analyzer] another function name that returns a pointer to errno Add __get_errno_ptr() as yet another synonym for __errno_location. for gcc/analyzer/ChangeLog * kf.cc (register_known_functions): Add __get_errno_ptr. Diff: --- gcc/analyzer/kf.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc index 2a7c35703153..5c54b5564486 100644 --- a/gcc/analyzer/kf.cc +++ b/gcc/analyzer/kf.cc @@ -2373,6 +2373,7 @@ register_known_functions (known_function_manager &kfm, kfm.add ("___errno", std::make_unique ()); kfm.add ("__error", std::make_unique ()); kfm.add ("__errno", std::make_unique ()); +kfm.add ("__get_errno_ptr", std::make_unique ()); } /* Language-specific support functions. */
[gcc r16-3893] [ppc] [vxworks] allow code model selection
https://gcc.gnu.org/g:ba7bfdf60c33f66e4b9d7c64ae470e0337bcc01d commit r16-3893-gba7bfdf60c33f66e4b9d7c64ae470e0337bcc01d Author: Alexandre Oliva Date: Mon Sep 15 20:14:35 2025 -0300 [ppc] [vxworks] allow code model selection Bring code model selection logic to vxworks.h as well. for gcc/ChangeLog * config/rs6000/vxworks.h (TARGET_CMODEL, SET_CMODEL): Define. Diff: --- gcc/config/rs6000/vxworks.h | 5 + 1 file changed, 5 insertions(+) diff --git a/gcc/config/rs6000/vxworks.h b/gcc/config/rs6000/vxworks.h index e77247b726ea..9eb074be31a8 100644 --- a/gcc/config/rs6000/vxworks.h +++ b/gcc/config/rs6000/vxworks.h @@ -267,6 +267,11 @@ along with GCC; see the file COPYING3. If not see #undef DOT_SYMBOLS #define DOT_SYMBOLS 0 +/* Allow code model to be selected. */ +#undef TARGET_CMODEL +#define TARGET_CMODEL rs6000_current_cmodel +#define SET_CMODEL(opt) rs6000_current_cmodel = opt + /* For link specs, we leverage the linux configuration bits through LINK_OS_EXTRA_SPEC32/64 and need to cancel the default %(link_os) expansion in VXWORKS_LINK_SPEC. */
[gcc r16-3894] aarch64: move pr113356.C under g++.target
https://gcc.gnu.org/g:2725514bfd1babe470cf3722043c271407f5 commit r16-3894-g2725514bfd1babe470cf3722043c271407f5 Author: Clément Chigot Date: Mon Sep 15 20:14:40 2025 -0300 aarch64: move pr113356.C under g++.target This test requires a C++ compiler. for gcc/testsuite/ChangeLog * gcc.target/aarch64/pr113356.C: Move to ... * g++.target/aarch64/pr113356.C: ... here. Diff: --- gcc/testsuite/{gcc.target => g++.target}/aarch64/pr113356.C | 0 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/gcc/testsuite/gcc.target/aarch64/pr113356.C b/gcc/testsuite/g++.target/aarch64/pr113356.C similarity index 100% rename from gcc/testsuite/gcc.target/aarch64/pr113356.C rename to gcc/testsuite/g++.target/aarch64/pr113356.C
[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)] Extraction fonction gfc_nullify_descriptor
https://gcc.gnu.org/g:9adca0663067add718969f5a440afabb1d593255 commit 9adca0663067add718969f5a440afabb1d593255 Author: Mikael Morin Date: Wed Jul 16 16:49:28 2025 +0200 Extraction fonction gfc_nullify_descriptor Diff: --- gcc/fortran/trans-descriptor.cc | 8 gcc/fortran/trans-descriptor.h | 3 +++ gcc/fortran/trans-expr.cc | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 76997a28f0bb..434091d399e9 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "trans.h" #include "trans-const.h" #include "trans-types.h" +#include "trans-array.h" /**/ @@ -685,3 +686,10 @@ gfc_conv_descriptor_cosize (tree desc, int rank, int corank) { return gfc_conv_descriptor_size_1 (desc, rank, rank + corank - 1); } + + +void +gfc_nullify_descriptor (stmtblock_t *block, tree descr) +{ + gfc_conv_descriptor_data_set (block, descr, null_pointer_node); +} diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index c035ec638edd..2328d0dad6f6 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -96,4 +96,7 @@ gfc_get_descriptor_offsets_for_info (const_tree desc_type, tree *data_off, tree *stride_suboff, tree *lower_suboff, tree *upper_suboff); +/* Build a null array descriptor constructor. */ +void gfc_nullify_descriptor (stmtblock_t *block, tree); + #endif /* GFC_TRANS_DESCRIPTOR_H */ diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 251a9b430cfa..f129b9e4d0c5 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -11101,7 +11101,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) if (expr2->expr_type == EXPR_NULL) { /* Just set the data pointer to null. */ - gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node); + gfc_nullify_descriptor (&lse.pre, lse.expr); } else if (rank_remap) {
[gcc r16-3889] ctf: Fix struct size truncation in 32-bit hosts [PR121903, PR121411]
https://gcc.gnu.org/g:bace01eeab69cabd0a326174909ced554af85c79 commit r16-3889-gbace01eeab69cabd0a326174909ced554af85c79 Author: David Faust Date: Mon Sep 15 15:03:31 2025 -0700 ctf: Fix struct size truncation in 32-bit hosts [PR121903,PR121411] The 'size' argument of ctf_add_sou was size_t. After the prior fixes for PR121411, this could cause the struct size to be truncated when encoding extremely large structs on a host where size_t is smaller than unsigned HOST_WIDE_INT, manifesting for example as the test failure reported in PR121903. Change the argument to uHWI to resolve the issue. PR debug/121411 PR debug/121903 gcc/ * ctfc.h (ctf_add_sou): Change size arg from size_t to uHWI. * ctfc.cc (ctf_add_sou): Likewise. Diff: --- gcc/ctfc.cc | 2 +- gcc/ctfc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/ctfc.cc b/gcc/ctfc.cc index 51511d69baa0..221e62e8f45d 100644 --- a/gcc/ctfc.cc +++ b/gcc/ctfc.cc @@ -798,7 +798,7 @@ ctf_add_function (ctf_container_ref ctfc, uint32_t flag, const char * name, ctf_dtdef_ref ctf_add_sou (ctf_container_ref ctfc, uint32_t flag, const char * name, -uint32_t kind, size_t size, dw_die_ref die) +uint32_t kind, unsigned HOST_WIDE_INT size, dw_die_ref die) { ctf_dtdef_ref dtd; diff --git a/gcc/ctfc.h b/gcc/ctfc.h index 32c73be6a412..26f35f0ac6f9 100644 --- a/gcc/ctfc.h +++ b/gcc/ctfc.h @@ -439,7 +439,7 @@ extern ctf_dtdef_ref ctf_add_function (ctf_container_ref, uint32_t, const char *, const ctf_funcinfo_t *, dw_die_ref, bool, int); extern ctf_dtdef_ref ctf_add_sou (ctf_container_ref, uint32_t, const char *, - uint32_t, size_t, dw_die_ref); + uint32_t, unsigned HOST_WIDE_INT, dw_die_ref); extern int ctf_add_enumerator (ctf_container_ref, ctf_dtdef_ref, const char *, HOST_WIDE_INT, dw_die_ref);
[gcc r16-3890] Widening-Mul: Refine build_and_insert_cast when rhs is cast
https://gcc.gnu.org/g:d0526e8ef0d92e93b956acb731e212a39106ef0a commit r16-3890-gd0526e8ef0d92e93b956acb731e212a39106ef0a Author: Pan Li Date: Mon Sep 8 22:25:03 2025 +0800 Widening-Mul: Refine build_and_insert_cast when rhs is cast The widening-mul will insert a cast for the widen-mul, the function build_and_insert_cast is design to take care of it. In some case the optimized gimple has some unnecessary cast, for example as below code. #define SAT_U_MUL_FMT_5(NT, WT) \ NT __attribute__((noinline))\ sat_u_mul_##NT##_from_##WT##_fmt_5 (NT a, NT b) \ { \ WT x = (WT)a * (WT)b; \ NT hi = x >> (sizeof(NT) * 8);\ NT lo = (NT)x;\ return lo | -!!hi;\ } SAT_U_MUL_FMT_5(uint64_t, uint128_t) There will be a additional cast to uint128_t after optimized, this patch would like to refine this by checking the def of the rhs cast, if it comes from a cast with less or equal precision, the rhs of the def will be leveraged. Before this patch: 29 │ _1 = (__int128 unsigned) a_8(D); 30 │ _2 = (__int128 unsigned) b_9(D); 31 │ _35 = (unsigned long) _1; 32 │ _34 = (unsigned long) _2; 33 │ x_10 = _35 w* _34; After this patch: 27 │ _35 = (unsigned long) a_8(D); 28 │ _34 = (unsigned long) b_9(D); 29 │ x_10 = _35 w* _34; gcc/ChangeLog: * tree-ssa-math-opts.cc (build_and_insert_cast): Refine the cast insert by check the rhs of val. gcc/testsuite/ChangeLog: * gcc.target/riscv/sat/widen-mul-0.c: New test. * gcc.target/riscv/sat/widen-mul-1.c: New test. * gcc.target/riscv/sat/widen-mul-2.c: New test. * gcc.target/riscv/sat/widen-mul-3.c: New test. * gcc.target/riscv/sat/widen-mul.h: New test. Signed-off-by: Pan Li Diff: --- gcc/testsuite/gcc.target/riscv/sat/widen-mul-0.c | 8 gcc/testsuite/gcc.target/riscv/sat/widen-mul-1.c | 8 gcc/testsuite/gcc.target/riscv/sat/widen-mul-2.c | 8 gcc/testsuite/gcc.target/riscv/sat/widen-mul-3.c | 8 gcc/testsuite/gcc.target/riscv/sat/widen-mul.h | 15 +++ gcc/tree-ssa-math-opts.cc| 22 +- 6 files changed, 68 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.target/riscv/sat/widen-mul-0.c b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-0.c new file mode 100644 index ..1074fa9d5f41 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-0.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "widen-mul.h" + +SAT_U_MUL_FMT_5(uint8_t, uint128_t) + +/* { dg-final { scan-tree-dump-not " = (__int128 unsigned) " "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/widen-mul-1.c b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-1.c new file mode 100644 index ..5f8f0dd733ce --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-1.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "widen-mul.h" + +SAT_U_MUL_FMT_5(uint16_t, uint128_t) + +/* { dg-final { scan-tree-dump-not " = (__int128 unsigned) " "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/widen-mul-2.c b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-2.c new file mode 100644 index ..4c54cc07b535 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-2.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "widen-mul.h" + +SAT_U_MUL_FMT_5(uint32_t, uint128_t) + +/* { dg-final { scan-tree-dump-not " = (__int128 unsigned) " "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/widen-mul-3.c b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-3.c new file mode 100644 index ..d3dd97104b70 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/widen-mul-3.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "widen-mul.h" + +SAT_U_MUL_FMT_5(uint64_t, uint128_t) + +/* { dg-final { scan-tree-dump-not " = (__int128 unsigned) " "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/widen-mul.h b/gcc/testsuite/gcc.target/riscv/sat/widen-mul.h new file mode 100644 index ..a0a44084e58a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/widen-mul.h @@ -0,0 +1,15 @@ +#include + +#if __riscv_xlen == 64 +typedef unsigned __int128 uint128_t; +#endif + +#define SAT_U_MUL_FMT_5(NT, WT) \ +NT __attr
[gcc r16-3892] [ppc] adjust configure test for large TOC support
https://gcc.gnu.org/g:fbbf5f0a3f62d9ce45507885f95924d7f973c1e1 commit r16-3892-gfbbf5f0a3f62d9ce45507885f95924d7f973c1e1 Author: Alexandre Oliva Date: Mon Sep 15 20:14:32 2025 -0300 [ppc] adjust configure test for large TOC support The use of the TLS register in a TOC/GOT address computation was probably a cut&pasto or a thinko. It causes a linker warning and, because the TLS access in the test is incomplete, may cause significant confusion. Adjust to use the TOC/GOT register as base. for gcc/ChangeLog * configure.ac: Adjust base register in linker test for large TOC support. * configure: Rebuild. Diff: --- gcc/configure| 2 +- gcc/configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/configure b/gcc/configure index 5a779db0a29f..d6cc7fc17ca0 100755 --- a/gcc/configure +++ b/gcc/configure @@ -33209,7 +33209,7 @@ ie0:.space 8 .global _start .text _start: - addis 9,13,ie0@got@tprel@ha + addis 9,2,ie0@got@tprel@ha ld 9,ie0@got@tprel@l(9) EOF if $gcc_cv_as -a64 -o conftest.o conftest.s > /dev/null 2>&1 \ diff --git a/gcc/configure.ac b/gcc/configure.ac index 7e57d527ecdd..19975fa5be5b 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -6789,7 +6789,7 @@ ie0: .space 8 .global _start .text _start: - addis 9,13,ie0@got@tprel@ha + addis 9,2,ie0@got@tprel@ha ld 9,ie0@got@tprel@l(9) EOF if $gcc_cv_as -a64 -o conftest.o conftest.s > /dev/null 2>&1 \
[gcc r16-3898] i386/testsuite: Fix non unique name tests
https://gcc.gnu.org/g:89a7d765ecabd47ee609ca0a3bfbd14ff27abc77 commit r16-3898-g89a7d765ecabd47ee609ca0a3bfbd14ff27abc77 Author: Haochen Jiang Date: Mon Sep 15 15:17:35 2025 +0800 i386/testsuite: Fix non unique name tests After r16-3651, compare_tests script will explicitly mention those tests have the same name. This helps us review all the tests we have. Among them, most of them are unintentional typos (e.g., keep testing the same vector size for scan-assembler). Fix them through this commit. gcc/testsuite/ChangeLog: * gcc.target/i386/avx512bw-vpackssdw-1.c: Fix xmm/ymm mask tests. * gcc.target/i386/avx512bw-vpacksswb-1.c: Ditto. * gcc.target/i386/avx512bw-vpackusdw-1.c: Ditto. * gcc.target/i386/avx512bw-vpackuswb-1.c: Ditto. * gcc.target/i386/avx512bw-vpermw-1.c: Test xmm. * gcc.target/i386/avx512bw-vpmulhw-1.c: Fix xmm/ymm mask tests. * gcc.target/i386/avx512f-vec-init.c: Remove duplicate test. * gcc.target/i386/avx512fp16-13.c: Fix test for aligned load. * gcc.target/i386/avx512fp16-conjugation-1.c: Revise the test to test more precisely on masks. * gcc.target/i386/avx512fp16vl-conjugation-1.c: Ditto. * gcc.target/i386/avx512vbmi-vpermb-1.c: Test xmm. * gcc.target/i386/avx512vl-vcvtpd2ps-1.c: Fix scan asm. * gcc.target/i386/avx512vl-vinsert-1.c: Fix typo. * gcc.target/i386/avx512vl-vpmulld-1.c: Fix xmm/ymm mask tests. * gcc.target/i386/avx512vl-vptestmd-1.c: Ditto. * gcc.target/i386/bitwise_mask_op-1.c: Fix typo. * gcc.target/i386/cond_op_shift_q-1.c: Test both vpsra{,v} and vpsll{,v}. * gcc.target/i386/cond_op_shift_ud-1.c: Ditto. * gcc.target/i386/cond_op_shift_uq-1.c: Ditto. * gcc.target/i386/memcpy-pr95886.c: Fix the wrong const int. * gcc.target/i386/part-vect-sqrtph-1.c: Remove duplicate test. * gcc.target/i386/pr107432-7.c: Test vpmov{s,z}xbw instead of vpmov{s,z}xbd. * gcc.target/i386/pr88828-0.c: Fix pblendw scan asm. Diff: --- gcc/testsuite/gcc.target/i386/avx512bw-vpackssdw-1.c| 4 ++-- gcc/testsuite/gcc.target/i386/avx512bw-vpacksswb-1.c| 4 ++-- gcc/testsuite/gcc.target/i386/avx512bw-vpackusdw-1.c| 4 ++-- gcc/testsuite/gcc.target/i386/avx512bw-vpackuswb-1.c| 4 ++-- gcc/testsuite/gcc.target/i386/avx512bw-vpermw-1.c | 6 +++--- gcc/testsuite/gcc.target/i386/avx512bw-vpmulhw-1.c | 6 +++--- gcc/testsuite/gcc.target/i386/avx512f-vec-init.c| 1 - gcc/testsuite/gcc.target/i386/avx512fp16-13.c | 7 --- .../gcc.target/i386/avx512fp16-conjugation-1.c | 13 - .../gcc.target/i386/avx512fp16vl-conjugation-1.c| 17 ++--- gcc/testsuite/gcc.target/i386/avx512vbmi-vpermb-1.c | 6 +++--- gcc/testsuite/gcc.target/i386/avx512vl-vcvtpd2ps-1.c| 8 gcc/testsuite/gcc.target/i386/avx512vl-vinsert-1.c | 2 +- gcc/testsuite/gcc.target/i386/avx512vl-vpmulld-1.c | 4 ++-- gcc/testsuite/gcc.target/i386/avx512vl-vptestmd-1.c | 4 ++-- gcc/testsuite/gcc.target/i386/bitwise_mask_op-1.c | 2 +- gcc/testsuite/gcc.target/i386/cond_op_shift_q-1.c | 4 ++-- gcc/testsuite/gcc.target/i386/cond_op_shift_ud-1.c | 4 ++-- gcc/testsuite/gcc.target/i386/cond_op_shift_uq-1.c | 4 ++-- gcc/testsuite/gcc.target/i386/memcpy-pr95886.c | 2 +- gcc/testsuite/gcc.target/i386/part-vect-sqrtph-1.c | 1 - gcc/testsuite/gcc.target/i386/pr107432-7.c | 8 gcc/testsuite/gcc.target/i386/pr88828-0.c | 4 +--- 23 files changed, 53 insertions(+), 66 deletions(-) diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpackssdw-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpackssdw-1.c index 70bef644d523..4bb0be1258cf 100644 --- a/gcc/testsuite/gcc.target/i386/avx512bw-vpackssdw-1.c +++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpackssdw-1.c @@ -4,8 +4,8 @@ /* { dg-final { scan-assembler-times "vpackssdw\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vpackssdw\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}{z}(?:\n|\[ \\t\]+#)" 1 } } */ /* { dg-final { scan-assembler-times "vpackssdw\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */ -/* { dg-final { scan-assembler-times "vpackssdw\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */ -/* { dg-final { scan-assembler-times "vpackssdw\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}{z}(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpackssdw\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}{z}(?:\n|\[ \\t\]+#)" 1 } } */ +/* { dg-final { scan-assembler-times "vpackssdw\[ \\t\]+\[^\{\n\]*%xmm\[
[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 gfc_get_scalar_to_descriptor_type
https://gcc.gnu.org/g:94d5fa0b04041270b0ae1ae20a9a293c714c7749 commit 94d5fa0b04041270b0ae1ae20a9a293c714c7749 Author: Mikael Morin Date: Thu Aug 7 14:05:20 2025 +0200 Refactoring gfc_get_scalar_to_descriptor_type Correction gfc_get_scalar_to_descriptor_type Correction gfc_get_scalar_to_descriptor_type Diff: --- gcc/fortran/trans-expr.cc | 6 +++--- gcc/fortran/trans-types.cc | 8 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 185554fcfe4e..f7bb11dbf52f 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -96,7 +96,7 @@ gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr) { tree desc, type, etype; - type = gfc_get_scalar_to_descriptor_type (scalar, attr); + type = gfc_get_scalar_to_descriptor_type (TREE_TYPE (scalar), attr); etype = TREE_TYPE (scalar); desc = gfc_create_var (type, "desc"); DECL_ARTIFICIAL (desc) = 1; @@ -903,7 +903,7 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym, if (fsym->ts.u.derived->components->as) { tree type; - type = gfc_get_scalar_to_descriptor_type (parmse->expr, + 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)); @@ -1312,7 +1312,7 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts, { if (e->rank == 0) { - tree type = gfc_get_scalar_to_descriptor_type (parmse->expr, + tree type = gfc_get_scalar_to_descriptor_type (TREE_TYPE (parmse->expr), gfc_expr_attr (e)); gfc_conv_descriptor_dtype_set (&block, ctree, gfc_get_dtype (type)); diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc index e0eed7da7fe3..cc9ddeb463fe 100644 --- a/gcc/fortran/trans-types.cc +++ b/gcc/fortran/trans-types.cc @@ -2167,7 +2167,7 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound, arrays. */ tree -gfc_get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr) +gfc_get_scalar_to_descriptor_type (tree scalar_type, symbol_attribute attr) { enum gfc_array_kind akind; @@ -2178,9 +2178,9 @@ gfc_get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr) else akind = GFC_ARRAY_ASSUMED_SHAPE_CONT; - if (POINTER_TYPE_P (TREE_TYPE (scalar))) -scalar = TREE_TYPE (scalar); - return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1, + if (POINTER_TYPE_P (scalar_type)) +scalar_type = TREE_TYPE (scalar_type); + return gfc_get_array_type_bounds (scalar_type, 0, 0, NULL, NULL, 1, akind, !(attr.pointer || attr.target)); }
[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)] Suppression gfc_conv_descriptor_version compil' OK
https://gcc.gnu.org/g:89f9fd003f1e0862d801fad842076c200cb63322 commit 89f9fd003f1e0862d801fad842076c200cb63322 Author: Mikael Morin Date: Sun Jun 29 12:58:32 2025 +0200 Suppression gfc_conv_descriptor_version compil' OK Suppression non_lvalue version_get Ajout location version_set Suppression mise à la ligne version_set Diff: --- gcc/fortran/trans-array.cc | 23 +-- gcc/fortran/trans-descriptor.cc | 19 +-- gcc/fortran/trans-descriptor.h | 3 ++- gcc/fortran/trans.cc| 5 ++--- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index ea9bc1da516c..496fc9790024 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -6455,10 +6455,11 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg, build_tree_list (NULL_TREE, alloc), DECL_ATTRIBUTES (omp_alt_alloc)); omp_alt_alloc = build_call_expr (omp_alt_alloc, 3, align, sz, alloc); - succ_add_expr = fold_build2_loc (input_location, MODIFY_EXPR, - void_type_node, - gfc_conv_descriptor_version (se->expr), + stmtblock_t tmp_block; + gfc_init_block (&tmp_block); + gfc_conv_descriptor_version_set (&tmp_block, se->expr, build_int_cst (integer_type_node, 1)); + succ_add_expr = gfc_finish_block (&tmp_block); } /* The allocatable variant takes the old pointer as first argument. */ @@ -10600,10 +10601,12 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest, { tree cd, t; if (c->attr.pdt_array) - cd = fold_build2_loc (input_location, EQ_EXPR, - boolean_type_node, - gfc_conv_descriptor_version (comp), - build_int_cst (integer_type_node, 1)); + { + tree version = gfc_conv_descriptor_version_get (comp); + cd = fold_build2_loc (input_location, EQ_EXPR, + boolean_type_node, version, + build_int_cst (integer_type_node, 1)); + } else cd = gfc_omp_call_is_alloc (tmp); t = builtin_decl_explicit (BUILT_IN_GOMP_FREE); @@ -10613,8 +10616,8 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest, gfc_init_block (&tblock); gfc_add_expr_to_block (&tblock, t); if (c->attr.pdt_array) - gfc_add_modify (&tblock, gfc_conv_descriptor_version (comp), - integer_zero_node); + gfc_conv_descriptor_version_set (&tblock, comp, +integer_zero_node); tmp = build3_loc (input_location, COND_EXPR, void_type_node, cd, gfc_finish_block (&tblock), gfc_call_free (tmp)); @@ -11665,7 +11668,7 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop, { tree cond, omp_tmp; cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, - gfc_conv_descriptor_version (desc), + gfc_conv_descriptor_version_get (desc), build_int_cst (integer_type_node, 1)); omp_tmp = builtin_decl_explicit (BUILT_IN_GOMP_REALLOC); omp_tmp = build_call_expr_loc (input_location, omp_tmp, 4, diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 8fe0e3bfaa9d..02c1cbdfb8ea 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -298,8 +298,8 @@ gfc_conv_descriptor_rank (tree desc) } -tree -gfc_conv_descriptor_version (tree desc) +static tree +get_descriptor_version (tree desc) { tree tmp; tree dtype; @@ -312,6 +312,21 @@ gfc_conv_descriptor_version (tree desc) dtype, tmp, NULL_TREE); } +tree +gfc_conv_descriptor_version_get (tree desc) +{ + return get_descriptor_version (desc); +} + +void +gfc_conv_descriptor_version_set (stmtblock_t *block, tree desc, tree value) +{ + location_t loc = input_location; + tree t = get_descriptor_version (desc); + gfc_add_modify_loc (loc, block, t, + fold_convert_loc (loc, TREE_TYPE (t), value)); +} + /* Return the element length from the descriptor dtype field. */ diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index 8cd65b46f5fa..e5300bf0704e 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-de
[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)] Extraction gfc_copy_descriptor
https://gcc.gnu.org/g:f20d1d53e139de278a6f23daa86ecf55211d3cfb commit f20d1d53e139de278a6f23daa86ecf55211d3cfb Author: Mikael Morin Date: Wed Jul 16 22:09:17 2025 +0200 Extraction gfc_copy_descriptor Diff: --- gcc/fortran/trans-array.cc | 25 ++--- gcc/fortran/trans-descriptor.cc | 33 + gcc/fortran/trans-descriptor.h | 1 + 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 123e7de97566..4572d16313fa 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -7871,29 +7871,8 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) if (full && !transposed_dims (ss)) { if (se->direct_byref && !se->byref_noassign) - { - struct lang_type *lhs_ls - = TYPE_LANG_SPECIFIC (TREE_TYPE (se->expr)), - *rhs_ls = TYPE_LANG_SPECIFIC (TREE_TYPE (desc)); - /* When only the array_kind differs, do a view_convert. */ - tmp = lhs_ls && rhs_ls && lhs_ls->rank == rhs_ls->rank - && lhs_ls->akind != rhs_ls->akind - ? build1 (VIEW_CONVERT_EXPR, TREE_TYPE (se->expr), desc) - : desc; - /* Copy the descriptor for pointer assignments. */ - gfc_add_modify (&se->pre, se->expr, tmp); - - /* Add any offsets from subreferences. */ - gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE, - subref_array_target, expr); - - /* and set the span field. */ - if (ss_info->expr->ts.type == BT_CHARACTER) - tmp = gfc_conv_descriptor_span_get (desc); - else - tmp = gfc_get_array_span (desc, expr); - gfc_conv_descriptor_span_set (&se->pre, se->expr, tmp); - } + gfc_copy_descriptor (&se->pre, se->expr, desc, expr, +subref_array_target); else if (se->want_pointer) { /* We pass full arrays directly. This means that pointers and diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index d5ca4d4fb82f..8b80c332f47d 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -1270,3 +1270,36 @@ gfc_copy_sequence_descriptor (stmtblock_t *block, tree dest, tree src, int rank) gfc_conv_descriptor_span_get (src)); gfc_conv_descriptor_offset_set (block, dest, gfc_index_zero_node); } + + +void +gfc_copy_descriptor (stmtblock_t *block, tree dest, tree src, +gfc_expr *src_expr, bool subref) +{ + struct lang_type *dest_ls = TYPE_LANG_SPECIFIC (TREE_TYPE (dest)); + struct lang_type *src_ls = TYPE_LANG_SPECIFIC (TREE_TYPE (src)); + + /* When only the array_kind differs, do a view_convert. */ + tree tmp1; + if (dest_ls + && src_ls + && dest_ls->rank == src_ls->rank + && dest_ls->akind != src_ls->akind) +tmp1 = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dest), src); + else +tmp1 = src; + + /* Copy the descriptor for pointer assignments. */ + gfc_add_modify (block, dest, tmp1); + + /* Add any offsets from subreferences. */ + gfc_get_dataptr_offset (block, dest, src, NULL_TREE, subref, src_expr); + + /* and set the span field. */ + tree tmp2; + if (src_expr->ts.type == BT_CHARACTER) +tmp2 = gfc_conv_descriptor_span_get (src); + else +tmp2 = gfc_get_array_span (src, src_expr); + gfc_conv_descriptor_span_set (block, dest, tmp2); +} diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index cb920ff2cbbb..3a22abab72c2 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -108,6 +108,7 @@ void gfc_shift_descriptor (stmtblock_t *, tree, int, tree [GFC_MAX_DIMENSIONS], 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_set_descriptor_from_scalar_class (stmtblock_t *, tree, tree, gfc_expr *); void gfc_set_descriptor_from_scalar (stmtblock_t *, tree, tree, symbol_attribute,
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: Correction assertion évaluation LSHIFT_EXPR et RSHIFT_EXPR
https://gcc.gnu.org/g:4425aca695b084e862b9ecdeaaf0e3725d2b480a commit 4425aca695b084e862b9ecdeaaf0e3725d2b480a Author: Mikael Morin Date: Fri Aug 29 10:14:50 2025 +0200 gimple-simulate: Correction assertion évaluation LSHIFT_EXPR et RSHIFT_EXPR Diff: --- gcc/gimple-simulate.cc | 41 - 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc index 4fc64d342089..0951731a1d2c 100644 --- a/gcc/gimple-simulate.cc +++ b/gcc/gimple-simulate.cc @@ -2105,7 +2105,9 @@ simul_scope::evaluate_binary (enum tree_code code, tree type, tree lhs, && TYPE_PRECISION (TREE_TYPE (lhs)) == TYPE_PRECISION (TREE_TYPE (rhs)) && TYPE_UNSIGNED (TREE_TYPE (lhs)) -== TYPE_UNSIGNED (TREE_TYPE (rhs; +== TYPE_UNSIGNED (TREE_TYPE (rhs))) + || code == LSHIFT_EXPR + || code == RSHIFT_EXPR); tree lval = val_lhs.to_tree (TREE_TYPE (lhs)); tree rval = val_rhs.to_tree (TREE_TYPE (rhs)); tree t = fold_binary (code, type, lval, rval); @@ -5723,6 +5725,43 @@ simul_scope_evaluate_binary_tests () wide_int wi_ne5 = val_ne5.get_known (); ASSERT_PRED1 (wi::fits_uhwi_p, wi_ne5); ASSERT_EQ (wi_ne5.to_uhwi (), 1); + + + tree l6 = create_var (long_integer_type_node, "l6"); + + vec decls6{}; + decls6.safe_push (l6); + + context_builder builder6 {}; + builder6.add_decls (&decls6); + simul_scope ctx6 = builder6.build (mem, printer); + + wide_int wi11_6 = wi::shwi (11, TYPE_PRECISION (long_integer_type_node)); + data_value cst11_6 (long_integer_type_node); + cst11_6.set_known (wi11_6); + data_storage *strg_l6 = ctx6.find_reachable_var (l6); + gcc_assert (strg_l6 != nullptr); + strg_l6->set (cst11_6); + + tree int3 = build_int_cst (integer_type_node, 3); + data_value lshift_6 = ctx6.evaluate_binary (LSHIFT_EXPR, + long_integer_type_node, + l6, int3); + + ASSERT_EQ (lshift_6.classify (), VAL_KNOWN); + wide_int wi_lshift6 = lshift_6.get_known (); + ASSERT_PRED1 (wi::fits_shwi_p, wi_lshift6); + ASSERT_EQ (wi_lshift6.to_shwi (), 88); + + tree int1 = build_int_cst (integer_type_node, 1); + data_value rshift_6 = ctx6.evaluate_binary (RSHIFT_EXPR, + long_integer_type_node, + l6, int1); + + ASSERT_EQ (rshift_6.classify (), VAL_KNOWN); + wide_int wi_rshift6 = rshift_6.get_known (); + ASSERT_PRED1 (wi::fits_shwi_p, wi_rshift6); + ASSERT_EQ (wi_rshift6.to_shwi (), 5); }
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Utilisation gfc_conv_descriptor_token_set
https://gcc.gnu.org/g:812ddeb416400232a8688af1e5dfaaca2ea2443d commit 812ddeb416400232a8688af1e5dfaaca2ea2443d Author: Mikael Morin Date: Tue Jul 15 17:17:33 2025 +0200 Utilisation gfc_conv_descriptor_token_set Diff: --- gcc/fortran/trans-array.cc | 12 +--- gcc/fortran/trans-descriptor.cc | 10 ++ gcc/fortran/trans-descriptor.h | 1 + gcc/fortran/trans-expr.cc | 12 +--- gcc/fortran/trans-intrinsic.cc | 3 +-- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 1fc95f54312a..bfb14f04bd7e 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -8444,7 +8444,7 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) tmp = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (tmp)); } - gfc_add_modify (&loop.pre, gfc_conv_descriptor_token (parm), tmp); + gfc_conv_descriptor_token_set (&loop.pre, parm, tmp); } desc = parm; } @@ -9053,7 +9053,7 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, bool g77, } else if (!ctree) { - tree old_field, new_field; + tree old_field; /* The original descriptor has transposed dims so we can't reuse it directly; we have to create a new one. */ @@ -9081,8 +9081,8 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, bool g77, == GFC_ARRAY_ALLOCATABLE) { old_field = gfc_conv_descriptor_token (old_desc); - new_field = gfc_conv_descriptor_token (new_desc); - gfc_add_modify (&se->pre, new_field, old_field); + gfc_conv_descriptor_token_set (&se->pre, new_desc, +old_field); } gfc_conv_descriptor_data_set (&se->pre, new_desc, ptr); @@ -11938,9 +11938,7 @@ gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block) image. This may happen, for example, with the caf_mpi implementation. */ TREE_STATIC (descriptor) = 1; - tmp = gfc_conv_descriptor_token (descriptor); - gfc_add_modify (&init, tmp, fold_convert (TREE_TYPE (tmp), - null_pointer_node)); + gfc_conv_descriptor_token_set (&init, descriptor, null_pointer_node); } } diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 578dcb21ef06..1430f948bd1f 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -519,6 +519,16 @@ gfc_conv_descriptor_token (tree desc) return field; } +void +gfc_conv_descriptor_token_set (stmtblock_t *block, tree desc, tree value) +{ + location_t loc = input_location; + tree t = gfc_conv_descriptor_token (desc); + gfc_add_modify_loc (loc, block, t, + fold_convert_loc (loc, TREE_TYPE (t), value)); +} + + static tree gfc_conv_descriptor_subfield (tree desc, tree dim, unsigned field_idx) { diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index 0547157bf2af..3f602219c284 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -83,6 +83,7 @@ void gfc_conv_descriptor_dimension_set (stmtblock_t *block, tree desc, int dim, 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); tree gfc_build_null_descriptor (tree type); diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 884ade4912bf..251a9b430cfa 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -849,7 +849,7 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym, 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_add_modify (&parmse->pre, gfc_conv_descriptor_token (ctree), token); + gfc_conv_descriptor_token_set (&parmse->pre, ctree, token); } if (optional) @@ -9886,8 +9886,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, { gfc_conv_descriptor_data_set (&block, dest, null_pointer_node); if (cm->attr.codimension && flag_coarray == GFC_FCOARRAY_LIB) - gfc_add_modify (&block, gfc_conv_descriptor_token (dest), - null_pointer_node); + gfc_conv_descriptor_token_set (&block, dest, null_pointer_node); } else if (cm->attr.allocatable || cm->attr.pdt_array) { @@ -11640,10 +11639,9 @@ gfc_trans_scalar
[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)] Factorisation set_dimension_fields gfc_set_descriptor
https://gcc.gnu.org/g:215eb06af7873eb0c10f393382343db0703ea2fc commit 215eb06af7873eb0c10f393382343db0703ea2fc Author: Mikael Morin Date: Sat Aug 16 18:11:01 2025 +0200 Factorisation set_dimension_fields gfc_set_descriptor Diff: --- gcc/fortran/trans-descriptor.cc | 17 ++--- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index d16127cf3ed7..ce7495ab1f34 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -1860,27 +1860,14 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree src, gfc_expr *src_expr, tree from = lowers[dim]; tree to = uppers[dim]; - gfc_conv_descriptor_lbound_set (block, dest, - gfc_rank_cst[dim], from); - - /* Set the new upper bound. */ - gfc_conv_descriptor_ubound_set (block, dest, - gfc_rank_cst[dim], to); - /* Multiply the stride by the section stride to get the total stride. */ stride = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, stride, info->stride[n]); - tmp = fold_build2_loc (input_location, MULT_EXPR, -TREE_TYPE (offset), stride, from); - offset = fold_build2_loc (input_location, MINUS_EXPR, - TREE_TYPE (offset), offset, tmp); - - /* Store the new stride. */ - gfc_conv_descriptor_stride_set (block, dest, - gfc_rank_cst[dim], stride); + set_dimension_fields (block, dest, gfc_rank_cst[dim], from, to, stride, + &offset); } for (int n = rank; n < rank + corank; n++)
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: Correction ICE évaluation adresse
https://gcc.gnu.org/g:bef04edec0a6debb12aff1c9d0e0492ee24f7408 commit bef04edec0a6debb12aff1c9d0e0492ee24f7408 Author: Mikael Morin Date: Fri Aug 29 20:05:33 2025 +0200 gimple-simulate: Correction ICE évaluation adresse Diff: --- gcc/gimple-simulate.cc | 60 ++ 1 file changed, 60 insertions(+) diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc index e0cf25eb97aa..9333c64aa77d 100644 --- a/gcc/gimple-simulate.cc +++ b/gcc/gimple-simulate.cc @@ -1850,6 +1850,9 @@ simul_scope::get_storage (unsigned idx) const } +const simul_scope * current_scope; + + tree simul_valueize (tree t) { @@ -1861,9 +1864,21 @@ simul_valueize (tree t) && gimple_assign_rhs_code (def) == ADDR_EXPR) return gimple_assign_rhs1 (def); + data_value val = current_scope->evaluate (t); + switch (val.classify ()) + { + case VAL_KNOWN: + return val.to_tree (TREE_TYPE (t)); + + default: + gcc_unreachable (); + } + +#if 0 tree c = gimple_fold_stmt_to_constant (def, simul_valueize); if (c != NULL_TREE) return c; +#endif } return t; @@ -1937,9 +1952,13 @@ simul_scope::evaluate (tree expr) const else { poly_int64 offset; + + const simul_scope * sauv = current_scope; + current_scope = this; tree var = get_addr_base_and_unit_offset_1 (TREE_OPERAND (expr, 0), &offset, simul_valueize); + current_scope = sauv; HOST_WIDE_INT off; bool is_constant = offset.is_constant (&off); @@ -4327,6 +4346,47 @@ context_printer_print_first_data_ref_part_tests () const char * str13 = pp_formatted_text (&pp13); ASSERT_STREQ (str13, "# var1s1l[0].der1s1l_l2"); ASSERT_EQ (ignored_bits, HOST_BITS_PER_LONG - HOST_BITS_PER_SHORT); + + + heap_memory mem14; + context_printer printer14; + pretty_printer & pp14 = printer14.pp; + + tree a2d2i = build_array_type_nelts (der2i, 2); + tree a14 = create_var (a2d2i, "a14"); + tree p_14 = create_var (ptr_type_node, "p"); + + vec decls14{}; + decls14.safe_push (a14); + decls14.safe_push (p_14); + + context_builder builder14 {}; + builder14.add_decls (&decls14); + simul_scope ctx14 = builder14.build (mem14, printer14); + + data_storage *strg_a14 = ctx14.find_reachable_var (a14); + gcc_assert (strg_a14 != nullptr); + + storage_address addr_a14 (strg_a14->get_ref (), 0); + data_value val_p14 (ptr_type_node); + val_p14.set_address (addr_a14); + + data_storage *strg_p14 = ctx14.find_reachable_var (p_14); + gcc_assert (strg_p14 != nullptr); + strg_p14->set (val_p14); + + tree zero_off = build_zero_cst (build_pointer_type (void_type_node)); + tree ref_a14 = build2 (MEM_REF, der2i, p_14, zero_off); + tree ref14 = build3 (COMPONENT_REF, integer_type_node, ref_a14, + der2i_i2, NULL_TREE); + + tree res14 = printer14.print_first_data_ref_part (ctx14, ref14, 0, + nullptr, + VAL_UNDEFINED); + + ASSERT_EQ (res14, integer_type_node); + const char * str14 = pp_formatted_text (&pp14); + ASSERT_STREQ (str14, "# a14[0].der2i_i2"); }
[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)] gimple-simulate: Correction ICE MEM_REF avec offset négatif
https://gcc.gnu.org/g:8e155f7ca562bcf865e06959777a5a81edd7751b commit 8e155f7ca562bcf865e06959777a5a81edd7751b Author: Mikael Morin Date: Fri Aug 29 11:24:15 2025 +0200 gimple-simulate: Correction ICE MEM_REF avec offset négatif Diff: --- gcc/gimple-simulate.cc | 53 +- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc index 0951731a1d2c..9187efce399c 100644 --- a/gcc/gimple-simulate.cc +++ b/gcc/gimple-simulate.cc @@ -926,12 +926,12 @@ 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_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; + wide_int wi_offset = wi::to_wide (access_offset); + wide_int remaining_offset = wi_offset * CHAR_BIT + + offset + ptr_address->offset; + gcc_assert (wi::ges_p (remaining_offset, 0) + && wi::fits_shwi_p (remaining_offset)); if (TREE_CODE (data_ref) == TARGET_MEM_REF) { tree idx = TREE_OPERAND (data_ref, 2); @@ -945,12 +945,11 @@ find_mem_ref_replacement (simul_scope & context, tree data_ref, 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; + remaining_offset += wi_idx * CHAR_BIT; } - return pick_subref_at (var_ref, remaining_offset, nullptr, min_size); + return pick_subref_at (var_ref, remaining_offset.to_shwi (), nullptr, +min_size); } } @@ -4181,6 +4180,42 @@ context_printer_print_first_data_ref_part_tests () ASSERT_EQ (res11, integer_type_node); const char * str11 = pp_formatted_text (&pp11); ASSERT_STREQ (str11, "# var_i"); + + + tree a2i = build_array_type_nelts (integer_type_node, 2); + tree i12 = create_var (a2i, "i12"); + tree p12 = create_var (ptr_type_node, "p12"); + + context_printer printer12; + pretty_printer & pp12 = printer12.pp; + + vec decls12{}; + decls12.safe_push (i12); + decls12.safe_push (p12); + + context_builder builder12 {}; + builder12.add_decls (&decls12); + heap_memory mem12; + simul_scope ctx12 = builder12.build (mem12, printer12); + + data_storage *strg_i12 = ctx12.find_reachable_var (i12); + storage_address addr_i12 (strg_i12->get_ref (), 8); + + data_value val_addr12 (ptr_type_node); + val_addr12.set_address (addr_i12); + + data_storage *strg_p12 = ctx12.find_reachable_var (p12); + strg_p12->set (val_addr12); + + tree ref_i12 = build2 (MEM_REF, integer_type_node, p12, +build_minus_one_cst (ptr_type_node)); + + tree res12 = printer12.print_first_data_ref_part (ctx12, ref_i12, 0, nullptr, + VAL_UNDEFINED); + + ASSERT_EQ (res12, integer_type_node); + const char * str12 = pp_formatted_text (&pp12); + ASSERT_STREQ (str12, "# i12[0]"); }
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Suppression gfc_conv_descriptor_dimension compil' OK
https://gcc.gnu.org/g:d49656e0fc7106efa9379bcfd4369190f401625d commit d49656e0fc7106efa9379bcfd4369190f401625d Author: Mikael Morin Date: Sun Jun 29 14:28:16 2025 +0200 Suppression gfc_conv_descriptor_dimension compil' OK Suppression non_lvalue dimension_get ajout location dimension_set Diff: --- gcc/fortran/trans-array.cc | 10 +- gcc/fortran/trans-descriptor.cc | 35 --- gcc/fortran/trans-descriptor.h | 5 - 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index be2eef61ac95..1fc95f54312a 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -9068,11 +9068,11 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, bool g77, for (int i = 0; i < expr->rank; i++) { - old_field = gfc_conv_descriptor_dimension (old_desc, - gfc_rank_cst[get_array_ref_dim_for_loop_dim (ss, i)]); - new_field = gfc_conv_descriptor_dimension (new_desc, - gfc_rank_cst[i]); - gfc_add_modify (&se->pre, new_field, old_field); + int idx = get_array_ref_dim_for_loop_dim (ss, i); + old_field = gfc_conv_descriptor_dimension_get (old_desc, idx); + gfc_conv_descriptor_dimension_set (&se->pre, new_desc, i, +old_field); + } if (flag_coarray == GFC_FCOARRAY_LIB diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 9d04a4801233..578dcb21ef06 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -468,8 +468,8 @@ gfc_get_descriptor_dimension (tree desc) } -tree -gfc_conv_descriptor_dimension (tree desc, tree dim) +static tree +get_descriptor_dimension (tree desc, tree dim) { tree tmp; @@ -478,6 +478,35 @@ gfc_conv_descriptor_dimension (tree desc, tree dim) return gfc_build_array_ref (tmp, dim, NULL_TREE, true); } +tree +gfc_conv_descriptor_dimension_get (tree desc, tree dim) +{ + return get_descriptor_dimension (desc, dim); +} + +tree +gfc_conv_descriptor_dimension_get (tree desc, int dim) +{ + return gfc_conv_descriptor_dimension_get (desc, gfc_rank_cst[dim]); +} + +void +gfc_conv_descriptor_dimension_set (stmtblock_t *block, tree desc, tree dim, + tree value) +{ + location_t loc = input_location; + tree t = get_descriptor_dimension (desc, dim); + gfc_add_modify_loc (loc, block, t, + fold_convert_loc (loc, TREE_TYPE (t), value)); +} + +void +gfc_conv_descriptor_dimension_set (stmtblock_t *block, tree desc, int dim, + tree value) +{ + gfc_conv_descriptor_dimension_set (block, desc, gfc_rank_cst[dim], value); +} + tree gfc_conv_descriptor_token (tree desc) @@ -493,7 +522,7 @@ gfc_conv_descriptor_token (tree desc) static tree gfc_conv_descriptor_subfield (tree desc, tree dim, unsigned field_idx) { - tree tmp = gfc_conv_descriptor_dimension (desc, dim); + tree tmp = get_descriptor_dimension (desc, dim); tree field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), field_idx); gcc_assert (field != NULL_TREE); diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index 69cc4f3e2ac6..0547157bf2af 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -49,7 +49,6 @@ tree gfc_get_cfi_dim_sm (tree desc, tree idx); tree gfc_get_descriptor_dimension (tree desc); -tree gfc_conv_descriptor_dimension (tree desc, tree dim); tree gfc_conv_descriptor_token (tree desc); tree gfc_conv_descriptor_data_get (tree desc); @@ -61,6 +60,8 @@ tree gfc_conv_descriptor_rank_get (tree desc); tree gfc_conv_descriptor_type_get (tree desc); tree gfc_conv_descriptor_span_get (tree desc); +tree gfc_conv_descriptor_dimension_get (tree desc, tree dim); +tree gfc_conv_descriptor_dimension_get (tree desc, int dim); tree gfc_conv_descriptor_stride_get (tree desc, tree dim); tree gfc_conv_descriptor_lbound_get (tree desc, tree dim); tree gfc_conv_descriptor_ubound_get (tree desc, tree dim); @@ -77,6 +78,8 @@ 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 g
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Interdiction non-lvalue as lhs
https://gcc.gnu.org/g:4e739e5b36e56a8c8e6ce39b941dad9c809a4ff9 commit 4e739e5b36e56a8c8e6ce39b941dad9c809a4ff9 Author: Mikael Morin Date: Tue Feb 11 21:34:11 2025 +0100 Interdiction non-lvalue as lhs git commit correction erreur gimplify Diff: --- gcc/gimplify.cc | 6 ++ 1 file changed, 6 insertions(+) diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index ca1fa2189cb9..2baf07dddb4f 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -7248,6 +7248,12 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR || TREE_CODE (*expr_p) == INIT_EXPR); + if (TREE_CODE (*to_p) == NON_LVALUE_EXPR) +{ + error ("non-lvalue used as lhs in %qD", *expr_p); + return GS_ERROR; +} + /* Trying to simplify a clobber using normal logic doesn't work, so handle it here. */ if (TREE_CLOBBER_P (*from_p))
[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)] 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 set_dtype_if_unallocated
https://gcc.gnu.org/g:93dbd09fceb543ca2474efcc6d4fcc68b33f8eeb commit 93dbd09fceb543ca2474efcc6d4fcc68b33f8eeb Author: Mikael Morin Date: Sun Aug 10 11:03:57 2025 +0200 Suppression set_dtype_if_unallocated Extraction gfc_descriptor_set_dtype_if_unallocated Sauvegarde Revert partiel Sauvegarde Correction indentation Diff: --- gcc/fortran/trans-array.cc | 2 +- gcc/fortran/trans-descriptor.cc | 33 +++-- gcc/fortran/trans-descriptor.h | 2 +- gcc/fortran/trans-expr.cc | 104 ++-- 4 files changed, 58 insertions(+), 83 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 7449670d2f52..c31a66d0e8d6 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -547,7 +547,7 @@ void gfc_trans_static_array_pointer (gfc_symbol * sym) { gcc_assert (TREE_STATIC (sym->backend_decl)); - gfc_init_static_descriptor (sym->backend_decl); + gfc_init_static_descriptor (sym); } diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 048184afb76b..ad07726d52bc 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -848,10 +848,38 @@ gfc_init_absent_descriptor (stmtblock_t *block, tree descr) void -gfc_init_static_descriptor (tree descr) +gfc_init_static_descriptor (gfc_symbol *sym) { + vec *v = NULL; + + tree descr = sym->backend_decl; tree type = TREE_TYPE (descr); - DECL_INITIAL (descr) = gfc_build_null_descriptor (type); + + gcc_assert (GFC_DESCRIPTOR_TYPE_P (type)); + tree fields = TYPE_FIELDS (type); + + tree data_field = gfc_advance_chain (fields, DATA_FIELD); + CONSTRUCTOR_APPEND_ELT (v, data_field, + fold_convert (TREE_TYPE (data_field), + null_pointer_node)); + + gfc_array_spec *as; + if (sym->ts.type == BT_CLASS) +as = CLASS_DATA (sym)->as; + else +as = sym->as; + + int rank = as ? as->rank : 0; + tree dtype_field = gfc_advance_chain (fields, DTYPE_FIELD); + tree dtype_value = gfc_get_dtype_rank_type (rank, + gfc_get_element_type (type)); + CONSTRUCTOR_APPEND_ELT (v, dtype_field, + fold_convert (TREE_TYPE (dtype_field), dtype_value)); + + tree constr = build_constructor (type, v); + TREE_CONSTANT (constr) = 1; + + DECL_INITIAL (descr) = constr; } @@ -2806,4 +2834,3 @@ gfc_set_empty_descriptor_bounds (stmtblock_t *block, tree descr, int rank) 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 6ca550fe8de2..40e1586ce5f7 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -86,7 +86,7 @@ gfc_get_descriptor_offsets_for_info (const_tree desc_type, tree *data_off, void gfc_nullify_descriptor (stmtblock_t *block, tree); void gfc_init_descriptor_result (stmtblock_t *block, tree descr); void gfc_init_absent_descriptor (stmtblock_t *block, tree descr); -void gfc_init_static_descriptor (tree descr); +void gfc_init_static_descriptor (gfc_symbol *); tree gfc_create_null_actual_descriptor (stmtblock_t *, gfc_typespec *, symbol_attribute, int); diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index a675c0fcdb44..20387351485c 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -5840,50 +5840,6 @@ expr_may_alias_variables (gfc_expr *e, bool array_may_alias) } -/* A helper function to set the dtype for unallocated or unassociated - entities. */ - -static void -set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e) -{ - tree tmp; - tree desc; - tree cond; - tree type; - stmtblock_t block; - - /* TODO Figure out how to handle optional dummies. */ - if (e && e->expr_type == EXPR_VARIABLE - && e->symtree->n.sym->attr.optional) -return; - - desc = parmse->expr; - if (desc == NULL_TREE) -return; - - if (POINTER_TYPE_P (TREE_TYPE (desc))) -desc = build_fold_indirect_ref_loc (input_location, desc); - if (GFC_CLASS_TYPE_P (TREE_TYPE (desc))) -desc = gfc_class_data_get (desc); - if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))) -return; - - gfc_init_block (&block); - tmp = gfc_conv_descriptor_data_get (desc); - cond = fold_build2_loc (input_location, EQ_EXPR, - logical_type_node, tmp, - build_int_cst (TREE_TYPE (tmp), 0)); - type = gfc_get_element_type (TREE_TYPE (desc)); - gfc_conv_descriptor_dtype_set (&block, desc, -gfc_get_dtype_rank_type (e->rank, type)); - cond = build3_v (COND_EXPR, cond, - gfc_finish_block (&block), - build_empty_stmt (input_location)); - gfc_add_expr_to_block (&parmse->pre, cond); -} - - - /* Provide an interface between gfortra
[gcc r14-12026] libstdc++: Fix memory leak in PSTL TBB backend [PR117276]
https://gcc.gnu.org/g:83926770efa15d5e0a1e265d26012bdd623fd75e commit r14-12026-g83926770efa15d5e0a1e265d26012bdd623fd75e Author: Jonathan Wakely Date: Fri Sep 12 12:49:39 2025 +0100 libstdc++: Fix memory leak in PSTL TBB backend [PR117276] Backport of upstream patch: https://github.com/uxlfoundation/oneDPL/pull/1589 libstdc++-v3/ChangeLog: PR libstdc++/117276 * include/pstl/parallel_backend_tbb.h (__func_task::finalize): Make deallocation unconditional. (cherry picked from commit d8f1655a781a76f5c86b3545b181b2005e585d29) Diff: --- libstdc++-v3/include/pstl/parallel_backend_tbb.h | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libstdc++-v3/include/pstl/parallel_backend_tbb.h b/libstdc++-v3/include/pstl/parallel_backend_tbb.h index 96e4b709fbee..d13883dd1d24 100644 --- a/libstdc++-v3/include/pstl/parallel_backend_tbb.h +++ b/libstdc++-v3/include/pstl/parallel_backend_tbb.h @@ -521,7 +521,7 @@ class __root_task friend class __func_task<_Func>; }; -#else // TBB_INTERFACE_VERSION <= 12000 +#else // TBB_INTERFACE_VERSION > 12000 class __task : public tbb::detail::d1::task { protected: @@ -656,10 +656,16 @@ class __func_task : public __task _PSTL_ASSERT(__parent != nullptr); _PSTL_ASSERT(__parent->_M_refcount.load(std::memory_order_relaxed) > 0); -if (--__parent->_M_refcount == 0) + +auto __refcount = --__parent->_M_refcount; + +// Placing the deallocation after the refcount decrement allows another thread to proceed with tree +// folding concurrently with this task cleanup. +__alloc.deallocate(this, *__ed); + +if (__refcount == 0) { _PSTL_ASSERT(__next == nullptr); -__alloc.deallocate(this, *__ed); return __parent; }
[gcc r14-12025] libstdc++: Remove blank line from bits/unique_ptr.h
https://gcc.gnu.org/g:3f53d9bdf07209674aaae4b2dd615e12e5322796 commit r14-12025-g3f53d9bdf07209674aaae4b2dd615e12e5322796 Author: Jonathan Wakely Date: Mon Sep 8 12:55:03 2025 +0100 libstdc++: Remove blank line from bits/unique_ptr.h libstdc++-v3/ChangeLog: * include/bits/unique_ptr.h: Remove blank line. (cherry picked from commit 15327920854653887e8715bb1592121cafec5c3b) Diff: --- libstdc++-v3/include/bits/unique_ptr.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index edcff78bff9f..71e2fd217acb 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -1,4 +1,3 @@ - // unique_ptr implementation -*- C++ -*- // Copyright (C) 2008-2024 Free Software Foundation, Inc.
[gcc r16-3888] Ada: Fix GNAT build failure for x32 multilib
https://gcc.gnu.org/g:e97969e20b39f33bc3644ae8a16bd5ef1e9ef2d3 commit r16-3888-ge97969e20b39f33bc3644ae8a16bd5ef1e9ef2d3 Author: Eric Botcazou Date: Mon Sep 15 23:02:52 2025 +0200 Ada: Fix GNAT build failure for x32 multilib gcc/ada PR ada/114065 PR ada/121953 * Makefile.rtl (LIBGNAT_TARGET_PAIRS) [x32-linux]: Replace libgnarl/s-osinte__x32.adb with libgnarl/s-osinte__posix.adb. * libgnarl/s-osinte__x32.adb: Delete. Diff: --- gcc/ada/Makefile.rtl | 2 +- gcc/ada/libgnarl/s-osinte__x32.adb | 73 -- 2 files changed, 1 insertion(+), 74 deletions(-) diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl index 0c290794309a..0fa2c51ceb6c 100644 --- a/gcc/ada/Makefile.rtl +++ b/gcc/ada/Makefile.rtl @@ -2943,7 +2943,7 @@ ifeq ($(strip $(filter-out %x32 linux%,$(target_cpu) $(target_os))),) s-intman.adbhttp://www.gnu.org/licenses/>. -- --- -- --- GNARL was developed by the GNARL team at Florida State University. -- --- Extensive contributions were provided by Ada Core Technologies, Inc. -- --- -- --- - --- This version is for Linux/x32 - --- This package encapsulates all direct interfaces to OS services --- that are needed by children of System. - -with Interfaces.C; - -package body System.OS_Interface is - - - -- Get_Stack_Base -- - - - function Get_Stack_Base (thread : pthread_t) return Address is - pragma Warnings (Off, thread); - - begin - return Null_Address; - end Get_Stack_Base; - - -- - -- pthread_init -- - -- - - procedure pthread_init is - begin - null; - end pthread_init; - - - -- To_Target_Priority -- - - - function To_Target_Priority - (Prio : System.Any_Priority) return Interfaces.C.int - is - begin - return Interfaces.C.int (Prio); - end To_Target_Priority; - -end System.OS_Interface;
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Refactoring get_ref_comp
https://gcc.gnu.org/g:eedee58b395b2f7e182917aac3b43f75aee9c044 commit eedee58b395b2f7e182917aac3b43f75aee9c044 Author: Mikael Morin Date: Wed Aug 6 14:23:40 2025 +0200 Refactoring get_ref_comp Renommage type Correction compil' Diff: --- gcc/fortran/trans-descriptor.cc | 57 +++-- 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index ee8487a6cc3c..b54910a5e93c 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -184,16 +184,24 @@ get_type_field (tree type, unsigned field_idx) static tree -gfc_get_descriptor_field (tree desc, unsigned field_idx) +get_ref_comp (tree ref, unsigned field_idx, tree type = NULL_TREE) { - tree type = TREE_TYPE (desc); - gcc_assert (GFC_DESCRIPTOR_TYPE_P (type)); - - tree field = get_type_field (type, field_idx); - gcc_assert (field != NULL_TREE); + tree field = get_type_field (TREE_TYPE (ref), field_idx); + gcc_assert (field != NULL_TREE + && (type == NULL_TREE + || TREE_TYPE (field) == type)); return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), - desc, field, NULL_TREE); + ref, field, NULL_TREE); +} + + +static tree +gfc_get_descriptor_field (tree desc, unsigned field_idx) +{ + gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))); + + return get_ref_comp (desc, field_idx); } @@ -305,15 +313,10 @@ gfc_conv_descriptor_span_set (stmtblock_t *block, tree desc, tree value) static tree get_descriptor_rank (tree desc) { - tree tmp; tree dtype; dtype = get_descriptor_dtype (desc); - tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), GFC_DTYPE_RANK); - gcc_assert (tmp != NULL_TREE - && TREE_TYPE (tmp) == signed_char_type_node); - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp), - dtype, tmp, NULL_TREE); + return get_ref_comp (dtype, GFC_DTYPE_RANK, signed_char_type_node); } tree @@ -340,15 +343,10 @@ gfc_conv_descriptor_rank_set (stmtblock_t *block, tree desc, int value) static tree get_descriptor_version (tree desc) { - tree tmp; tree dtype; dtype = get_descriptor_dtype (desc); - tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), GFC_DTYPE_VERSION); - gcc_assert (tmp != NULL_TREE - && TREE_TYPE (tmp) == integer_type_node); - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp), - dtype, tmp, NULL_TREE); + return get_ref_comp (dtype, GFC_DTYPE_VERSION, integer_type_node); } tree @@ -372,16 +370,10 @@ gfc_conv_descriptor_version_set (stmtblock_t *block, tree desc, tree value) static tree get_descriptor_elem_len (tree desc) { - tree tmp; tree dtype; dtype = get_descriptor_dtype (desc); - tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), - GFC_DTYPE_ELEM_LEN); - gcc_assert (tmp != NULL_TREE - && TREE_TYPE (tmp) == size_type_node); - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp), - dtype, tmp, NULL_TREE); + return get_ref_comp (dtype, GFC_DTYPE_ELEM_LEN, size_type_node); } tree @@ -403,15 +395,10 @@ gfc_conv_descriptor_elem_len_set (stmtblock_t *block, tree desc, tree value) static tree get_descriptor_type (tree desc) { - tree tmp; tree dtype; dtype = get_descriptor_dtype (desc); - tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), GFC_DTYPE_TYPE); - gcc_assert (tmp!= NULL_TREE - && TREE_TYPE (tmp) == signed_char_type_node); - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp), - dtype, tmp, NULL_TREE); + return get_ref_comp (dtype, GFC_DTYPE_TYPE, signed_char_type_node); } tree @@ -541,11 +528,7 @@ static tree gfc_conv_descriptor_subfield (tree desc, tree dim, unsigned field_idx) { tree tmp = get_descriptor_dimension (desc, dim); - tree field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), field_idx); - gcc_assert (field != NULL_TREE); - - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), - tmp, field, NULL_TREE); + return get_ref_comp (tmp, field_idx); } static tree
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Factorisation utilisation shapeval
https://gcc.gnu.org/g:fbe90409178cf8ff25cfbe391edb9d35c2edf56c commit fbe90409178cf8ff25cfbe391edb9d35c2edf56c Author: Mikael Morin Date: Sun Aug 17 19:56:14 2025 +0200 Factorisation utilisation shapeval 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 d283c741767f..f3d6d83fd902 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -1755,12 +1755,12 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, tree ptr, gfc_conv_expr (&shapese, shape); gfc_add_block_to_block (&body, &shapese.pre); + tree shapeval = fold_convert (gfc_array_index_type, shapese.expr); + shapeval = gfc_evaluate_now (shapeval, &body); tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, lbound, gfc_index_one_node); tree ubound = fold_build2_loc (input_location, PLUS_EXPR, -gfc_array_index_type, tmp, -fold_convert (gfc_array_index_type, - shapese.expr)); +gfc_array_index_type, tmp, shapeval); gfc_conv_descriptor_ubound_set (&body, desc, dim, ubound); gfc_add_block_to_block (&body, &shapese.post); @@ -1774,9 +1774,7 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, tree ptr, /* 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))); + gfc_array_index_type, stride, shapeval)); /* Finish scalarization loop. */ gfc_trans_scalarizing_loops (&loop, &body); gfc_add_block_to_block (block, &loop.pre);
[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_from_scalar
https://gcc.gnu.org/g:53b1048a8b2547b54c2d83e0eabb5d5e25c81c2a commit 53b1048a8b2547b54c2d83e0eabb5d5e25c81c2a Author: Mikael Morin Date: Thu Aug 7 14:11:43 2025 +0200 Extraction gfc_set_descriptor_from_scalar Correction gfc_get_scalar_to_descriptor_type Renommage set_descriptor_from_scalar{,_class} Diff: --- gcc/fortran/trans-descriptor.cc | 17 + gcc/fortran/trans-descriptor.h | 4 ++-- gcc/fortran/trans-expr.cc | 13 + 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index a73717f043e6..a3de865f73b6 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -933,3 +933,20 @@ gfc_create_null_actual_descriptor (stmtblock_t *block, gfc_typespec *ts, return desc; } + + +void +gfc_set_descriptor_from_scalar_class (stmtblock_t *block, tree descr, + tree scalar, gfc_expr *scalar_expr) +{ + 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)); + + tree tmp = gfc_class_data_get (scalar); + if (!POINTER_TYPE_P (TREE_TYPE (tmp))) +tmp = gfc_build_addr_expr (NULL_TREE, tmp); + + gfc_conv_descriptor_data_set (block, descr, tmp); +} diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index 4cbcc56f24b3..c7285529acf7 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -25,8 +25,6 @@ void gfc_set_scalar_null_descriptor (stmtblock_t *block, tree, gfc_symbol *, gfc void gfc_set_descriptor_with_shape (stmtblock_t *, tree, tree, gfc_expr *, locus *); tree gfc_get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr); -void gfc_set_descriptor_from_scalar (stmtblock_t *, tree, tree, -symbol_attribute *, tree = NULL_TREE); void gfc_copy_sequence_descriptor (stmtblock_t &, tree, tree, bool); void gfc_set_gfc_from_cfi (stmtblock_t *, stmtblock_t *, tree, tree, tree, gfc_symbol *, bool, bool, bool); @@ -102,4 +100,6 @@ 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 *); + #endif /* GFC_TRANS_DESCRIPTOR_H */ diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index f7bb11dbf52f..7741d5ef0246 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -1311,18 +1311,7 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts, && e->rank != class_ts.u.derived->components->as->rank) { if (e->rank == 0) - { - tree type = gfc_get_scalar_to_descriptor_type (TREE_TYPE (parmse->expr), -gfc_expr_attr (e)); - gfc_conv_descriptor_dtype_set (&block, ctree, -gfc_get_dtype (type)); - - tmp = gfc_class_data_get (parmse->expr); - if (!POINTER_TYPE_P (TREE_TYPE (tmp))) - tmp = gfc_build_addr_expr (NULL_TREE, tmp); - - gfc_conv_descriptor_data_set (&block, ctree, tmp); - } + gfc_set_descriptor_from_scalar_class (&block, ctree, parmse->expr, e); else gfc_class_array_data_assign (&block, ctree, parmse->expr, false); }
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Introduction gfc_symbol_attr
https://gcc.gnu.org/g:5009dd11e2f8cd0e8b8517ff0c23c3191355facd commit 5009dd11e2f8cd0e8b8517ff0c23c3191355facd Author: Mikael Morin Date: Thu Jul 17 16:38:25 2025 +0200 Introduction gfc_symbol_attr Ajout déclaration gfc_symbol_attr Diff: --- gcc/fortran/gfortran.h | 1 + gcc/fortran/primary.cc | 86 -- 2 files changed, 56 insertions(+), 31 deletions(-) diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 482031d26005..cfba71618182 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -4134,6 +4134,7 @@ const char *gfc_dt_lower_string (const char *); const char *gfc_dt_upper_string (const char *); /* primary.cc */ +symbol_attribute gfc_symbol_attr (gfc_symbol *); symbol_attribute gfc_variable_attr (gfc_expr *, gfc_typespec *); symbol_attribute gfc_expr_attr (gfc_expr *); symbol_attribute gfc_caf_attr (gfc_expr *, bool i = false, bool *r = NULL); diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc index 6df95558bb15..e9db6b8c392f 100644 --- a/gcc/fortran/primary.cc +++ b/gcc/fortran/primary.cc @@ -2909,43 +2909,14 @@ check_substring: } -/* Given an expression that is a variable, figure out what the - ultimate variable's type and attribute is, traversing the reference - structures if necessary. - - This subroutine is trickier than it looks. We start at the base - symbol and store the attribute. Component references load a - completely new attribute. - - A couple of rules come into play. Subobjects of targets are always - targets themselves. If we see a component that goes through a - pointer, then the expression must also be a target, since the - pointer is associated with something (if it isn't core will soon be - dumped). If we see a full part or section of an array, the - expression is also an array. - - We can have at most one full array reference. */ - symbol_attribute -gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts) +gfc_symbol_attr (gfc_symbol *sym) { - int dimension, codimension, pointer, allocatable, target, optional; + int dimension, codimension, pointer, allocatable, target; symbol_attribute attr; - gfc_ref *ref; - gfc_symbol *sym; - gfc_component *comp; - bool has_inquiry_part; - bool has_substring_ref = false; - - if (expr->expr_type != EXPR_VARIABLE - && expr->expr_type != EXPR_FUNCTION - && !(expr->expr_type == EXPR_NULL && expr->ts.type != BT_UNKNOWN)) -gfc_internal_error ("gfc_variable_attr(): Expression isn't a variable"); - sym = expr->symtree->n.sym; attr = sym->attr; - optional = attr.optional; if (sym->ts.type == BT_CLASS && sym->attr.class_ok && sym->ts.u.derived) { dimension = CLASS_DATA (sym)->attr.dimension; @@ -2981,6 +2952,59 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts) target = 0; } + attr.dimension = dimension; + attr.codimension = codimension; + attr.pointer = pointer; + attr.allocatable = allocatable; + attr.target = target; + + return attr; +} + + +/* Given an expression that is a variable, figure out what the + ultimate variable's type and attribute is, traversing the reference + structures if necessary. + + This subroutine is trickier than it looks. We start at the base + symbol and store the attribute. Component references load a + completely new attribute. + + A couple of rules come into play. Subobjects of targets are always + targets themselves. If we see a component that goes through a + pointer, then the expression must also be a target, since the + pointer is associated with something (if it isn't core will soon be + dumped). If we see a full part or section of an array, the + expression is also an array. + + We can have at most one full array reference. */ + +symbol_attribute +gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts) +{ + int dimension, codimension, pointer, allocatable, target, optional; + symbol_attribute attr; + gfc_ref *ref; + gfc_symbol *sym; + gfc_component *comp; + bool has_inquiry_part; + bool has_substring_ref = false; + + if (expr->expr_type != EXPR_VARIABLE + && expr->expr_type != EXPR_FUNCTION + && !(expr->expr_type == EXPR_NULL && expr->ts.type != BT_UNKNOWN)) +gfc_internal_error ("gfc_variable_attr(): Expression isn't a variable"); + + sym = expr->symtree->n.sym; + attr = gfc_symbol_attr (sym); + + optional = attr.optional; + dimension = attr.dimension; + codimension = attr.codimension; + pointer = attr.pointer; + allocatable = attr.allocatable; + target = attr.target; + if (ts != NULL && expr->ts.type == BT_UNKNOWN) *ts = sym->ts;
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: propagation valeurs indéfinies
https://gcc.gnu.org/g:de5836501f705cdf5312439e70820d1344f65b3c commit de5836501f705cdf5312439e70820d1344f65b3c Author: Mikael Morin Date: Fri Aug 29 11:31:42 2025 +0200 gimple-simulate: propagation valeurs indéfinies Ajout test gimple-simulate: Propagation des valeurs indéfinies Revert partiel Diff: --- gcc/gimple-simulate.cc | 34 ++ 1 file changed, 34 insertions(+) diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc index 9187efce399c..aeda491db332 100644 --- a/gcc/gimple-simulate.cc +++ b/gcc/gimple-simulate.cc @@ -2167,6 +2167,15 @@ simul_scope::evaluate_binary (enum tree_code code, tree type, tree lhs, else gcc_unreachable (); } + else if ((lhs_type == VAL_UNDEFINED || rhs_type == VAL_UNDEFINED) + && (lhs_type != VAL_ADDRESS + && rhs_type != VAL_ADDRESS + && lhs_type != VAL_MIXED + && rhs_type != VAL_MIXED)) +{ + data_value result (type); + return result; +} else gcc_unreachable (); } @@ -5797,6 +5806,31 @@ simul_scope_evaluate_binary_tests () wide_int wi_rshift6 = rshift_6.get_known (); ASSERT_PRED1 (wi::fits_shwi_p, wi_rshift6); ASSERT_EQ (wi_rshift6.to_shwi (), 5); + + + tree i1_7 = create_var (integer_type_node, "i1"); + tree i2_7 = create_var (integer_type_node, "i2"); + + vec decls7{}; + decls7.safe_push (i1_7); + decls7.safe_push (i2_7); + + context_builder builder7 {}; + builder7.add_decls (&decls7); + simul_scope ctx7 = builder7.build (mem, printer); + + data_value undef7_1 = ctx7.evaluate_binary (PLUS_EXPR, + integer_type_node, + i1_7, i2_7); + + ASSERT_EQ (undef7_1.classify (), VAL_UNDEFINED); + + tree cst_i1 = build_one_cst (integer_type_node); + data_value undef7_2 = ctx7.evaluate_binary (PLUS_EXPR, + integer_type_node, + i1_7, cst_i1); + + ASSERT_EQ (undef7_2.classify (), VAL_UNDEFINED); }
[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)] gimple-simulate: Réécriture de MEM_REF à l'interieur ce COMPONENT_EXPR
https://gcc.gnu.org/g:d0c9da400284edb0a2196bcee9b59818b6148123 commit d0c9da400284edb0a2196bcee9b59818b6148123 Author: Mikael Morin Date: Sat Aug 30 19:00:46 2025 +0200 gimple-simulate: Réécriture de MEM_REF à l'interieur ce COMPONENT_EXPR Diff: --- gcc/gimple-simulate.cc | 252 + 1 file changed, 169 insertions(+), 83 deletions(-) diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc index 3bdfd2bf6f7d..85c37ed468d9 100644 --- a/gcc/gimple-simulate.cc +++ b/gcc/gimple-simulate.cc @@ -797,36 +797,40 @@ context_printer::print_bb_entry (basic_block bb) } -/* Find the smallest subreference of VAR_REF starting at at least OFFSET +/* Find the smallest subreference of VAR_REF starting at at least MIN_OFFSET bit and of minimal size min_size. If no subreference was found at - OFFSET exactly but a reference was found at a further offset, store the + MIN_OFFSET exactly but a reference was found at a further offset, store the difference of offset in IGNORED_BITS. Return NULL_TREE if the smallest - reference is smaller than MIN_SIZE. Otherwise return the reference found. -*/ + reference is smaller than MIN_SIZE. Otherwise return the reference + found. */ + static tree -pick_subref_at (tree var_ref, unsigned offset, int * ignored_bits, - unsigned min_size) +pick_subref_at (tree var_ref, unsigned min_offset, + int * ignored_bits, unsigned min_size) { if (ignored_bits != nullptr) *ignored_bits = 0; tree ref = var_ref; - unsigned remaining_offset = offset; + unsigned remaining_offset = min_offset; while (true) { tree var_type = TREE_TYPE (ref); + unsigned type_size = get_constant_type_size (var_type); + if (type_size == min_size) + break; + if (TREE_CODE (var_type) == ARRAY_TYPE) { tree elt_type = TREE_TYPE (var_type); unsigned elt_width = get_constant_type_size (elt_type); if (elt_width < min_size) return NULL_TREE; + unsigned HOST_WIDE_INT hw_idx = remaining_offset / elt_width; tree t_idx = build_int_cst (integer_type_node, hw_idx); ref = build4 (ARRAY_REF, elt_type, ref, t_idx, NULL_TREE, NULL_TREE); remaining_offset -= hw_idx * elt_width; - if (elt_width == min_size) - break; } else if (TREE_CODE (var_type) == RECORD_TYPE) { @@ -865,8 +869,7 @@ pick_subref_at (tree var_ref, unsigned offset, int * ignored_bits, tree field_type = TREE_TYPE (field); unsigned field_width = get_constant_type_size (field_type); - if (field_width < min_size) - return NULL_TREE; + gcc_assert (field_width >= min_size); ref = build3 (COMPONENT_REF, field_type, ref, field, NULL_TREE); @@ -878,9 +881,6 @@ pick_subref_at (tree var_ref, unsigned offset, int * ignored_bits, } else remaining_offset -= field_position; - - if (field_width == min_size) - break; } else break; @@ -934,11 +934,9 @@ find_mem_ref_replacement (tree * repl, unsigned * offset, simul_scope & context, tree access_offset = TREE_OPERAND (data_ref, 1); gcc_assert (TREE_CONSTANT (access_offset)); wide_int wi_offset = wi::to_wide (access_offset); - wide_int remaining_offset = wi_offset * CHAR_BIT - + *offset + ptr_address->offset; - - gcc_assert (wi::ges_p (remaining_offset, 0) - && wi::fits_shwi_p (remaining_offset)); + int align = TYPE_ALIGN (access_type); + wide_int total_offset = wi_offset * CHAR_BIT + + *offset + ptr_address->offset; if (TREE_CODE (data_ref) == TARGET_MEM_REF) { tree idx = TREE_OPERAND (data_ref, 2); @@ -952,40 +950,101 @@ find_mem_ref_replacement (tree * repl, unsigned * offset, simul_scope & context, wide_int wi_step = step_val.get_known (); wi_idx *= wi_step; - remaining_offset += wi_idx * CHAR_BIT; + total_offset += wi_idx * CHAR_BIT; } - int ignored_bits; - tree t = pick_subref_at (var_ref, remaining_offset.to_shwi (), - &ignored_bits, + wide_int ref_offset = total_offset + & wi::mask (exact_log2 (align), true, + total_offset.get_precision ()); + gcc_assert (wi::ges_p (ref_offset, 0) + && wi::fits_uhwi_p (ref_offset)); + + tree t = pick_subref_at (var_ref, ref_offset.to_uhwi (), nullptr, get_constant_type_size (access_type)); if (t == NULL_TREE) { *repl = var_ref; - *offset = remaining_offset.to_shwi (); + gcc_assert (wi::ges_p (total_offset, 0) + && wi::fits_shwi_p
[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 r15-10331] ada: Fix internal error on aspect in complex object declaration
https://gcc.gnu.org/g:a04c1e9d55386632ec57fccbdc2e75122f310225 commit r15-10331-ga04c1e9d55386632ec57fccbdc2e75122f310225 Author: Eric Botcazou Date: Fri Aug 22 14:51:58 2025 +0200 ada: Fix internal error on aspect in complex object declaration The sufficient conditions are that the aspect be deferred and the object be rewritten as a renaming because of the complex initialization expression. gcc/ada/ChangeLog: * gcc-interface/trans.cc (gnat_to_gnu) : Deal with objects whose elaboration is deferred. (process_freeze_entity): Deal with renamed objects whose elaboration is deferred. Diff: --- gcc/ada/gcc-interface/trans.cc | 30 -- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc index e815eb52e340..d1df9ac938df 100644 --- a/gcc/ada/gcc-interface/trans.cc +++ b/gcc/ada/gcc-interface/trans.cc @@ -6855,9 +6855,22 @@ gnat_to_gnu (Node_Id gnat_node) && (Is_Array_Type (Etype (gnat_temp)) || Is_Record_Type (Etype (gnat_temp)) || Is_Concurrent_Type (Etype (gnat_temp) - gnat_to_gnu_entity (gnat_temp, - gnat_to_gnu (Renamed_Object (gnat_temp)), - true); + { + gnu_expr = gnat_to_gnu (Renamed_Object (gnat_temp)); + + /* The elaboration of object renamings present in the source code +never needs to be deferred. But regular objects may be turned +into renamings during expansion and their elaboration may need +to be deferred, in which case we expect the renamed references +to have been stabilized, so we do not do it again here. */ + if (Present (Freeze_Node (gnat_temp))) + { + gcc_assert (!Comes_From_Source (gnat_node)); + save_gnu_tree (gnat_node, gnu_expr, true); + } + else + gnat_to_gnu_entity (gnat_temp, gnu_expr, true); + } break; case N_Exception_Renaming_Declaration: @@ -9775,10 +9788,15 @@ process_freeze_entity (Node_Id gnat_node) } else { + /* For an object whose elaboration is deferred, the GCC tree of the +declaration, if any, is the initialization expression. */ + const Node_Id gnat_decl = Declaration_Node (gnat_entity); tree gnu_init - = (Nkind (Declaration_Node (gnat_entity)) == N_Object_Declaration - && present_gnu_tree (Declaration_Node (gnat_entity))) - ? get_gnu_tree (Declaration_Node (gnat_entity)) : NULL_TREE; + = (Nkind (gnat_decl) == N_Object_Declaration + || Nkind (gnat_decl) == N_Object_Renaming_Declaration) + && Present (Freeze_Node (gnat_entity)) + && present_gnu_tree (gnat_decl) + ? get_gnu_tree (gnat_decl) : NULL_TREE; gnu_new = gnat_to_gnu_entity (gnat_entity, gnu_init, true); }
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: Correction ICE évaluation adresse
https://gcc.gnu.org/g:bef04edec0a6debb12aff1c9d0e0492ee24f7408 commit bef04edec0a6debb12aff1c9d0e0492ee24f7408 Author: Mikael Morin Date: Fri Aug 29 20:05:33 2025 +0200 gimple-simulate: Correction ICE évaluation adresse Diff: --- gcc/gimple-simulate.cc | 60 ++ 1 file changed, 60 insertions(+) diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc index e0cf25eb97aa..9333c64aa77d 100644 --- a/gcc/gimple-simulate.cc +++ b/gcc/gimple-simulate.cc @@ -1850,6 +1850,9 @@ simul_scope::get_storage (unsigned idx) const } +const simul_scope * current_scope; + + tree simul_valueize (tree t) { @@ -1861,9 +1864,21 @@ simul_valueize (tree t) && gimple_assign_rhs_code (def) == ADDR_EXPR) return gimple_assign_rhs1 (def); + data_value val = current_scope->evaluate (t); + switch (val.classify ()) + { + case VAL_KNOWN: + return val.to_tree (TREE_TYPE (t)); + + default: + gcc_unreachable (); + } + +#if 0 tree c = gimple_fold_stmt_to_constant (def, simul_valueize); if (c != NULL_TREE) return c; +#endif } return t; @@ -1937,9 +1952,13 @@ simul_scope::evaluate (tree expr) const else { poly_int64 offset; + + const simul_scope * sauv = current_scope; + current_scope = this; tree var = get_addr_base_and_unit_offset_1 (TREE_OPERAND (expr, 0), &offset, simul_valueize); + current_scope = sauv; HOST_WIDE_INT off; bool is_constant = offset.is_constant (&off); @@ -4327,6 +4346,47 @@ context_printer_print_first_data_ref_part_tests () const char * str13 = pp_formatted_text (&pp13); ASSERT_STREQ (str13, "# var1s1l[0].der1s1l_l2"); ASSERT_EQ (ignored_bits, HOST_BITS_PER_LONG - HOST_BITS_PER_SHORT); + + + heap_memory mem14; + context_printer printer14; + pretty_printer & pp14 = printer14.pp; + + tree a2d2i = build_array_type_nelts (der2i, 2); + tree a14 = create_var (a2d2i, "a14"); + tree p_14 = create_var (ptr_type_node, "p"); + + vec decls14{}; + decls14.safe_push (a14); + decls14.safe_push (p_14); + + context_builder builder14 {}; + builder14.add_decls (&decls14); + simul_scope ctx14 = builder14.build (mem14, printer14); + + data_storage *strg_a14 = ctx14.find_reachable_var (a14); + gcc_assert (strg_a14 != nullptr); + + storage_address addr_a14 (strg_a14->get_ref (), 0); + data_value val_p14 (ptr_type_node); + val_p14.set_address (addr_a14); + + data_storage *strg_p14 = ctx14.find_reachable_var (p_14); + gcc_assert (strg_p14 != nullptr); + strg_p14->set (val_p14); + + tree zero_off = build_zero_cst (build_pointer_type (void_type_node)); + tree ref_a14 = build2 (MEM_REF, der2i, p_14, zero_off); + tree ref14 = build3 (COMPONENT_REF, integer_type_node, ref_a14, + der2i_i2, NULL_TREE); + + tree res14 = printer14.print_first_data_ref_part (ctx14, ref14, 0, + nullptr, + VAL_UNDEFINED); + + ASSERT_EQ (res14, integer_type_node); + const char * str14 = pp_formatted_text (&pp14); + ASSERT_STREQ (str14, "# a14[0].der2i_i2"); }
[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(refs/users/mikael/heads/refactor_descriptor_v08)] Factorisation set_dimension_fields gfc_set_descriptor_with_shape
https://gcc.gnu.org/g:6ce639860b0db5eed334e179fac445d852268e56 commit 6ce639860b0db5eed334e179fac445d852268e56 Author: Mikael Morin Date: Sat Aug 16 18:19:27 2025 +0200 Factorisation set_dimension_fields gfc_set_descriptor_with_shape Correction régression c_f_pointer_tests_4 Diff: --- gcc/fortran/trans-descriptor.cc | 18 -- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index ce7495ab1f34..6ada111b9e6e 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -1995,15 +1995,12 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, tree ptr, gfc_conv_expr (&lowerse, lower); gfc_add_block_to_block (&body, &lowerse.pre); lbound = fold_convert (gfc_array_index_type, lowerse.expr); + lbound = gfc_evaluate_now (lbound, &body); 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 shapeval = fold_convert (gfc_array_index_type, shapese.expr); @@ -2012,29 +2009,22 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, tree ptr, lbound, gfc_index_one_node); tree ubound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, tmp, shapeval); - gfc_conv_descriptor_ubound_set (&body, desc, dim, ubound); + ubound = gfc_evaluate_now (ubound, &body); 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)); + set_dimension_fields (&body, desc, dim, lbound, ubound, stride, offset); /* Update stride. */ gfc_add_modify (&body, stride, fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, stride, shapeval)); + /* 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); }
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Refactor get_descr_dim_comp
https://gcc.gnu.org/g:8fda392ae9a8d7f9fb730ec6bf6f4de6511267bb commit 8fda392ae9a8d7f9fb730ec6bf6f4de6511267bb Author: Mikael Morin Date: Wed Aug 6 14:41:41 2025 +0200 Refactor get_descr_dim_comp Diff: --- gcc/fortran/trans-descriptor.cc | 17 ++--- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index e7853880a232..5ebd3a10a868 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -512,18 +512,17 @@ gfc_conv_descriptor_token_set (stmtblock_t *block, tree desc, tree value) static tree -gfc_conv_descriptor_subfield (tree desc, tree dim, unsigned field_idx) +get_descr_dim_comp (tree desc, tree dim, unsigned field_idx, + tree type = NULL_TREE) { tree tmp = get_descriptor_dimension (desc, dim); - return get_ref_comp (tmp, field_idx); + return get_ref_comp (tmp, field_idx, type); } static tree get_descriptor_stride (tree desc, tree dim) { - tree field = gfc_conv_descriptor_subfield (desc, dim, STRIDE_SUBFIELD); - gcc_assert (TREE_TYPE (field) == gfc_array_index_type); - return field; + return get_descr_dim_comp (desc, dim, STRIDE_SUBFIELD, gfc_array_index_type); } tree @@ -554,9 +553,7 @@ gfc_conv_descriptor_stride_set (stmtblock_t *block, tree desc, static tree get_descriptor_lbound (tree desc, tree dim) { - tree field = gfc_conv_descriptor_subfield (desc, dim, LBOUND_SUBFIELD); - gcc_assert (TREE_TYPE (field) == gfc_array_index_type); - return field; + return get_descr_dim_comp (desc, dim, LBOUND_SUBFIELD, gfc_array_index_type); } tree @@ -576,9 +573,7 @@ gfc_conv_descriptor_lbound_set (stmtblock_t *block, tree desc, static tree get_descriptor_ubound (tree desc, tree dim) { - tree field = gfc_conv_descriptor_subfield (desc, dim, UBOUND_SUBFIELD); - gcc_assert (TREE_TYPE (field) == gfc_array_index_type); - return field; + return get_descr_dim_comp (desc, dim, UBOUND_SUBFIELD, gfc_array_index_type); } tree
[gcc r16-3887] forwprop: Handle memcpy for copy prop [PR121418, PR121417]
https://gcc.gnu.org/g:597b50abb0d2fc1f123a99e1b4beb89ad6259d9e commit r16-3887-g597b50abb0d2fc1f123a99e1b4beb89ad6259d9e Author: Andrew Pinski Date: Sat Sep 6 21:49:18 2025 -0700 forwprop: Handle memcpy for copy prop [PR121418, PR121417] It turns out easy to add support for memcpy copy prop when the memcpy has changed into `MEM` copy. Instead of rejecting right out we need to figure out that `a` and `MEM[&a]` are equivalent in terms of address and size. And then create a VIEW_CONVER_EXPR from the original src to the new type. Note this also allows for `a.b` and `a` being considered equivalent if b is the only field (PR 121751). Changes since v1: * v2: Move check for IMAG/REAL and BFR earlier. Add a wrapping function around get_inner_reference and use that instead of get_addr_base_and_unit_offset. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/121751 PR tree-optimization/121418 PR tree-optimization/121417 gcc/ChangeLog: * tree-ssa-forwprop.cc (split_core_and_offset_size): New function. (optimize_agr_copyprop_1): Allow for the same address but different type accesses via a VCE. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/copy-prop-aggregate-1.c: New test. * gcc.dg/tree-ssa/copy-prop-aggregate-memcpy-1.c: New test. * gcc.dg/tree-ssa/copy-prop-aggregate-memcpy-2.c: New test. Signed-off-by: Andrew Pinski Diff: --- .../gcc.dg/tree-ssa/copy-prop-aggregate-1.c| 33 +++ .../gcc.dg/tree-ssa/copy-prop-aggregate-memcpy-1.c | 18 .../gcc.dg/tree-ssa/copy-prop-aggregate-memcpy-2.c | 20 + gcc/tree-ssa-forwprop.cc | 100 - 4 files changed, 170 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-1.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-1.c new file mode 100644 index ..1094c4d768bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-1.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-forwprop1-details -fdump-tree-optimized" } */ +/* PR tree-optimization/121751 */ + + +struct s1 +{ + int t[1024]; +}; + +struct s2 { + struct s1 t; +}; + +struct s3 +{ + struct s2 t; +}; + +void g(struct s3*); + +void f(struct s1 s) +{ + struct s2 removeme; + removeme.t = s; + struct s3 t1; + t1.t = removeme; + g(&t1); +} + + +/* { dg-final { scan-tree-dump-times "after previous" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-not "removeme " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-memcpy-1.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-memcpy-1.c new file mode 100644 index ..5faf6d0bf9bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-memcpy-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-forwprop1-details -fdump-tree-optimized" } */ +/* PR tree-optimization/121418 */ + +struct s1 +{ + unsigned char t[1024]; +}; + +struct s1 f(struct s1 a) +{ + struct s1 removeme1 = a; + __builtin_memcpy (&removeme1, &a, sizeof(struct s1)); + return removeme1; +} + +/* { dg-final { scan-tree-dump-times "after previous" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-not "removeme1 " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-memcpy-2.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-memcpy-2.c new file mode 100644 index ..b1ba30d0aba0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-memcpy-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-forwprop1-details -fdump-tree-optimized" } */ +/* PR tree-optimization/121417 */ + +struct s1 +{ + unsigned char t[1024]; +}; + +struct s1 f(struct s1 a) +{ + struct s1 removeme1 = a; + struct s1 removeme2; + __builtin_memcpy (&removeme2, &removeme1, sizeof(struct s1)); + return removeme2; +} + +/* { dg-final { scan-tree-dump-times "after previous" 2 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-not "removeme1 " "optimized" } } */ +/* { dg-final { scan-tree-dump-not "removeme2 " "optimized" } } */ diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index 9c6f4b355d6d..1eacff01587c 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -1418,6 +1418,46 @@ optimize_aggr_zeroprop (gimple_stmt_iterator *gsip, bool full_walk) return changed; } +/* Returns the pointer to the base of the object of the + reference EXPR and extracts the information about + the offset of the access, storing it to PBYTESIZE, + PBYTEPOS and PREVERSEP. + If the access is not a byte sized or position is not + on the byte, return NULL. */ +static tree +split_core_and_offset_size (tree expr, + poly_int
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: propagation valeurs indéfinies
https://gcc.gnu.org/g:de5836501f705cdf5312439e70820d1344f65b3c commit de5836501f705cdf5312439e70820d1344f65b3c Author: Mikael Morin Date: Fri Aug 29 11:31:42 2025 +0200 gimple-simulate: propagation valeurs indéfinies Ajout test gimple-simulate: Propagation des valeurs indéfinies Revert partiel Diff: --- gcc/gimple-simulate.cc | 34 ++ 1 file changed, 34 insertions(+) diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc index 9187efce399c..aeda491db332 100644 --- a/gcc/gimple-simulate.cc +++ b/gcc/gimple-simulate.cc @@ -2167,6 +2167,15 @@ simul_scope::evaluate_binary (enum tree_code code, tree type, tree lhs, else gcc_unreachable (); } + else if ((lhs_type == VAL_UNDEFINED || rhs_type == VAL_UNDEFINED) + && (lhs_type != VAL_ADDRESS + && rhs_type != VAL_ADDRESS + && lhs_type != VAL_MIXED + && rhs_type != VAL_MIXED)) +{ + data_value result (type); + return result; +} else gcc_unreachable (); } @@ -5797,6 +5806,31 @@ simul_scope_evaluate_binary_tests () wide_int wi_rshift6 = rshift_6.get_known (); ASSERT_PRED1 (wi::fits_shwi_p, wi_rshift6); ASSERT_EQ (wi_rshift6.to_shwi (), 5); + + + tree i1_7 = create_var (integer_type_node, "i1"); + tree i2_7 = create_var (integer_type_node, "i2"); + + vec decls7{}; + decls7.safe_push (i1_7); + decls7.safe_push (i2_7); + + context_builder builder7 {}; + builder7.add_decls (&decls7); + simul_scope ctx7 = builder7.build (mem, printer); + + data_value undef7_1 = ctx7.evaluate_binary (PLUS_EXPR, + integer_type_node, + i1_7, i2_7); + + ASSERT_EQ (undef7_1.classify (), VAL_UNDEFINED); + + tree cst_i1 = build_one_cst (integer_type_node); + data_value undef7_2 = ctx7.evaluate_binary (PLUS_EXPR, + integer_type_node, + i1_7, cst_i1); + + ASSERT_EQ (undef7_2.classify (), VAL_UNDEFINED); }
[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/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)] Refactoring getters & setters
https://gcc.gnu.org/g:d56ee42aa6bb00e66355a127e6b9f121d4d3c1c5 commit d56ee42aa6bb00e66355a127e6b9f121d4d3c1c5 Author: Mikael Morin Date: Tue Jul 1 22:10:35 2025 +0200 Refactoring getters & setters Nettoyage refactoring Correction refactoring Diff: --- gcc/fortran/trans-descriptor.cc | 18 -- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 5ebd3a10a868..c1b4f3b5e019 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -184,7 +184,6 @@ get_type_field (tree type, unsigned field_idx, tree field_type = NULL_TREE) return field; } - static tree get_ref_comp (tree ref, unsigned field_idx, tree type = NULL_TREE) { @@ -195,8 +194,7 @@ get_ref_comp (tree ref, unsigned field_idx, tree type = NULL_TREE) static tree -gfc_get_descriptor_field (tree desc, unsigned field_idx, - tree type = NULL_TREE) +get_descr_comp (tree desc, unsigned field_idx, tree type = NULL_TREE) { gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))); @@ -207,7 +205,7 @@ gfc_get_descriptor_field (tree desc, unsigned field_idx, static tree get_descriptor_data (tree desc) { - return gfc_get_descriptor_field (desc, DATA_FIELD); + return get_descr_comp (desc, DATA_FIELD); } /* This provides READ-ONLY access to the data field. The field itself @@ -236,7 +234,7 @@ gfc_conv_descriptor_data_get (tree desc) void gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value) { - tree field = gfc_get_descriptor_field (desc, DATA_FIELD); + tree field = get_descriptor_data (desc); gfc_add_modify (block, field, fold_convert (TREE_TYPE (field), value)); } @@ -244,7 +242,7 @@ gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value) static tree get_descriptor_offset (tree desc) { - return gfc_get_descriptor_field (desc, OFFSET_FIELD, gfc_array_index_type); + return get_descr_comp (desc, OFFSET_FIELD, gfc_array_index_type); } tree @@ -264,7 +262,7 @@ gfc_conv_descriptor_offset_set (stmtblock_t *block, tree desc, tree value) static tree get_descriptor_dtype (tree desc) { - return gfc_get_descriptor_field (desc, DTYPE_FIELD, get_dtype_type_node ()); + return get_descr_comp (desc, DTYPE_FIELD, get_dtype_type_node ()); } tree @@ -286,7 +284,7 @@ gfc_conv_descriptor_dtype_set (stmtblock_t *block, tree desc, tree value) static tree gfc_conv_descriptor_span (tree desc) { - return gfc_get_descriptor_field (desc, SPAN_FIELD, gfc_array_index_type); + return get_descr_comp (desc, SPAN_FIELD, gfc_array_index_type); } tree @@ -443,7 +441,7 @@ gfc_conv_descriptor_type_set (tree desc, int value) tree gfc_get_descriptor_dimension (tree desc) { - tree field = gfc_get_descriptor_field (desc, DIMENSION_FIELD); + tree field = get_descr_comp (desc, DIMENSION_FIELD); gcc_assert (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE); return field; @@ -494,7 +492,7 @@ tree gfc_conv_descriptor_token (tree desc) { gcc_assert (flag_coarray == GFC_FCOARRAY_LIB); - tree field = gfc_get_descriptor_field (desc, CAF_TOKEN_FIELD); + tree field = get_descr_comp (desc, CAF_TOKEN_FIELD); /* Should be a restricted pointer - except in the finalization wrapper. */ gcc_assert (TREE_TYPE (field) == prvoid_type_node || TREE_TYPE (field) == pvoid_type_node);
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Déplacement shift descriptor vers gfc_conv_array_parameter
https://gcc.gnu.org/g:877f897ec3921f1a326ca8ad21a44a962c917239 commit 877f897ec3921f1a326ca8ad21a44a962c917239 Author: Mikael Morin Date: Tue Dec 17 17:27:24 2024 +0100 Déplacement shift descriptor vers gfc_conv_array_parameter Suppression variables inutilisées Diff: --- gcc/fortran/trans-array.cc | 61 - gcc/fortran/trans-array.h | 2 +- gcc/fortran/trans-descriptor.cc | 47 +++ gcc/fortran/trans-descriptor.h | 3 ++ gcc/fortran/trans-expr.cc | 20 +- 5 files changed, 76 insertions(+), 57 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 7e71e67a61ae..7b8f712a2f7b 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -107,40 +107,31 @@ gfc_array_dataptr_type (tree desc) return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc))); } -/* Modify a descriptor such that the lbound of a given dimension is the value - specified. This also updates ubound and offset accordingly. */ -void -gfc_conv_shift_descriptor_lbound (stmtblock_t* block, tree desc, - int dim, tree new_lbound) +static bool +keep_descriptor_lower_bound (gfc_expr *e) { - tree offs, ubound, lbound, stride; - tree diff, offs_diff; - - new_lbound = fold_convert (gfc_array_index_type, new_lbound); - - offs = gfc_conv_descriptor_offset_get (desc); - lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]); - ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]); - stride = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[dim]); + gfc_ref *ref; - /* Get difference (new - old) by which to shift stuff. */ - diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - new_lbound, lbound); + /* Detect any array references with vector subscripts. */ + for (ref = e->ref; ref; ref = ref->next) +if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT + && ref->u.ar.type != AR_FULL) + { + int dim; + for (dim = 0; dim < ref->u.ar.dimen; dim++) + if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR) + break; + if (dim < ref->u.ar.dimen) + break; + } - /* Shift ubound and offset accordingly. This has to be done before - updating the lbound, as they depend on the lbound expression! */ - ubound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, - ubound, diff); - gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[dim], ubound); - offs_diff = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - diff, stride); - offs = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - offs, offs_diff); - gfc_conv_descriptor_offset_set (block, desc, offs); + /* Array references with vector subscripts and non-variable + expressions need be converted to a one-based descriptor. */ + if (ref || e->expr_type != EXPR_VARIABLE) +return false; - /* Finally set lbound to value we want. */ - gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[dim], new_lbound); + return true; } @@ -8597,7 +8588,7 @@ is_pointer (gfc_expr *e) void gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, bool g77, const gfc_symbol *fsym, const char *proc_name, - tree *size, tree *lbshift, tree *packed) + tree *size, bool maybe_shift, tree *packed) { tree ptr; tree desc; @@ -8834,13 +8825,9 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, bool g77, stmtblock_t block; gfc_init_block (&block); - if (lbshift && *lbshift) - { - /* Apply a shift of the lbound when supplied. */ - for (int dim = 0; dim < expr->rank; ++dim) - gfc_conv_shift_descriptor_lbound (&block, se->expr, dim, - *lbshift); - } + if (maybe_shift && !keep_descriptor_lower_bound (expr)) + gfc_conv_shift_descriptor (&block, se->expr, expr->rank); + tmp = gfc_class_data_get (ctree); if (expr->rank > 1 && CLASS_DATA (fsym)->as->rank != expr->rank && CLASS_DATA (fsym)->as->type == AS_EXPLICIT && !no_pack) diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h index c1886eb1faaf..f0ecc8c57877 100644 --- a/gcc/fortran/trans-array.h +++ b/gcc/fortran/trans-array.h @@ -153,7 +153,7 @@ tree gfc_get_array_span (tree, gfc_expr *); void gfc_conv_expr_descriptor (gfc_se *, gfc_expr *); /* Convert an array for passing as an actual function parameter. */ void gfc_conv_array_parameter (gfc_se *, gfc_expr *, bool, const gfc_symbol *, - const char *, tree *, tree * = nullptr, + const char *, tree *,
[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(refs/users/mikael/heads/refactor_descriptor_v08)] Reindentation retour à la ligne set_descriptor_with_shape
https://gcc.gnu.org/g:baad800a3d24158edf9f995b71d160553760297c commit baad800a3d24158edf9f995b71d160553760297c Author: Mikael Morin Date: Sun Aug 17 19:43:40 2025 +0200 Reindentation retour à la ligne set_descriptor_with_shape Diff: --- gcc/fortran/trans-descriptor.cc | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 60cb6f1b9798..d283c741767f 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -1755,11 +1755,12 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, tree ptr, 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); + tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, +lbound, gfc_index_one_node); + tree ubound = fold_build2_loc (input_location, PLUS_EXPR, +gfc_array_index_type, tmp, +fold_convert (gfc_array_index_type, + shapese.expr)); gfc_conv_descriptor_ubound_set (&body, desc, dim, ubound); gfc_add_block_to_block (&body, &shapese.post); @@ -1771,10 +1772,11 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, tree ptr, 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))); + 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);
[gcc r14-12020] s390: Emulate vec_cmp{eq, gt, gtu} for 128-bit integers
https://gcc.gnu.org/g:f5ac7f0fa0f742824c68a4607f08b4d7d0dca865 commit r14-12020-gf5ac7f0fa0f742824c68a4607f08b4d7d0dca865 Author: Stefan Schulze Frielinghaus Date: Tue Jul 16 10:41:41 2024 +0200 s390: Emulate vec_cmp{eq,gt,gtu} for 128-bit integers Mode iterator V_HW enables V1TI for target VXE which means vec_cmpv1tiv1ti becomes available which leads to an ICE since there is no corresponding insn. Fixed by emulating comparisons and enabling mode V1TI unconditionally for V_HW. For the sake of symmetry, I also added TI mode to V_HW since TF mode is already included. As a consequence the consumers of V_HW vec_{splat,slb,sld,sldw,sldb,srdb,srab,srb,test_mask_int,test_mask} also become available for 128-bit integers. This fixes gcc.c-torture/execute/pr105613.c and gcc.dg/pr106063.c. gcc/ChangeLog: * config/s390/vector.md (V_HW): Enable V1TI unconditionally and add TI. (vec_cmpu): Add 128-bit integer variants. (*vec_cmpeq_nocc_emu): Emulate operation. (*vec_cmpgt_nocc_emu): Emulate operation. (*vec_cmpgtu_nocc_emu): Emulate operation. gcc/testsuite/ChangeLog: * gcc.target/s390/vector/vec-cmp-emu-1.c: New test. * gcc.target/s390/vector/vec-cmp-emu-2.c: New test. * gcc.target/s390/vector/vec-cmp-emu-3.c: New test. (cherry picked from commit 1b575bb24a7a3d2b00197dd5deb4c26b313f442b) Diff: --- gcc/config/s390/vector.md | 113 ++--- .../gcc.target/s390/vector/vec-cmp-emu-1.c | 35 +++ .../gcc.target/s390/vector/vec-cmp-emu-2.c | 18 .../gcc.target/s390/vector/vec-cmp-emu-3.c | 17 4 files changed, 171 insertions(+), 12 deletions(-) diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md index a79f21b05c73..558513bc56af 100644 --- a/gcc/config/s390/vector.md +++ b/gcc/config/s390/vector.md @@ -30,7 +30,7 @@ ; V_HW2 is for having two iterators expanding independently e.g. vcond. ; It's similar to V_HW, but not fully identical: V1TI is not included, because ; there are no 128-bit compares. -(define_mode_iterator V_HW [V16QI V8HI V4SI V2DI (V1TI "TARGET_VXE") V2DF +(define_mode_iterator V_HW [V16QI V8HI V4SI V2DI V1TI TI V2DF (V4SF "TARGET_VXE") (V1TF "TARGET_VXE") (TF "TARGET_VXE")]) (define_mode_iterator V_HW2 [V16QI V8HI V4SI V2DI V2DF (V4SF "TARGET_VXE") @@ -50,6 +50,7 @@ (define_mode_iterator VI_HW_HSDT [V8HI V4SI V2DI V1TI TI]) (define_mode_iterator VI_HW_HS [V8HI V4SI]) (define_mode_iterator VI_HW_QH [V16QI V8HI]) +(define_mode_iterator VI_HW_T [V1TI TI]) ; Directly supported vector modes with a certain number of elements (define_mode_iterator V_HW_2 [V2DI V2DF]) @@ -149,7 +150,7 @@ (V1HI "V1HI") (V2HI "V2HI") (V4HI "V4HI") (V8HI "V8HI") (V1SI "V1SI") (V2SI "V2SI") (V4SI "V4SI") (V1DI "V1DI") (V2DI "V2DI") - (V1TI "V1TI") + (V1TI "V1TI") (TI "V1TI") (V1SF "V1SI") (V2SF "V2SI") (V4SF "V4SI") (V1DF "V1DI") (V2DF "V2DI") (V1TF "V1TI") (TF "V1TI")]) @@ -158,7 +159,7 @@ (V1HI "v1hi") (V2HI "v2hi") (V4HI "v4hi") (V8HI "v8hi") (V1SI "v1si") (V2SI "v2si") (V4SI "v4si") (V1DI "v1di") (V2DI "v2di") - (V1TI "v1ti") + (V1TI "v1ti") (TI "v1ti") (V1SF "v1si") (V2SF "v2si") (V4SF "v4si") (V1DF "v1di") (V2DF "v2di") (V1TF "v1ti") (TF "v1ti")]) @@ -1945,11 +1946,11 @@ DONE; }) -(define_expand "vec_cmpu" - [(set (match_operand:VI_HW0 "register_operand" "") - (match_operator:VI_HW 1 "" - [(match_operand:VI_HW 2 "register_operand" "") - (match_operand:VI_HW 3 "register_operand" "")]))] +(define_expand "vec_cmpu" + [(set (match_operand:VIT_HW0 "register_operand" "") + (match_operator:VIT_HW 1 "" + [(match_operand:VIT_HW 2 "register_operand" "") + (match_operand:VIT_HW 3 "register_operand" "")]))] "TARGET_VX" { s390_expand_vec_compare (operands[0], GET_CODE(operands[1]), operands[2], operands[3]); @@ -1964,6 +1965,94 @@ "vc\t%v2,%v0,%v1" [(set_attr "op_type" "VRR")]) +(define_insn_and_split "*vec_cmpeq_nocc_emu" + [(set (match_operand:VI_HW_T 0 "register_operand" "=v") + (eq:VI_HW_T (match_operand:VI_HW_T 1 "register_operand" "v") + (match_operand:VI_HW_T 2 "register_operand" "v")))] + "TARGET_VX" + "#" + "&& can_create_pseudo_p ()" + [(set (match_dup 3) + (eq:V2DI (match_dup 1) (match
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Déplacement fonctions descripteur vers fichier séparé
https://gcc.gnu.org/g:5450a7e6f901fa3e502de1f79d7d2c81d750b4f9 commit 5450a7e6f901fa3e502de1f79d7d2c81d750b4f9 Author: Mikael Morin Date: Wed Jun 18 17:31:23 2025 +0200 Déplacement fonctions descripteur vers fichier séparé Suppression déclarations trans-array.h Inclusion trans-descriptor.h Correction en-têtes Suppression declaration gfc_array_data_ptr_type Ajout commentaires Suppression gfc_conv_descriptor_data_addr Diff: --- gcc/fortran/Make-lang.in| 7 +- gcc/fortran/trans-array.cc | 499 + gcc/fortran/trans-array.h | 34 --- gcc/fortran/trans-decl.cc | 1 + gcc/fortran/trans-descriptor.cc | 535 gcc/fortran/trans-descriptor.h | 86 +++ gcc/fortran/trans-expr.cc | 1 + gcc/fortran/trans-intrinsic.cc | 1 + gcc/fortran/trans-io.cc | 1 + gcc/fortran/trans-openmp.cc | 1 + gcc/fortran/trans-stmt.cc | 1 + gcc/fortran/trans.cc| 1 + 12 files changed, 634 insertions(+), 534 deletions(-) diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in index 5b2f921bf2ef..2ddb0366e9dc 100644 --- a/gcc/fortran/Make-lang.in +++ b/gcc/fortran/Make-lang.in @@ -63,9 +63,10 @@ F95_PARSER_OBJS = fortran/arith.o fortran/array.o fortran/bbt.o \ F95_OBJS = $(F95_PARSER_OBJS) $(FORTRAN_TARGET_OBJS) \ fortran/convert.o fortran/dependency.o fortran/f95-lang.o \ fortran/trans.o fortran/trans-array.o fortran/trans-common.o \ -fortran/trans-const.o fortran/trans-decl.o fortran/trans-expr.o \ -fortran/trans-intrinsic.o fortran/trans-io.o fortran/trans-openmp.o \ -fortran/trans-stmt.o fortran/trans-types.o fortran/frontend-passes.o +fortran/trans-const.o fortran/trans-decl.o fortran/trans-descriptor.o \ +fortran/trans-expr.o fortran/trans-intrinsic.o fortran/trans-io.o \ +fortran/trans-openmp.o fortran/trans-stmt.o fortran/trans-types.o \ +fortran/frontend-passes.o fortran_OBJS = $(F95_OBJS) fortran/gfortranspec.o diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index dcf1cbecb54d..b99e12a506dd 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -92,6 +92,7 @@ along with GCC; see the file COPYING3. If not see #include "trans-array.h" #include "trans-const.h" #include "dependency.h" +#include "trans-descriptor.h" static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor_base); @@ -106,456 +107,6 @@ gfc_array_dataptr_type (tree desc) return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc))); } -/* Build expressions to access members of the CFI descriptor. */ -#define CFI_FIELD_BASE_ADDR 0 -#define CFI_FIELD_ELEM_LEN 1 -#define CFI_FIELD_VERSION 2 -#define CFI_FIELD_RANK 3 -#define CFI_FIELD_ATTRIBUTE 4 -#define CFI_FIELD_TYPE 5 -#define CFI_FIELD_DIM 6 - -#define CFI_DIM_FIELD_LOWER_BOUND 0 -#define CFI_DIM_FIELD_EXTENT 1 -#define CFI_DIM_FIELD_SM 2 - -static tree -gfc_get_cfi_descriptor_field (tree desc, unsigned field_idx) -{ - tree type = TREE_TYPE (desc); - gcc_assert (TREE_CODE (type) == RECORD_TYPE - && TYPE_FIELDS (type) - && (strcmp ("base_addr", -IDENTIFIER_POINTER (DECL_NAME (TYPE_FIELDS (type - == 0)); - tree field = gfc_advance_chain (TYPE_FIELDS (type), field_idx); - gcc_assert (field != NULL_TREE); - - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), - desc, field, NULL_TREE); -} - -tree -gfc_get_cfi_desc_base_addr (tree desc) -{ - return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_BASE_ADDR); -} - -tree -gfc_get_cfi_desc_elem_len (tree desc) -{ - return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_ELEM_LEN); -} - -tree -gfc_get_cfi_desc_version (tree desc) -{ - return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_VERSION); -} - -tree -gfc_get_cfi_desc_rank (tree desc) -{ - return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_RANK); -} - -tree -gfc_get_cfi_desc_type (tree desc) -{ - return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_TYPE); -} - -tree -gfc_get_cfi_desc_attribute (tree desc) -{ - return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_ATTRIBUTE); -} - -static tree -gfc_get_cfi_dim_item (tree desc, tree idx, unsigned field_idx) -{ - tree tmp = gfc_get_cfi_descriptor_field (desc, CFI_FIELD_DIM); - tmp = gfc_build_array_ref (tmp, idx, NULL_TREE, true); - tree field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), field_idx); - gcc_assert (field != NULL_TREE); - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), - tmp, field, NULL_TREE); -} - -tree -gfc_get_cfi_dim_lbound (tree desc, tree idx) -{ - return gfc_get_cfi_dim_item (desc, idx, CFI_DIM_FIELD_LOWER_BOUND); -} - -tree -gfc_get_cfi_dim_extent (tree desc, tree idx) -{ - return gfc_get_cfi_dim_item (desc, idx, CFI_DIM_FIELD_EXTENT)
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction gfc_conv_shift_descriptor
https://gcc.gnu.org/g:671cb2be3fb2e456fca107e8added349b6a46baf commit 671cb2be3fb2e456fca107e8added349b6a46baf Author: Mikael Morin Date: Wed Jul 16 21:39:51 2025 +0200 Extraction gfc_conv_shift_descriptor Suppression variable inutilisée Diff: --- gcc/fortran/trans-descriptor.cc | 39 +++ gcc/fortran/trans-descriptor.h | 1 + gcc/fortran/trans-expr.cc | 36 +--- 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 591887cb70e2..2e2345d9c35e 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -1119,3 +1119,42 @@ gfc_conv_shift_descriptor (stmtblock_t *block, tree desc, conv_shift_descriptor (block, desc, as); } + + +void +gfc_conv_shift_descriptor (stmtblock_t *block, tree dest, tree src, + int rank, tree zero_cond) +{ + tree tmp = gfc_conv_descriptor_data_get (src); + gfc_conv_descriptor_data_set (block, dest, tmp); + + tree offset = gfc_index_zero_node; + for (int n = 0 ; n < rank; n++) +{ + tree lbound = gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]); + lbound = fold_build3_loc (input_location, COND_EXPR, + gfc_array_index_type, zero_cond, + gfc_index_one_node, lbound); + lbound = gfc_evaluate_now (lbound, block); + + tmp = gfc_conv_descriptor_ubound_get (src, gfc_rank_cst[n]); + tmp = fold_build2_loc (input_location, PLUS_EXPR, +gfc_array_index_type, tmp, lbound); + gfc_conv_descriptor_lbound_set (block, dest, + gfc_rank_cst[n], lbound); + gfc_conv_descriptor_ubound_set (block, dest, + gfc_rank_cst[n], tmp); + + /* Set stride and accumulate the offset. */ + tmp = gfc_conv_descriptor_stride_get (src, gfc_rank_cst[n]); + gfc_conv_descriptor_stride_set (block, dest, + gfc_rank_cst[n], tmp); + tmp = fold_build2_loc (input_location, MULT_EXPR, +gfc_array_index_type, lbound, tmp); + offset = fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, offset, tmp); + offset = gfc_evaluate_now (offset, block); +} + + gfc_conv_descriptor_offset_set (block, dest, offset); +} diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index 1d9a640bccb5..5604126273c8 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -103,6 +103,7 @@ void gfc_init_descriptor_variable (stmtblock_t *block, gfc_symbol *sym, tree des void gfc_conv_shift_descriptor_lbound (stmtblock_t *, tree, int, tree); void gfc_conv_shift_descriptor (stmtblock_t *, tree, int); void gfc_conv_shift_descriptor (stmtblock_t *, tree, const gfc_array_ref &); +void gfc_conv_shift_descriptor (stmtblock_t *, tree, tree, int, tree); 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 969b6712ea7f..e463702a02a3 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -11755,7 +11755,6 @@ fcncall_realloc_result (gfc_se *se, int rank, tree dtype) tree desc; tree res_desc; tree tmp; - tree offset; tree zero_cond; tree not_same_shape; stmtblock_t shape_block; @@ -11788,9 +11787,6 @@ fcncall_realloc_result (gfc_se *se, int rank, tree dtype) tmp = gfc_call_free (tmp); gfc_add_expr_to_block (&se->post, tmp); - tmp = gfc_conv_descriptor_data_get (res_desc); - gfc_conv_descriptor_data_set (&se->post, desc, tmp); - /* Check that the shapes are the same between lhs and expression. The evaluation of the shape is done in 'shape_block' to avoid unitialized warnings from the lhs bounds. */ @@ -11834,37 +11830,7 @@ fcncall_realloc_result (gfc_se *se, int rank, tree dtype) /* Now reset the bounds returned from the function call to bounds based on the lhs lbounds, except where the lhs is not allocated or the shapes of 'variable and 'expr' are different. Set the offset accordingly. */ - offset = gfc_index_zero_node; - for (n = 0 ; n < rank; n++) -{ - tree lbound; - - lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]); - lbound = fold_build3_loc (input_location, COND_EXPR, - gfc_array_index_type, zero_cond, - gfc_index_one_node, lbound); - lbound = gfc_evaluate_now (lbound, &se->post); - - tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]); - tmp = fold_build2_loc (input_location, PLUS_EXPR, -gfc_array_index_type, tmp, lbound);
[gcc r16-3788] ada: Implement overflow checking for unsigned types
https://gcc.gnu.org/g:3a3854f3ea8ffcce624f064a137bacde03ab5efb commit r16-3788-g3a3854f3ea8ffcce624f064a137bacde03ab5efb Author: Eric Botcazou Date: Wed Jul 23 00:19:10 2025 +0200 ada: Implement overflow checking for unsigned types The implementation is essentially mirrored from the one for signed types. gcc/ada/ChangeLog: * gcc-interface/gigi.h (standard_datatypes): Add ADT_uns_mulv64_decl and ADT_uns_mulv128_decl. (uns_mulv64_decl): New macro. (uns_mulv128_decl): Likewise. * gcc-interface/trans.cc (gigi): Create the uns_mulv64_decl and uns_mulv128_decl declarations. (gnat_to_gnu) : Perform an overflow check for unsigned integer addition, subtraction and multiplication if required. : Perform an overflow check for unsigned integer negation if required. (build_unary_op_trapv): Add support for unsigned types. (build_binary_op_trapv): Likewise. : Perform the check if the LHS is zero in the signed case as well. Diff: --- gcc/ada/gcc-interface/gigi.h | 8 +++- gcc/ada/gcc-interface/trans.cc | 103 + 2 files changed, 79 insertions(+), 32 deletions(-) diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index 0345111fb85f..45b1bfd23e3a 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -388,11 +388,13 @@ enum standard_datatypes /* Function declaration node for run-time reallocation function. */ ADT_realloc_decl, - /* Function decl node for 64-bit multiplication with overflow checking. */ + /* Function decl nodes for 64-bit multiplication with overflow checking. */ ADT_mulv64_decl, + ADT_uns_mulv64_decl, - /* Function decl node for 128-bit multiplication with overflow checking. */ + /* Function decl nodes for 128-bit multiplication with overflow checking. */ ADT_mulv128_decl, + ADT_uns_mulv128_decl, /* Identifier for the name of the _Parent field in tagged record types. */ ADT_parent_name_id, @@ -455,7 +457,9 @@ extern GTY(()) tree gnat_raise_decls_ext[(int) LAST_REASON_CODE + 1]; #define free_decl gnat_std_decls[(int) ADT_free_decl] #define realloc_decl gnat_std_decls[(int) ADT_realloc_decl] #define mulv64_decl gnat_std_decls[(int) ADT_mulv64_decl] +#define uns_mulv64_decl gnat_std_decls[(int) ADT_uns_mulv64_decl] #define mulv128_decl gnat_std_decls[(int) ADT_mulv128_decl] +#define uns_mulv128_decl gnat_std_decls[(int) ADT_uns_mulv128_decl] #define parent_name_id gnat_std_decls[(int) ADT_parent_name_id] #define not_handled_by_others_name_id \ gnat_std_decls[(int) ADT_not_handled_by_others_name_id] diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc index fd1d39cd0f55..3c6e87e52c0a 100644 --- a/gcc/ada/gcc-interface/trans.cc +++ b/gcc/ada/gcc-interface/trans.cc @@ -319,7 +319,7 @@ gigi (Node_Id gnat_root, { Node_Id gnat_iter; Entity_Id gnat_literal; - tree t, ftype, int64_type; + tree t, ftype; struct elab_info *info; int i; @@ -466,7 +466,7 @@ gigi (Node_Id gnat_root, false, NULL, Empty); /* This is used for 64-bit multiplication with overflow checking. */ - int64_type = gnat_type_for_size (64, 0); + tree int64_type = gnat_type_for_size (64, 0); mulv64_decl = create_subprog_decl (get_identifier ("__gnat_mulv64"), NULL_TREE, build_function_type_list (int64_type, int64_type, @@ -475,6 +475,15 @@ gigi (Node_Id gnat_root, false, NULL, Empty); strub_make_callable (mulv64_decl); + tree uint64_type = gnat_type_for_size (64, 1); + uns_mulv64_decl += create_subprog_decl (get_identifier ("__gnat_uns_mulv64"), NULL_TREE, + build_function_type_list (uint64_type, uint64_type, +uint64_type, NULL_TREE), + NULL_TREE, is_default, true, true, true, false, + false, NULL, Empty); + strub_make_callable (uns_mulv64_decl); + if (Enable_128bit_Types) { tree int128_type = gnat_type_for_size (128, 0); @@ -487,6 +496,17 @@ gigi (Node_Id gnat_root, NULL_TREE, is_default, true, true, true, false, false, NULL, Empty); strub_make_callable (mulv128_decl); + + tree uint128_type = gnat_type_for_size (128, 1); + uns_mulv128_decl + = create_subprog_decl (get_identifier ("__gnat_uns_mulv128"), NULL_TREE, + build_function_type_list (uint128_type, +uint128_type, +uint128_type, +NULL_TREE), + NULL_TREE, is_default, tr
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Refactoring get_ref_comp
https://gcc.gnu.org/g:eedee58b395b2f7e182917aac3b43f75aee9c044 commit eedee58b395b2f7e182917aac3b43f75aee9c044 Author: Mikael Morin Date: Wed Aug 6 14:23:40 2025 +0200 Refactoring get_ref_comp Renommage type Correction compil' Diff: --- gcc/fortran/trans-descriptor.cc | 57 +++-- 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index ee8487a6cc3c..b54910a5e93c 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -184,16 +184,24 @@ get_type_field (tree type, unsigned field_idx) static tree -gfc_get_descriptor_field (tree desc, unsigned field_idx) +get_ref_comp (tree ref, unsigned field_idx, tree type = NULL_TREE) { - tree type = TREE_TYPE (desc); - gcc_assert (GFC_DESCRIPTOR_TYPE_P (type)); - - tree field = get_type_field (type, field_idx); - gcc_assert (field != NULL_TREE); + tree field = get_type_field (TREE_TYPE (ref), field_idx); + gcc_assert (field != NULL_TREE + && (type == NULL_TREE + || TREE_TYPE (field) == type)); return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), - desc, field, NULL_TREE); + ref, field, NULL_TREE); +} + + +static tree +gfc_get_descriptor_field (tree desc, unsigned field_idx) +{ + gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))); + + return get_ref_comp (desc, field_idx); } @@ -305,15 +313,10 @@ gfc_conv_descriptor_span_set (stmtblock_t *block, tree desc, tree value) static tree get_descriptor_rank (tree desc) { - tree tmp; tree dtype; dtype = get_descriptor_dtype (desc); - tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), GFC_DTYPE_RANK); - gcc_assert (tmp != NULL_TREE - && TREE_TYPE (tmp) == signed_char_type_node); - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp), - dtype, tmp, NULL_TREE); + return get_ref_comp (dtype, GFC_DTYPE_RANK, signed_char_type_node); } tree @@ -340,15 +343,10 @@ gfc_conv_descriptor_rank_set (stmtblock_t *block, tree desc, int value) static tree get_descriptor_version (tree desc) { - tree tmp; tree dtype; dtype = get_descriptor_dtype (desc); - tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), GFC_DTYPE_VERSION); - gcc_assert (tmp != NULL_TREE - && TREE_TYPE (tmp) == integer_type_node); - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp), - dtype, tmp, NULL_TREE); + return get_ref_comp (dtype, GFC_DTYPE_VERSION, integer_type_node); } tree @@ -372,16 +370,10 @@ gfc_conv_descriptor_version_set (stmtblock_t *block, tree desc, tree value) static tree get_descriptor_elem_len (tree desc) { - tree tmp; tree dtype; dtype = get_descriptor_dtype (desc); - tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), - GFC_DTYPE_ELEM_LEN); - gcc_assert (tmp != NULL_TREE - && TREE_TYPE (tmp) == size_type_node); - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp), - dtype, tmp, NULL_TREE); + return get_ref_comp (dtype, GFC_DTYPE_ELEM_LEN, size_type_node); } tree @@ -403,15 +395,10 @@ gfc_conv_descriptor_elem_len_set (stmtblock_t *block, tree desc, tree value) static tree get_descriptor_type (tree desc) { - tree tmp; tree dtype; dtype = get_descriptor_dtype (desc); - tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), GFC_DTYPE_TYPE); - gcc_assert (tmp!= NULL_TREE - && TREE_TYPE (tmp) == signed_char_type_node); - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp), - dtype, tmp, NULL_TREE); + return get_ref_comp (dtype, GFC_DTYPE_TYPE, signed_char_type_node); } tree @@ -541,11 +528,7 @@ static tree gfc_conv_descriptor_subfield (tree desc, tree dim, unsigned field_idx) { tree tmp = get_descriptor_dimension (desc, dim); - tree field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), field_idx); - gcc_assert (field != NULL_TREE); - - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), - tmp, field, NULL_TREE); + return get_ref_comp (tmp, field_idx); } static tree
[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [RISC-V] Avoid setting output object more than once in IOR/XOR synthesis
https://gcc.gnu.org/g:c604c4ffac4973a04c974a8dad2bdf1d3c9c5f67 commit c604c4ffac4973a04c974a8dad2bdf1d3c9c5f67 Author: Jeff Law Date: Sat May 17 07:16:50 2025 -0600 [RISC-V] Avoid setting output object more than once in IOR/XOR synthesis While evaluating Shreya's logical AND synthesis work on spec2017 I ran into a code quality regression where combine was failing to eliminate a redundant sign extension. I had a hunch the problem would be with the multiple sets of the same pseudo register in the AND synthesis path. I was right that the problem was multiple sets of the same pseudo, but it was actually some of the splitters in the RISC-V backend that were the culprit. Those multiple sets caused the sign bit tracking code to need to make conservative assumptions thus resulting in failure to eliminate the unnecessary sign extension. So before we start moving on the logical AND patch we're going to do some cleanups. There's multiple moving parts in play. For example, we have splitters which do multiple sets of the output register. Fixing some of those independently would result in a code quality regression. Instead they need some adjustments to or removal of mvconst_internal. Of course getting rid of mvconst_internal will trigger all kinds of code quality regressions right now which ultimately lead back to the need to revamp the logical AND expander. Point being we've got some circular dependencies and breaking them may result in short term code quality regressions. I'll obviously try to avoid those as much as possible. So to start the process this patch adjusts the recently added XOR/IOR synthesis to avoid re-using the destination register. While the reuse was clearly safe from a semantic standpoint, various parts of the compiler can do a better job for pseudos that are only set once. Given this synthesis path should only be active during initial RTL generation, we can create new pseudos at will, so we create a new one for each insn. At the end of the sequence we copy from the last set into the final destination. This has various trivial impacts on the code generation, but the resulting code looks no better or worse to me across spec2017. This has been tested in my tester and is currently bootstrapping on my BPI. Waiting on data from the pre-commit tester before moving forward... gcc/ * config/riscv/riscv.cc (synthesize_ior_xor): Avoid writing operands[0] more than once, use new pseudos instead. (cherry picked from commit 6ecda1972a1e19d23e6dd238c7509c25acf5c914) Diff: --- gcc/config/riscv/riscv.cc | 52 --- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index e6bd26f0635f..6295d3958357 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -14277,17 +14277,21 @@ synthesize_ior_xor (rtx_code code, rtx operands[3]) { /* Pre-flipping bits we want to preserve. */ rtx input = operands[1]; + rtx output = NULL_RTX; ival = ~INTVAL (operands[2]); while (ival) { HOST_WIDE_INT tmpval = HOST_WIDE_INT_UC (1) << ctz_hwi (ival); rtx x = GEN_INT (tmpval); x = gen_rtx_XOR (word_mode, input, x); - emit_insn (gen_rtx_SET (operands[0], x)); - input = operands[0]; + output = gen_reg_rtx (word_mode); + emit_insn (gen_rtx_SET (output, x)); + input = output; ival &= ~tmpval; } + gcc_assert (output); + /* Now flip all the bits, which restores the bits we were preserving. */ rtx x = gen_rtx_NOT (word_mode, input); @@ -14310,23 +14314,29 @@ synthesize_ior_xor (rtx_code code, rtx operands[3]) int msb = BITS_PER_WORD - 1 - clz_hwi (ival); if (msb - lsb + 1 <= 11) { + rtx output = gen_reg_rtx (word_mode); + rtx input = operands[1]; + /* Rotate the source right by LSB bits. */ rtx x = GEN_INT (lsb); - x = gen_rtx_ROTATERT (word_mode, operands[1], x); - emit_insn (gen_rtx_SET (operands[0], x)); + x = gen_rtx_ROTATERT (word_mode, input, x); + emit_insn (gen_rtx_SET (output, x)); + input = output; /* Shift the constant right by LSB bits. */ x = GEN_INT (ival >> lsb); /* Perform the IOR/XOR operation. */ - x = gen_rtx_fmt_ee (code, word_mode, operands[0], x); - emit_insn (gen_rtx_SET (operands[0], x)); + x = gen_rtx_fmt_ee (code, word_mode, input, x); + output = gen_reg_rtx (word_mode); + emit_insn (gen_rtx_SET (output, x)); + input = output; /* And rotate left to put everything back in place, we don't have rotate
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Factorisation gfc_conv_shift_descriptor
https://gcc.gnu.org/g:13b2631720f9a53e318a519bb1417f6568ffc888 commit 13b2631720f9a53e318a519bb1417f6568ffc888 Author: Mikael Morin Date: Fri Jul 18 14:45:07 2025 +0200 Factorisation gfc_conv_shift_descriptor Factorisation gfc_conv_shift_descriptor Diff: --- gcc/fortran/trans-expr.cc | 7 +-- gcc/fortran/trans-stmt.cc | 6 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index e463702a02a3..3c5600d324a7 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -1060,7 +1060,6 @@ gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e, tree ctree; tree var; tree tmp; - int dim; bool unlimited_poly; unlimited_poly = class_ts.type == BT_CLASS @@ -1127,11 +1126,7 @@ gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e, /* Array references with vector subscripts and non-variable expressions need be converted to a one-based descriptor. */ if (e->expr_type != EXPR_VARIABLE) - { - for (dim = 0; dim < e->rank; ++dim) - gfc_conv_shift_descriptor_lbound (&parmse->pre, parmse->expr, - dim, gfc_index_one_node); - } + gfc_conv_shift_descriptor (&parmse->pre, parmse->expr, e->rank); if (class_ts.u.derived->components->as->rank != e->rank) { diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc index 1867f67b16e3..57ca11e1bafb 100644 --- a/gcc/fortran/trans-stmt.cc +++ b/gcc/fortran/trans-stmt.cc @@ -2168,16 +2168,12 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) if ((!sym->assoc->variable && !cst_array_ctor) || !whole_array) { - int dim; - if (whole_array) gfc_add_modify (&se.pre, desc, se.expr); /* The generated descriptor has lower bound zero (as array temporary), shift bounds so we get lower bounds of 1. */ - for (dim = 0; dim < e->rank; ++dim) - gfc_conv_shift_descriptor_lbound (&se.pre, desc, - dim, gfc_index_one_node); + gfc_conv_shift_descriptor (&se.pre, desc, e->rank); } if (e->expr_type == EXPR_FUNCTION
[gcc(refs/users/aoliva/heads/testme)] [analyzer] another function name that returns a pointer to errno
https://gcc.gnu.org/g:ad19a18f93211499e05fbcaeb61b6ba4a935eb4a commit ad19a18f93211499e05fbcaeb61b6ba4a935eb4a Author: Alexandre Oliva Date: Wed Sep 10 19:59:08 2025 -0300 [analyzer] another function name that returns a pointer to errno Add __get_errno_ptr() as yet another synonym for __errno_location. for gcc/analyzer/ChangeLog * kf.cc (register_known_functions): Add __get_errno_ptr. Diff: --- gcc/analyzer/kf.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc index 2a7c35703153..5c54b5564486 100644 --- a/gcc/analyzer/kf.cc +++ b/gcc/analyzer/kf.cc @@ -2373,6 +2373,7 @@ register_known_functions (known_function_manager &kfm, kfm.add ("___errno", std::make_unique ()); kfm.add ("__error", std::make_unique ()); kfm.add ("__errno", std::make_unique ()); +kfm.add ("__get_errno_ptr", std::make_unique ()); } /* Language-specific support functions. */
[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 r16-3899] RISC-V: Imply zicsr for sdtrig and ssstrict extensions.
https://gcc.gnu.org/g:3e932d6384c9bc415255a5d2453e7ddf2c4792f2 commit r16-3899-g3e932d6384c9bc415255a5d2453e7ddf2c4792f2 Author: Dongyan Chen Date: Mon Sep 15 21:49:15 2025 -0600 RISC-V: Imply zicsr for sdtrig and ssstrict extensions. This patch implies zicsr for sdtrig and ssstrict extensions. According to the riscv-privileged spec, the sdtrig and ssstrict extensions are privileged extensions, so they should imply zicsr. gcc/ChangeLog: * config/riscv/riscv-ext.def: Imply zicsr. Diff: --- gcc/config/riscv/riscv-ext.def | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/config/riscv/riscv-ext.def b/gcc/config/riscv/riscv-ext.def index d162fa47efd9..80f534c64614 100644 --- a/gcc/config/riscv/riscv-ext.def +++ b/gcc/config/riscv/riscv-ext.def @@ -1564,7 +1564,7 @@ DEFINE_RISCV_EXT( /* FULL_NAME */ "sdtrig extension", /* DESC */ "", /* URL */ , - /* DEP_EXTS */ ({}), + /* DEP_EXTS */ ({"zicsr"}), /* SUPPORTED_VERSIONS */ ({{1, 0}}), /* FLAG_GROUP */ sd, /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED, @@ -1941,7 +1941,7 @@ DEFINE_RISCV_EXT( /* FULL_NAME */ "ssstrict extension", /* DESC */ "", /* URL */ , - /* DEP_EXTS */ ({}), + /* DEP_EXTS */ ({"zicsr"}), /* SUPPORTED_VERSIONS */ ({{1, 0}}), /* FLAG_GROUP */ ss, /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED,
[gcc r16-3900] RISC-V: Configure Profiles definitions in the definition file.
https://gcc.gnu.org/g:3e59b15a533c0d6398713241d821d44a8bc93195 commit r16-3900-g3e59b15a533c0d6398713241d821d44a8bc93195 Author: Jiawei Date: Mon Sep 15 21:54:32 2025 -0600 RISC-V: Configure Profiles definitions in the definition file. Moving RISC-V Profiles definations into 'riscv-profiles.def'. Add comments for 'riscv_profiles'. gcc/ChangeLog: * common/config/riscv/riscv-common.cc (struct riscv_profiles): Add comments. (RISCV_PROFILE): Removed. * config/riscv/riscv-profiles.def: New file. Diff: --- gcc/common/config/riscv/riscv-common.cc | 64 - gcc/config/riscv/riscv-profiles.def | 82 + 2 files changed, 91 insertions(+), 55 deletions(-) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index a165506f410d..efa2a45a6404 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -262,67 +262,21 @@ struct riscv_ext_version int minor_version; }; -struct riscv_profiles -{ +/* Information about one Profile we know about. */ +struct riscv_profiles { + /* This Profile's name. */ const char *profile_name; + + /* This Profile's arch canonical string. */ const char *profile_string; }; -/* This table records the mapping form RISC-V Profiles into march string. */ static const riscv_profiles riscv_profiles_table[] = { - /* RVI20U only contains the base extension 'i' as mandatory extension. */ - {"rvi20u64", "rv64i"}, - {"rvi20u32", "rv32i"}, - - /* RVA20U contains the 'i,m,a,f,d,c,zicsr,zicntr,ziccif,ziccrse,ziccamoa, - zicclsm,za128rs' as mandatory extensions. */ - {"rva20u64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa" - "_zicclsm_za128rs"}, - - /* RVA22U contains the 'i,m,a,f,d,c,zicsr,zihintpause,zba,zbb,zbs,zicntr, - zihpm,ziccif,ziccrse,ziccamoa, zicclsm,zic64b,za64rs,zicbom,zicbop,zicboz, - zfhmin,zkt' as mandatory extensions. */ - {"rva22u64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa" - "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" - "_zicboz_zfhmin_zkt"}, - - /* RVA23 contains all mandatory base ISA for RVA22U64 and the new extension - 'v,zihintntl,zvfhmin,zvbb,zvkt,zicond,zimop,zcmop,zfa,zawrs' as mandatory - extensions. */ - {"rva23u64", "rv64imafdcbv_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" - "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" - "_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zicond_zimop_zcmop_zcb" - "_zfa_zawrs_supm"}, - - /* RVA23S contains all mandatory base ISA for RVA23U64 and the privileged - extensions as mandatory extensions. */ - {"rva23s64", "rv64imafdcbv_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" - "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" - "_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zicond_zimop_zcmop_zcb" - "_zfa_zawrs_svbare_svade_ssccptr_sstvecd_sstvala_sscounterenw_svpbmt" - "_svinval_svnapot_sstc_sscofpmf_ssnpm_ssu64xl_sha_supm" - }, - - /* RVB23 contains all mandatory base ISA for RVA22U64 and the new extension - 'zihintntl,zicond,zimop,zcmop,zfa,zawrs' as mandatory - extensions. */ - {"rvb23u64", "rv64imafdcb_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" - "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" - "_zicboz_zfhmin_zkt_zihintntl_zicond_zimop_zcmop_zcb" - "_zfa_zawrs"}, - - /* RVB23S contains all mandatory base ISA for RVB23U64 and the privileged - extensions as mandatory extensions. */ - {"rvb23s64", "rv64imafdcb_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa" - "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop" - "_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zicond_zimop_zcmop_zcb" - "_zfa_zawrs_svbare_svade_ssccptr_sstvecd_sstvala_sscounterenw_svpbmt" - "_svinval_svnapot_sstc_sscofpmf_ssu64xl_supm" - }, - - /* Terminate the list. */ - {NULL, NULL} +#define RISCV_PROFILE(PROFILE_NAME, ARCH) \ +{PROFILE_NAME, ARCH}, +#include "../../../config/riscv/riscv-profiles.def" +{NULL, NULL} }; static const riscv_cpu_info riscv_cpu_tables[] = diff --git a/gcc/config/riscv/riscv-profiles.def b/gcc/config/riscv/riscv-profiles.def new file mode 100644 index ..741c4719b37d --- /dev/null +++ b/gcc/config/riscv/riscv-profiles.def @@ -0,0 +1,82 @@ +/* List of supported core and tune info for RISC-V. + Copyright (C) 2025 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Pu
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Suppression gfc_conv_descriptor_attribute compil' OK
https://gcc.gnu.org/g:b2cec1f99b0df0f539228be89cf6b04024324890 commit b2cec1f99b0df0f539228be89cf6b04024324890 Author: Mikael Morin Date: Sun Jun 29 14:15:55 2025 +0200 Suppression gfc_conv_descriptor_attribute compil' OK Diff: --- gcc/fortran/trans-descriptor.cc | 16 gcc/fortran/trans-descriptor.h | 1 - 2 files changed, 17 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index c656bc722a75..9d04a4801233 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -392,22 +392,6 @@ gfc_conv_descriptor_elem_len_set (stmtblock_t *block, tree desc, tree value) } -tree -gfc_conv_descriptor_attribute (tree desc) -{ - tree tmp; - tree dtype; - - dtype = get_descriptor_dtype (desc); - tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), - GFC_DTYPE_ATTRIBUTE); - gcc_assert (tmp!= NULL_TREE - && TREE_TYPE (tmp) == short_integer_type_node); - return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp), - dtype, tmp, NULL_TREE); -} - - static tree get_descriptor_type (tree desc) { diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index 96f66b004ecb..69cc4f3e2ac6 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -48,7 +48,6 @@ tree gfc_get_cfi_dim_extent (tree desc, tree idx); tree gfc_get_cfi_dim_sm (tree desc, tree idx); -tree gfc_conv_descriptor_attribute (tree desc); tree gfc_get_descriptor_dimension (tree desc); tree gfc_conv_descriptor_dimension (tree desc, tree dim); tree gfc_conv_descriptor_token (tree desc);
[gcc r16-3901] RISC-V: Allow profiles input in '--with-arch' option.
https://gcc.gnu.org/g:41d8c4e150f21a256e2e0553d715f12f48e78636 commit r16-3901-g41d8c4e150f21a256e2e0553d715f12f48e78636 Author: Jiawei Date: Mon Sep 15 21:56:05 2025 -0600 RISC-V: Allow profiles input in '--with-arch' option. Allows profiles input in '--with-arch'. Check profiles with 'riscv-profiles.def'. gcc/ChangeLog: * config.gcc: Accept RISC-V profiles in `--with-arch`. * config/riscv/arch-canonicalize: Add profile detection and skip canonicalization for profiles. Diff: --- gcc/config.gcc | 13 ++--- gcc/config/riscv/arch-canonicalize | 23 ++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/gcc/config.gcc b/gcc/config.gcc index 9da9ac51eccd..9251b10ac897 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -4775,7 +4775,8 @@ case "${target}" in # Infer arch from --with-arch, --target, and --with-abi. case "${with_arch}" in - rv32e* | rv32i* | rv32g* | rv64e* | rv64i* | rv64g*) + rv32e* | rv32i* | rv32g* | rv64e* | rv64i* | rv64g* \ + | rvi20* | rva20* | rva22* | rva23* | rvb23*) # OK. ;; "") @@ -4789,7 +4790,7 @@ case "${target}" in esac ;; *) - echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32e, rv32i, rv32g, rv64e, rv64i, or rv64g." 1>&2 + echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32e, rv32i, rv32g, rv64e, rv64i, rv64g, or a profile." 1>&2 exit 1 ;; esac @@ -4827,9 +4828,15 @@ case "${target}" in ilp32,rv32* | ilp32e,rv32e* \ | ilp32f,rv32*f* | ilp32f,rv32g* \ | ilp32d,rv32*d* | ilp32d,rv32g* \ + | ilp32,rvi20u32* | ilp32f,rvi20u32* \ + | ilp32d,rvi20u32* \ | lp64,rv64* | lp64e,rv64e* \ | lp64f,rv64*f* | lp64f,rv64g* \ - | lp64d,rv64*d* | lp64d,rv64g*) + | lp64d,rv64*d* | lp64d,rv64g* \ + | lp64,rvi20u64* | lp64f,rvi20u64* \ + | lp64d,rva20u64* | lp64d,rva22u64* \ + | lp64d,rva23u64* | lp64d,rva23s64* \ + | lp64d,rvb23u64* | lp64d,rvb23s64) ;; *) echo "--with-abi=${with_abi} is not supported for ISA ${with_arch}" 1>&2 diff --git a/gcc/config/riscv/arch-canonicalize b/gcc/config/riscv/arch-canonicalize index 15a398502b38..78c8b25d17e5 100755 --- a/gcc/config/riscv/arch-canonicalize +++ b/gcc/config/riscv/arch-canonicalize @@ -341,6 +341,24 @@ def get_all_extensions(): # IMPLIED_EXT = parse_def_files() +def load_profiles(): +profiles = set() +def_path = os.path.join(os.path.dirname(__file__), "riscv-profiles.def") +with open(def_path) as f: +for line in f: +line = line.strip() +if line.startswith("RISCV_PROFILE"): +# Format: RISCV_PROFILE("rva20u64", "rv64imafd...") +parts = line.split('"') +if len(parts) >= 2: +profiles.add(parts[1]) # Compare PROFILE_NAME +return profiles + +SUPPORTED_PROFILES = load_profiles() + +def is_profile_arch(arch): +return arch in SUPPORTED_PROFILES + def arch_canonicalize(arch, isa_spec): # TODO: Support extension version. is_isa_spec_2p2 = isa_spec == '2.2' @@ -608,7 +626,10 @@ if __name__ == "__main__": sys.exit(run_unit_tests()) elif args.arch_strs: for arch in args.arch_strs: - print (arch_canonicalize(arch, args.misa_spec)) + if is_profile_arch(arch): + print(arch) + else: + print(arch_canonicalize(arch, args.misa_spec)) else: parser.print_help() sys.exit(1)
[gcc r16-3854] RISC-V: Fix vendor intrinsic tests for disabled multilib configurations
https://gcc.gnu.org/g:6485b105655c2179eb9f74ac35d535912f43cac5 commit r16-3854-g6485b105655c2179eb9f74ac35d535912f43cac5 Author: Kito Cheng Date: Wed Sep 10 18:23:12 2025 +0800 RISC-V: Fix vendor intrinsic tests for disabled multilib configurations Add wrapper headers that prevent vendor vector headers from including system stdint.h, ensuring tests work correctly when multilib is disabled. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/xandesvector/non-policy/non-overloaded/andes_vector.h: New file. * gcc.target/riscv/rvv/xandesvector/non-policy/non-overloaded/nds_vfncvtbf16s.c (#include): Use local andes_vector.h instead of system header. * gcc.target/riscv/rvv/xandesvector/non-policy/non-overloaded/nds_vfwcvtsbf16.c (#include): Likewise. * gcc.target/riscv/rvv/xandesvector/non-policy/overloaded/andes_vector.h: New file. * gcc.target/riscv/rvv/xandesvector/non-policy/overloaded/nds_vfncvtbf16s.c (#include): Use local andes_vector.h instead of system header. * gcc.target/riscv/rvv/xandesvector/non-policy/overloaded/nds_vfwcvtsbf16.c (#include): Likewise. * gcc.target/riscv/rvv/xandesvector/policy/non-overloaded/andes_vector.h: New file. * gcc.target/riscv/rvv/xandesvector/policy/non-overloaded/nds_vfncvtbf16s.c (#include): Use local andes_vector.h instead of system header. * gcc.target/riscv/rvv/xandesvector/policy/non-overloaded/nds_vfwcvtsbf16.c (#include): Likewise. * gcc.target/riscv/rvv/xandesvector/policy/overloaded/andes_vector.h: New file. * gcc.target/riscv/rvv/xandesvector/policy/overloaded/nds_vfncvtbf16s.c (#include): Use local andes_vector.h instead of system header. * gcc.target/riscv/rvv/xandesvector/policy/overloaded/nds_vfwcvtsbf16.c (#include): Likewise. * gcc.target/riscv/rvv/xsfvector/sifive_vector.h: New file. * gcc.target/riscv/rvv/xtheadvector/riscv_th_vector.h: New file. * gcc.target/riscv/rvv/xtheadvector/riscv_vector.h: New file. Diff: --- .../rvv/xandesvector/non-policy/non-overloaded/andes_vector.h | 11 +++ .../xandesvector/non-policy/non-overloaded/nds_vfncvtbf16s.c | 2 +- .../xandesvector/non-policy/non-overloaded/nds_vfwcvtsbf16.c | 2 +- .../rvv/xandesvector/non-policy/overloaded/andes_vector.h | 11 +++ .../rvv/xandesvector/non-policy/overloaded/nds_vfncvtbf16s.c | 2 +- .../rvv/xandesvector/non-policy/overloaded/nds_vfwcvtsbf16.c | 2 +- .../rvv/xandesvector/policy/non-overloaded/andes_vector.h | 11 +++ .../rvv/xandesvector/policy/non-overloaded/nds_vfncvtbf16s.c | 2 +- .../rvv/xandesvector/policy/non-overloaded/nds_vfwcvtsbf16.c | 2 +- .../riscv/rvv/xandesvector/policy/overloaded/andes_vector.h | 11 +++ .../rvv/xandesvector/policy/overloaded/nds_vfncvtbf16s.c | 2 +- .../rvv/xandesvector/policy/overloaded/nds_vfwcvtsbf16.c | 2 +- gcc/testsuite/gcc.target/riscv/rvv/xsfvector/sifive_vector.h | 11 +++ .../gcc.target/riscv/rvv/xtheadvector/riscv_th_vector.h | 11 +++ .../gcc.target/riscv/rvv/xtheadvector/riscv_vector.h | 11 +++ 15 files changed, 85 insertions(+), 8 deletions(-) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xandesvector/non-policy/non-overloaded/andes_vector.h b/gcc/testsuite/gcc.target/riscv/rvv/xandesvector/non-policy/non-overloaded/andes_vector.h new file mode 100644 index ..0d0a8efef6ed --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/xandesvector/non-policy/non-overloaded/andes_vector.h @@ -0,0 +1,11 @@ +/* Wrapper of andes_vector.h, prevent andes_vector.h including stdint.h from + C library, that might cause problem on testing RV32 related testcase when + we disable multilib. */ +#ifndef _ANDES_VECTOR_WRAP_H + +#define _GCC_WRAP_STDINT_H +#include "stdint-gcc.h" +#include_next +#define _ANDES_VECTOR_WRAP_H + +#endif diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xandesvector/non-policy/non-overloaded/nds_vfncvtbf16s.c b/gcc/testsuite/gcc.target/riscv/rvv/xandesvector/non-policy/non-overloaded/nds_vfncvtbf16s.c index 8b03564d4ffc..5f15d7f235c8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/xandesvector/non-policy/non-overloaded/nds_vfncvtbf16s.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/xandesvector/non-policy/non-overloaded/nds_vfncvtbf16s.c @@ -2,7 +2,7 @@ /* { dg-options "-march=rv32gv_xandesvbfhcvt -mabi=ilp32 -O3 -fno-schedule-insns -fno-schedule-insns2" { target { rv32 } } } */ /* { dg-options "-march=rv64gv_xandesvbfhcvt -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2" { target { rv64 } } } */ -#include +#include "andes_vector.h" vbfloat16mf4_t test_nds_vfncvt_bf16_s_bf16mf4(vfloat32mf2_t vs2, size_t vl) { return __riscv_nds_vfncvt_bf16_s_bf16mf4(vs2,
[gcc r14-12021] c++: Fix mangling of _Float16 template args [PR121801]
https://gcc.gnu.org/g:1d92f9592eb1f90d4ac776bd49d83e3316001b1f commit r14-12021-g1d92f9592eb1f90d4ac776bd49d83e3316001b1f Author: Matthias Kretz Date: Fri Sep 5 12:16:34 2025 +0200 c++: Fix mangling of _Float16 template args [PR121801] Signed-off-by: Matthias Kretz gcc/testsuite/ChangeLog: PR c++/121801 * g++.dg/abi/pr121801.C: New test. gcc/cp/ChangeLog: PR c++/121801 * mangle.cc (write_real_cst): Handle 16-bit real and assert that reals have 16 bits or a multiple of 32 bits. (cherry picked from commit 19d1c7c28f4fd0557dd868a7a4041b00ceada890) Diff: --- gcc/cp/mangle.cc| 15 ++- gcc/testsuite/g++.dg/abi/pr121801.C | 13 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index fe8e5a0fa288..245c768b1805 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -2160,11 +2160,24 @@ write_real_cst (const tree value) int i, limit, dir; tree type = TREE_TYPE (value); - int words = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type)) / 32; + int bits = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type)); + int words = bits / 32; real_to_target (target_real, &TREE_REAL_CST (value), TYPE_MODE (type)); + if (words == 0) +{ + /* _Float16 and std::bfloat16_t are the only supported types smaller than +32 bits. */ + gcc_assert (bits == 16); + sprintf (buffer, "%04lx", (unsigned long) target_real[0]); + write_chars (buffer, 4); + return; +} + + gcc_assert (bits % 32 == 0); + /* The value in target_real is in the target word order, so we must write it out backward if that happens to be little-endian. write_number cannot be used, it will diff --git a/gcc/testsuite/g++.dg/abi/pr121801.C b/gcc/testsuite/g++.dg/abi/pr121801.C new file mode 100644 index ..cd35186d8881 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/pr121801.C @@ -0,0 +1,13 @@ +// PR c++/121801 +// { dg-do compile { target { c++20 && float16 } } } +// { dg-add-options float16 } + +template<_Float16 T> void f() {} + +void uses() { + f<_Float16(1)>(); + f<_Float16(2)>(); +} + +// { dg-final { scan-assembler "_Z1fILDF16_3c00EEvv" } } +// { dg-final { scan-assembler "_Z1fILDF16_4000EEvv" } }
[gcc r16-3853] Bail out early during gimplify_asm_expr [PR121391]
https://gcc.gnu.org/g:4cff794ca18a96ceeb83ccb18b08ffa0a63c58af commit r16-3853-g4cff794ca18a96ceeb83ccb18b08ffa0a63c58af Author: Stefan Schulze Frielinghaus Date: Mon Sep 15 09:10:53 2025 +0200 Bail out early during gimplify_asm_expr [PR121391] In case an asm operand is an error node, constraints etc. are still validated. Furthermore, all other operands are gimplified, although an error is returned in the end anyway. For hard register constraints an operand is required in order to determine the mode from which the number of registers follows. Therefore, instead of adding extra guards, bail out early. gcc/ChangeLog: PR middle-end/121391 * gimplify.cc (gimplify_asm_expr): In case an asm operand is an error node, bail out early. gcc/testsuite/ChangeLog: * gcc.dg/pr121391-1.c: New test. * gcc.dg/pr121391-2.c: New test. Diff: --- gcc/gimplify.cc | 18 ++ gcc/testsuite/gcc.dg/pr121391-1.c | 9 + gcc/testsuite/gcc.dg/pr121391-2.c | 9 + 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index ca1fa2189cb9..900968356651 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -7930,6 +7930,8 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) bool ok; size_t constraint_len; + if (error_operand_p (TREE_VALUE (link))) + return GS_ERROR; link_next = TREE_CHAIN (link); oconstraints[i] @@ -7951,10 +7953,9 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) /* If we can't make copies, we can only accept memory. Similarly for VLAs. */ tree outtype = TREE_TYPE (TREE_VALUE (link)); - if (outtype != error_mark_node - && (TREE_ADDRESSABLE (outtype) - || !COMPLETE_TYPE_P (outtype) - || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype + if (TREE_ADDRESSABLE (outtype) + || !COMPLETE_TYPE_P (outtype) + || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))) { if (allows_mem) allows_reg = 0; @@ -8155,6 +8156,8 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) int input_num = 0; for (link = ASM_INPUTS (expr); link; ++input_num, ++i, link = link_next) { + if (error_operand_p (TREE_VALUE (link))) + return GS_ERROR; link_next = TREE_CHAIN (link); constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); reg_info.operand = TREE_VALUE (link); @@ -8169,10 +8172,9 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) /* If we can't make copies, we can only accept memory. */ tree intype = TREE_TYPE (TREE_VALUE (link)); - if (intype != error_mark_node - && (TREE_ADDRESSABLE (intype) - || !COMPLETE_TYPE_P (intype) - || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype + if (TREE_ADDRESSABLE (intype) + || !COMPLETE_TYPE_P (intype) + || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))) { if (allows_mem) allows_reg = 0; diff --git a/gcc/testsuite/gcc.dg/pr121391-1.c b/gcc/testsuite/gcc.dg/pr121391-1.c new file mode 100644 index ..6a015210ef9c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr121391-1.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target aarch64*-*-* arm*-*-* powerpc*-*-* s390*-*-* x86_64-*-* } } */ + +/* For the non existing variable we are faced with an error mark node during + gimplify_asm_expr(). */ + +void test (void) +{ + __asm__ __volatile__ ("" : "={2}" (non_existing_var)); /* { dg-error {'non_existing_var' undeclared} } */ +} diff --git a/gcc/testsuite/gcc.dg/pr121391-2.c b/gcc/testsuite/gcc.dg/pr121391-2.c new file mode 100644 index ..c03f0ab283b8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr121391-2.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target aarch64*-*-* arm*-*-* powerpc*-*-* s390*-*-* x86_64-*-* } } */ + +/* For the non existing variable we are faced with an error mark node during + gimplify_asm_expr(). */ + +void test (void) +{ + __asm__ __volatile__ ("" :: "{2}" (non_existing_var)); /* { dg-error {'non_existing_var' undeclared} } */ +}
[gcc r15-10325] LoongArch: Fix wrong code from bstrpick split
https://gcc.gnu.org/g:4dd2885905afde80da0498f381b0818b05bc9844 commit r15-10325-g4dd2885905afde80da0498f381b0818b05bc9844 Author: Xi Ruoyao Date: Fri Sep 12 15:57:08 2025 +0800 LoongArch: Fix wrong code from bstrpick split After late-combine is added, split1 can see an input like (insn 56 55 169 5 (set (reg/v:DI 87 [ n ]) (ior:DI (and:DI (reg/v:DI 87 [ n ]) (const_int 281474976710655 [0x])) (and:DI (reg:DI 131 [ _45 ]) (const_int -281474976710656 [0x] "pr121906.c":22:8 108 {*bstrins_di_for_ior_mask} (nil)) And the splitter ends up emitting (insn 184 55 185 5 (set (reg/v:DI 87 [ n ]) (reg:DI 131 [ _45 ])) "pr121906.c":22:8 -1 (nil)) (insn 185 184 169 5 (set (zero_extract:DI (reg/v:DI 87 [ n ]) (const_int 48 [0x30]) (const_int 0 [0])) (reg/v:DI 87 [ n ])) "pr121906.c":22:8 -1 (nil)) which obviously lost everything in r87, instead of retaining its lower bits as we expect. It's because the splitter didn't anticipate the output register may be one of the input registers. PR target/121906 gcc/ * config/loongarch/loongarch.md (*bstrins__for_ior_mask): Always create a new pseudo for the input register of the bstrins instruction. gcc/testsuite/ * gcc.target/loongarch/pr121906.c: New test. (cherry picked from commit 290851e63a5b99c99eb196f2823ea3051c0f0214) Diff: --- gcc/config/loongarch/loongarch.md | 14 ++-- gcc/testsuite/gcc.target/loongarch/pr121906.c | 31 +++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 32ef9809b108..f42dc102d109 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -1619,13 +1619,13 @@ operands[2] = GEN_INT (len); operands[4] = GEN_INT (lo); -if (lo) - { - rtx tmp = gen_reg_rtx (mode); - emit_move_insn (tmp, gen_rtx_ASHIFTRT(mode, operands[3], - GEN_INT (lo))); - operands[3] = tmp; - } +/* Use a new pseudo register even if lo == 0 or we'll wreck havoc + when operands[0] is same as operands[3]. See PR 121906. */ +rtx tmp = gen_reg_rtx (mode); +rtx val = lo ? gen_rtx_ASHIFTRT (mode, operands[3], GEN_INT (lo)) +: operands[3]; +emit_move_insn (tmp, val); +operands[3] = tmp; }) ;; We always avoid the shift operation in bstrins__for_ior_mask diff --git a/gcc/testsuite/gcc.target/loongarch/pr121906.c b/gcc/testsuite/gcc.target/loongarch/pr121906.c new file mode 100644 index ..b4fde5f0c854 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/pr121906.c @@ -0,0 +1,31 @@ +/* PR target/121906 */ +/* { dg-do run } */ +/* { dg-options "-O2 -mno-lsx" } */ + +typedef unsigned short u16; +typedef unsigned long u64; +typedef u16 v4hi __attribute__ ((vector_size (8))); +typedef u16 v8hi __attribute__ ((vector_size (16))); + +u64 d; +int e, i; +u16 x; + +int +main () +{ + v4hi n = { 1 }; + u64 *o = &d; +p: + asm goto ("" : : : : q); + n[3] = (-(v8hi){ 0, 0, 0, 0, x })[7]; + for (; e >= 0; e--) +{ + *o = n[0]; + if (i) +goto p; +q: +} + if (d != 1) +__builtin_trap (); +}
[gcc r16-3856] LoongArch: Fix wrong code from bstrpick split
https://gcc.gnu.org/g:290851e63a5b99c99eb196f2823ea3051c0f0214 commit r16-3856-g290851e63a5b99c99eb196f2823ea3051c0f0214 Author: Xi Ruoyao Date: Fri Sep 12 15:57:08 2025 +0800 LoongArch: Fix wrong code from bstrpick split After late-combine is added, split1 can see an input like (insn 56 55 169 5 (set (reg/v:DI 87 [ n ]) (ior:DI (and:DI (reg/v:DI 87 [ n ]) (const_int 281474976710655 [0x])) (and:DI (reg:DI 131 [ _45 ]) (const_int -281474976710656 [0x] "pr121906.c":22:8 108 {*bstrins_di_for_ior_mask} (nil)) And the splitter ends up emitting (insn 184 55 185 5 (set (reg/v:DI 87 [ n ]) (reg:DI 131 [ _45 ])) "pr121906.c":22:8 -1 (nil)) (insn 185 184 169 5 (set (zero_extract:DI (reg/v:DI 87 [ n ]) (const_int 48 [0x30]) (const_int 0 [0])) (reg/v:DI 87 [ n ])) "pr121906.c":22:8 -1 (nil)) which obviously lost everything in r87, instead of retaining its lower bits as we expect. It's because the splitter didn't anticipate the output register may be one of the input registers. PR target/121906 gcc/ * config/loongarch/loongarch.md (*bstrins__for_ior_mask): Always create a new pseudo for the input register of the bstrins instruction. gcc/testsuite/ * gcc.target/loongarch/pr121906.c: New test. Diff: --- gcc/config/loongarch/loongarch.md | 14 ++-- gcc/testsuite/gcc.target/loongarch/pr121906.c | 31 +++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 32ef9809b108..f42dc102d109 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -1619,13 +1619,13 @@ operands[2] = GEN_INT (len); operands[4] = GEN_INT (lo); -if (lo) - { - rtx tmp = gen_reg_rtx (mode); - emit_move_insn (tmp, gen_rtx_ASHIFTRT(mode, operands[3], - GEN_INT (lo))); - operands[3] = tmp; - } +/* Use a new pseudo register even if lo == 0 or we'll wreck havoc + when operands[0] is same as operands[3]. See PR 121906. */ +rtx tmp = gen_reg_rtx (mode); +rtx val = lo ? gen_rtx_ASHIFTRT (mode, operands[3], GEN_INT (lo)) +: operands[3]; +emit_move_insn (tmp, val); +operands[3] = tmp; }) ;; We always avoid the shift operation in bstrins__for_ior_mask diff --git a/gcc/testsuite/gcc.target/loongarch/pr121906.c b/gcc/testsuite/gcc.target/loongarch/pr121906.c new file mode 100644 index ..b4fde5f0c854 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/pr121906.c @@ -0,0 +1,31 @@ +/* PR target/121906 */ +/* { dg-do run } */ +/* { dg-options "-O2 -mno-lsx" } */ + +typedef unsigned short u16; +typedef unsigned long u64; +typedef u16 v4hi __attribute__ ((vector_size (8))); +typedef u16 v8hi __attribute__ ((vector_size (16))); + +u64 d; +int e, i; +u16 x; + +int +main () +{ + v4hi n = { 1 }; + u64 *o = &d; +p: + asm goto ("" : : : : q); + n[3] = (-(v8hi){ 0, 0, 0, 0, x })[7]; + for (; e >= 0; e--) +{ + *o = n[0]; + if (i) +goto p; +q: +} + if (d != 1) +__builtin_trap (); +}
[gcc r16-3852] Fix whitespace after r16-3679-g19d1c7c28f4fd0
https://gcc.gnu.org/g:8d264d90a22d5e13c876a4f352c702c7f5bc4f0b commit r16-3852-g8d264d90a22d5e13c876a4f352c702c7f5bc4f0b Author: Matthias Kretz Date: Tue Sep 9 08:16:02 2025 +0200 Fix whitespace after r16-3679-g19d1c7c28f4fd0 Signed-off-by: Matthias Kretz gcc/cp/ChangeLog: * mangle.cc (write_real_cst): Replace 8 spaces with Tab. Diff: --- gcc/cp/mangle.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index 7678c0a97b96..761aae484c80 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -2185,7 +2185,7 @@ write_real_cst (const tree value) if (words == 0) { /* _Float16 and std::bfloat16_t are the only supported types smaller than - 32 bits. */ +32 bits. */ gcc_assert (bits == 16); sprintf (buffer, "%04lx", (unsigned long) target_real[0]); write_chars (buffer, 4);
[gcc r16-3863] ada: Fix code generation when there is no No_Finalization restiction
https://gcc.gnu.org/g:90997ddd7b8764741e57bee52bcd3712afb3ea8d commit r16-3863-g90997ddd7b8764741e57bee52bcd3712afb3ea8d Author: Vadim Godunko Date: Sun Jul 13 09:41:22 2025 +0400 ada: Fix code generation when there is no No_Finalization restiction Check whether library is elaborated is not generated when there is not standard library available on target. gcc/ada/ChangeLog: * bindgen.adb (Gen_Adafinal): Don't generate code when use of standard library suppressed. Diff: --- gcc/ada/bindgen.adb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gcc/ada/bindgen.adb b/gcc/ada/bindgen.adb index cb39af67f9a5..14367ebe97a7 100644 --- a/gcc/ada/bindgen.adb +++ b/gcc/ada/bindgen.adb @@ -490,7 +490,9 @@ package body Bindgen is WBI (""); WBI (" begin"); - if not CodePeer_Mode then + if not CodePeer_Mode +and not Suppress_Standard_Library_On_Target + then WBI (" if not Is_Elaborated then"); WBI (" return;"); WBI (" end if;");
[gcc r16-3872] ada: Fix crash on iterator of type with Constant_Indexing aspect
https://gcc.gnu.org/g:fa714c16d45e56f27733f4be3eeb3070457a4667 commit r16-3872-gfa714c16d45e56f27733f4be3eeb3070457a4667 Author: Eric Botcazou Date: Fri Aug 29 09:24:33 2025 +0200 ada: Fix crash on iterator of type with Constant_Indexing aspect This happens when the type returned by the indexing function is a private type whose completion is derived from another private type, because the Finalize_Address routine cannot correctly fetch the actual root type. gcc/ada/ChangeLog: * exp_util.adb (Finalize_Address): In an untagged derivation, call Root_Type on the full view of the base type if the partial view is itself not a derived type. (Is_Untagged_Derivation): Minor formatting tweak. Diff: --- gcc/ada/exp_util.adb | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index 4135e24424d3..78fb3167c82d 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -6206,7 +6206,11 @@ package body Exp_Util is Utyp := Corresponding_Record_Type (Root_Type (Btyp)); elsif Is_Implicit_Full_View (Utyp) then -Utyp := Underlying_Type (Root_Type (Btyp)); +if Is_Derived_Type (Btyp) then + Utyp := Underlying_Type (Root_Type (Btyp)); +else + Utyp := Underlying_Type (Root_Type (Full_View (Btyp))); +end if; if Is_Protected_Type (Utyp) then Utyp := Corresponding_Record_Type (Utyp); @@ -10033,7 +10037,8 @@ package body Exp_Util is begin return (not Is_Tagged_Type (T) and then Is_Derived_Type (T)) or else - (Is_Private_Type (T) and then Present (Full_View (T)) + (Is_Private_Type (T) + and then Present (Full_View (T)) and then not Is_Tagged_Type (Full_View (T)) and then Is_Derived_Type (Full_View (T)) and then Etype (Full_View (T)) /= T);
[gcc r16-3866] ada: Remove the note that GNAT LLVM doesn't ship the light runtime
https://gcc.gnu.org/g:18f0f8024c6e822d20e20854d971b53b141f038d commit r16-3866-g18f0f8024c6e822d20e20854d971b53b141f038d Author: Sebastian Poeplau Date: Wed Aug 27 10:02:21 2025 +0200 ada: Remove the note that GNAT LLVM doesn't ship the light runtime gcc/ada/ChangeLog: * doc/gnat_ugn/building_executable_programs_with_gnat.rst: Remove the note on light runtimes. Diff: --- gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst index 2a26e4659b8b..fbd3202c3d65 100644 --- a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst +++ b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst @@ -8143,5 +8143,4 @@ GNAT. .. only:: PRO - It provides the same runtimes with the exception that light runtimes - are not currently included with the native compilers. + It provides the same runtimes.
[gcc r16-3876] ada: Update ghost code SPARK RM rules
https://gcc.gnu.org/g:9c79e191c09d9906e795bd532da6c66e11cecc9d commit r16-3876-g9c79e191c09d9906e795bd532da6c66e11cecc9d Author: Viljar Indus Date: Tue Sep 2 10:16:37 2025 +0300 ada: Update ghost code SPARK RM rules gcc/ada/ChangeLog: * contracts.adb: Update SPARK RM reference numbers. * freeze.adb: Likewise. * ghost.adb: Likewise. * ghost.ads: Likewise. * sem_ch12.adb: Likewise. * sem_ch3.adb: Likewise. * sem_ch6.adb: Likewise. * sem_prag.adb: Likwise. * sem_res.adb: Likewise. Diff: --- gcc/ada/contracts.adb | 4 ++-- gcc/ada/freeze.adb| 2 +- gcc/ada/ghost.adb | 44 ++-- gcc/ada/ghost.ads | 10 +- gcc/ada/sem_ch12.adb | 10 +- gcc/ada/sem_ch3.adb | 4 ++-- gcc/ada/sem_ch6.adb | 14 +++--- gcc/ada/sem_prag.adb | 18 +- gcc/ada/sem_res.adb | 2 +- 9 files changed, 54 insertions(+), 54 deletions(-) diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb index a6862c424165..d87199939837 100644 --- a/gcc/ada/contracts.adb +++ b/gcc/ada/contracts.adb @@ -1131,12 +1131,12 @@ package body Contracts is if Comes_From_Source (Obj_Id) and then Is_Ghost_Entity (Obj_Id) then -- A Ghost object cannot be of a type that yields a synchronized - -- object (SPARK RM 6.9(21)). + -- object (SPARK RM 6.9(22)). if Yields_Synchronized_Object (Obj_Typ) then Error_Msg_N ("ghost object & cannot be synchronized", Obj_Id); - -- A Ghost object cannot be imported or exported (SPARK RM 6.9(7)). + -- A Ghost object cannot be imported or exported (SPARK RM 6.9(9)). -- One exception to this is the object that represents the dispatch -- table of a Ghost tagged type, as the symbol needs to be exported. diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index 31a583b769e8..9de4fa409c0f 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -4245,7 +4245,7 @@ package body Freeze is <> -- A Ghost type cannot have a component of protected or task type - -- (SPARK RM 6.9(21)). + -- (SPARK RM 6.9(22)). if Is_Ghost_Entity (Arr) and then Is_Concurrent_Type (Ctyp) then Error_Msg_N diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb index ef6315a7d3d5..d097c70b707f 100644 --- a/gcc/ada/ghost.adb +++ b/gcc/ada/ghost.adb @@ -226,7 +226,7 @@ package body Ghost is Policy := Ghost_Policy_In_Effect (Prev_Id); -- The Ghost policy in effect at the point of declaration and at the - -- point of completion must match (SPARK RM 6.9(16)). + -- point of completion must match (SPARK RM 6.9(19)). if Is_Checked_Ghost_Entity (Prev_Id) and then Policy = Name_Ignore @@ -260,7 +260,7 @@ package body Ghost is function Is_OK_Ghost_Context (Context : Node_Id) return Boolean; -- Determine whether node Context denotes a Ghost-friendly context where - -- a Ghost entity can safely reside (SPARK RM 6.9(10)). + -- a Ghost entity can safely reside (SPARK RM 6.9(13)). function In_Aspect_Or_Pragma_Predicate (N : Node_Id) return Boolean; -- Return True iff N is enclosed in an aspect or pragma Predicate @@ -486,8 +486,8 @@ package body Ghost is return True; -- An assertion expression pragma is Ghost when it contains a --- reference to a Ghost entity (SPARK RM 6.9(10)), except for --- predicate pragmas (SPARK RM 6.9(11)). +-- reference to a Ghost entity (SPARK RM 6.9(13)), except for +-- predicate pragmas (SPARK RM 6.9(14)). elsif Is_Valid_Assertion_Kind (Prag_Nam) and then Assertion_Expression_Pragma (Prag_Id) @@ -500,14 +500,14 @@ package body Ghost is return True; -- A pragma that applies to a Ghost construct or specifies an --- aspect of a Ghost entity is a Ghost pragma (SPARK RM 6.9(3)) +-- aspect of a Ghost entity is a Ghost pragma (SPARK RM 6.9(4)) elsif Is_Ghost_Pragma (Prag) then return True; -- Several pragmas that may apply to a non-Ghost entity are -- treated as Ghost when they contain a reference to a Ghost --- entity (SPARK RM 6.9(11)). +-- entity (SPARK RM 6.9(18)). elsif Prag_Nam in Name_Global @@ -728,11 +728,11 @@ package body Ghost is return True; -- A reference to a Ghost entity can appear within an aspect - -- specification (SPARK RM 6.9(10)). The precise checking will + -- specification (SPARK RM 6.9(13)). The precise checking will -- occur when analyzing the corresponding pragma. We make an
[gcc r16-3882] ada: Avoid ghost context errors when preanalyzing Loop_Invariant
https://gcc.gnu.org/g:e8de28890655d7766bea5263afcf9889393ea000 commit r16-3882-ge8de28890655d7766bea5263afcf9889393ea000 Author: Viljar Indus Date: Tue Sep 2 15:20:54 2025 +0300 ada: Avoid ghost context errors when preanalyzing Loop_Invariant gcc/ada/ChangeLog: * sem_prag.adb (Analyze_Pragma): Disable context checks for the preanalysis of the expression for Loop_Invariant pragmas as the ghost region for the pragma has not been set up yet. Diff: --- gcc/ada/sem_prag.adb | 6 ++ 1 file changed, 6 insertions(+) diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index b1fefa8a2972..f75f1f7eb4d1 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -14455,9 +14455,15 @@ package body Sem_Prag is -- Perform preanalysis to deal with embedded Loop_Entry -- attributes. + -- + -- But ignore the ghost context checks for now. The expression + -- will be reanalyzed with the correct ghost region once the + -- pragma has been converted to pragma check. + Ghost_Context_Checks_Disabled := True; Preanalyze_And_Resolve_Assert_Expression (Arg_Check, Any_Boolean); + Ghost_Context_Checks_Disabled := False; end if; -- Implement Assert[_And_Cut]/Assume/Loop_Invariant by generating
[gcc r16-3874] ada: Fix the condition of ghost level dependencies inside assignments
https://gcc.gnu.org/g:ff94323051f1cb875232b131fcb6a866fbf20e44 commit r16-3874-gff94323051f1cb875232b131fcb6a866fbf20e44 Author: Viljar Indus Date: Mon Sep 1 11:00:38 2025 +0300 ada: Fix the condition of ghost level dependencies inside assignments The assignee should depend on the level of all of the ghost entiies with the assignment. gcc/ada/ChangeLog: * ghost.adb (Check_Assignee_Levels): Fix the condition and improve error message handling. Diff: --- gcc/ada/ghost.adb | 13 + 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb index bfe6bff0751e..ef6315a7d3d5 100644 --- a/gcc/ada/ghost.adb +++ b/gcc/ada/ghost.adb @@ -561,22 +561,19 @@ package body Ghost is -- within an assignment statement whose target is a ghost -- variable that is assertion-level-dependent on E. - if not Is_Assertion_Level_Dependent (Id_Level, Assignee_Level) + if not Is_Assertion_Level_Dependent (Assignee_Level, Id_Level) then - Error_Msg_Sloc := Sloc (Ghost_Ref); - Error_Msg_N (Assertion_Level_Error_Msg, Ghost_Ref); Error_Msg_Name_1 := Chars (Id_Level); - Error_Msg_NE ("\& has assertion level %", Ghost_Ref, Id); + Error_Msg_N ("\& has assertion level %", Ghost_Ref); Error_Msg_Name_1 := Chars (Assignee_Level); Error_Msg_Node_2 := Assignee; - Error_Msg_NE -("\& is modifying & with %", Ghost_Ref, Id); - Error_Msg_Name_1 := Chars (Assignee_Level); + Error_Msg_NE ("\& is modifying & with %", Ghost_Ref, Id); + Error_Msg_Name_1 := Chars (Id_Level); Error_Msg_NE ("\assertion level of & should depend on %", Ghost_Ref, - Id); + Assignee); end if; end Check_Assignment_Levels;
[gcc r16-3870] ada: Fix section of Finalizable extension in GNAT RM
https://gcc.gnu.org/g:e2aab9ab8b32bdf0cb535a66e98ff3e3aad274c0 commit r16-3870-ge2aab9ab8b32bdf0cb535a66e98ff3e3aad274c0 Author: Ronan Desplanques Date: Fri May 30 11:50:09 2025 +0200 ada: Fix section of Finalizable extension in GNAT RM The generalized finalization extension was awarded the title of curated extension some time ago, but this wasn't reflected in the GNAT reference manual before this patch, which moves the documentation for generalized finalization in the curated extension section. gcc/ada/ChangeLog: * doc/gnat_rm/gnat_language_extensions.rst: Fix section of Finalizable. * gnat_rm.texi: Regenerate. * gnat_ugn.texi: Regenerate. Diff: --- gcc/ada/doc/gnat_rm/gnat_language_extensions.rst | 262 gcc/ada/gnat_rm.texi | 378 +++ gcc/ada/gnat_ugn.texi| 2 +- 3 files changed, 321 insertions(+), 321 deletions(-) diff --git a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst index c35f2b088dce..b0cd5fbfc09d 100644 --- a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst +++ b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst @@ -605,6 +605,137 @@ Here is an example of this feature: It ensures that arithmetic operations of type ``Uns_64`` are carried out using 64 bits. +Generalized Finalization + + +The ``Finalizable`` aspect can be applied to any record type, tagged or not, +to specify that it provides the same level of control on the operations of +initialization, finalization, and assignment of objects as the controlled +types (see RM 7.6(2) for a high-level overview). The only restriction is +that the record type must be a root type, in other words not a derived type. + +The aspect additionally makes it possible to specify relaxed semantics for +the finalization operations by means of the ``Relaxed_Finalization`` setting. +Here is the archetypal example: + +.. code-block:: ada + +type T is record + ... +end record + with Finalizable => (Initialize => Initialize, + Adjust => Adjust, + Finalize => Finalize, + Relaxed_Finalization => True); + +procedure Adjust (Obj : in out T); +procedure Finalize (Obj : in out T); +procedure Initialize (Obj : in out T); + +The three procedures have the same profile, with a single ``in out`` parameter, +and also have the same dynamic semantics as for controlled types: + + - ``Initialize`` is called when an object of type ``T`` is declared without + initialization expression. + + - ``Adjust`` is called after an object of type ``T`` is assigned a new value. + + - ``Finalize`` is called when an object of type ``T`` goes out of scope (for + stack-allocated objects) or is deallocated (for heap-allocated objects). + It is also called when the value is replaced by an assignment. + +However, when ``Relaxed_Finalization`` is either ``True`` or not explicitly +specified, the following differences are implemented relative to the semantics +of controlled types: + +* The compiler has permission to perform no automatic finalization of + heap-allocated objects: ``Finalize`` is only called when such an object + is explicitly deallocated, or when the designated object is assigned a new + value. As a consequence, no runtime support is needed for performing + implicit deallocation. In particular, no per-object header data is needed + for heap-allocated objects. + + Heap-allocated objects allocated through a nested access type will therefore + **not** be deallocated either. The result is simply that memory will be leaked + in this case. + +* The ``Adjust`` and ``Finalize`` procedures are automatically considered as + having the :ref:`No_Raise_Aspect` specified for them. In particular, the + compiler has permission to enforce none of the guarantees specified by the + RM 7.6.1 (14/1) and subsequent subclauses. + +Simple example of ref-counted type: + +.. code-block:: ada + + type T is record + Value : Integer; + Ref_Count : Natural := 0; + end record; + + procedure Inc_Ref (X : in out T); + procedure Dec_Ref (X : in out T); + + type T_Access is access all T; + + type T_Ref is record + Value : T_Access; + end record + with Finalizable => (Adjust => Adjust, + Finalize => Finalize); + + procedure Adjust (Ref : in out T_Ref) is + begin + Inc_Ref (Ref.Value); + end Adjust; + + procedure Finalize (Ref : in out T_Ref) is + begin + Def_Ref (Ref.Value); + end Finalize; + +Simple file handle that ensures resources are properly released: + +.. code-block:: ada + + package P is + type File (<>) is limited private; + + function Open (Path : String) return File; + + procedure Close (F :
[gcc r16-3860] ada: Fix documentation of Is_Ancestor_Package
https://gcc.gnu.org/g:78551d9e13a20a281546cdb5f6feaa336d5951bd commit r16-3860-g78551d9e13a20a281546cdb5f6feaa336d5951bd Author: Ronan Desplanques Date: Tue Aug 26 15:39:03 2025 +0200 ada: Fix documentation of Is_Ancestor_Package "Is_Ancestor_Package (E, E)" returns True and this patch fixes a comment that claimed otherwise. This patch also renames an object local to Is_Ancestor_Package that was misleadingly named "Par", a common abbreviation of "Parent". gcc/ada/ChangeLog: * sem_util.ads (Is_Ancestor_Package): Fix documentation comment. * sem_util.adb (Is_Ancestor_Package): Rename local object. Diff: --- gcc/ada/sem_util.adb | 8 gcc/ada/sem_util.ads | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 8a3998d7d123..432b036396d7 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -15991,14 +15991,14 @@ package body Sem_Util is (E1 : Entity_Id; E2 : Entity_Id) return Boolean is - Par : Entity_Id := E2; + Cursor : Entity_Id := E2; begin - while Present (Par) and then Par /= Standard_Standard loop - if Par = E1 then + while Present (Cursor) and then Cursor /= Standard_Standard loop + if Cursor = E1 then return True; end if; - Par := Scope (Par); + Cursor := Scope (Cursor); end loop; return False; diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index 04caed575065..88a1841cb389 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -1849,7 +1849,7 @@ package Sem_Util is function Is_Ancestor_Package (E1 : Entity_Id; E2 : Entity_Id) return Boolean; - -- True if package E1 is an ancestor of E2 other than E2 itself + -- True if package E1 is an ancestor of E2 function Is_Atomic_Object (N : Node_Id) return Boolean; -- Determine whether arbitrary node N denotes a reference to an atomic
[gcc r16-3867] ada: Improve ghost region creation for pragmas
https://gcc.gnu.org/g:99019f23a19baa3272ce298bab4541d875deccb8 commit r16-3867-g99019f23a19baa3272ce298bab4541d875deccb8 Author: Viljar Indus Date: Tue Aug 12 09:55:17 2025 +0300 ada: Improve ghost region creation for pragmas gcc/ada/ChangeLog: * atree.adb (Mark_New_Ghost_Node): Set Is_Implicit_Ghost for all newly created nodes. * gen_il-fields.ads (Is_Implicit_Ghost): New attribute. * gen_il-gen-gen_entities.adb (Entity_Kind): Add Is_Implicit_Ghost attribute. * ghost.adb (Ghost_Policy_In_Effect): Implicit_Ghost_Entities inside pragmas get the ghost mode from the region isntead of the global ghost policy. (Ghost_Assertion_Level_In_Effect): New function that returns the applicable assertion level for the given entity in a similar manner as Ghost_Policy_In_Effect. (Install_Ghost_Region): Set Is_Inside_Statement_Or_Pragma attribute. (Mark_And_Set_Ghost_Body): Update the logic for deriving the ghost region. (Set_Ghost_Mode): Ignored pragmas attached to checked ghost entities now create an ignored ghost region. Pragmas attached to non-ghost entities create the ghost region based on the policy applied to the given pragma. * opt.ads (Ghost_Config_Type): add new attribute Is_Inside_Statement_Or_Pragama to track whether we should take the active ghost mode from the ghost region for implicit ghost entities. * sem_prag.adb (Analyze_Pragma): Mark entities that have an explicit ghost pragma as non-implicit ghost. Diff: --- gcc/ada/atree.adb | 2 + gcc/ada/gen_il-fields.ads | 1 + gcc/ada/gen_il-gen-gen_entities.adb | 1 + gcc/ada/ghost.adb | 138 +--- gcc/ada/opt.ads | 6 ++ gcc/ada/sem_prag.adb| 1 + 6 files changed, 106 insertions(+), 43 deletions(-) diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb index 197d1ee51210..14d9ba4bb2fd 100644 --- a/gcc/ada/atree.adb +++ b/gcc/ada/atree.adb @@ -1807,6 +1807,7 @@ package body Atree is Set_Is_Checked_Ghost_Entity (N); Set_Ghost_Assertion_Level (N, Ghost_Config.Ghost_Mode_Assertion_Level); +Set_Is_Implicit_Ghost (N); end if; elsif Ghost_Config.Ghost_Mode = Ignore then @@ -1814,6 +1815,7 @@ package body Atree is Set_Is_Ignored_Ghost_Entity (N); Set_Ghost_Assertion_Level (N, Ghost_Config.Ghost_Mode_Assertion_Level); +Set_Is_Implicit_Ghost (N); end if; Set_Is_Ignored_Ghost_Node (N); diff --git a/gcc/ada/gen_il-fields.ads b/gcc/ada/gen_il-fields.ads index c9f9bc2c5ba6..6ff9866e6431 100644 --- a/gcc/ada/gen_il-fields.ads +++ b/gcc/ada/gen_il-fields.ads @@ -743,6 +743,7 @@ package Gen_IL.Fields is Is_Immediately_Visible, Is_Implementation_Defined, Is_Implicit_Full_View, + Is_Implicit_Ghost, Is_Imported, Is_Independent, Is_Initial_Condition_Procedure, diff --git a/gcc/ada/gen_il-gen-gen_entities.adb b/gcc/ada/gen_il-gen-gen_entities.adb index dd07b7a6e6e5..476e69d22cc0 100644 --- a/gcc/ada/gen_il-gen-gen_entities.adb +++ b/gcc/ada/gen_il-gen-gen_entities.adb @@ -159,6 +159,7 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Is_Ignored_Ghost_Entity, Flag), Sm (Is_Immediately_Visible, Flag), Sm (Is_Implementation_Defined, Flag), +Sm (Is_Implicit_Ghost, Flag), Sm (Is_Imported, Flag), Sm (Is_Independent, Flag), Sm (Is_Inlined, Flag), diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb index ae20ef972c82..bfe6bff0751e 100644 --- a/gcc/ada/ghost.adb +++ b/gcc/ada/ghost.adb @@ -94,15 +94,30 @@ package body Ghost is -- Returns the Assertion_Level entity if the node has a Ghost aspect and -- the Ghost aspect is using an Assertion_Level. + function Ghost_Assertion_Level_In_Effect (Id : Entity_Id) return Entity_Id; + -- Returns the ghost level applicable for the given entity Id in a similar + -- manner as Ghost_Policy_In_Effect. + function Ghost_Policy_In_Effect (Id : Entity_Id) return Name_Id; - -- Returns the first Assertion Policy in place for either Ghost or the - -- Assertion_Level associated with Ghost aspect on the the declaration node - -- Decl. + -- Returns the ghost policy applicable for the given entity Id. + -- + -- SPARK RM 6.9 (3): + -- + -- An object declaration which occurs inside an expression in a ghost + -- declaration, statement, assertion pragma or specification aspect + -- declaration is a ghost declaration. + -- + -- If this declaration does not have the Ghost aspect specified, the + -- assertion policy applicable to this declaration comes from the po
[gcc r16-3861] ada: Disable ghost context checks before context is set
https://gcc.gnu.org/g:33876c5ea8b671f1d79177a4d577897f4a546e69 commit r16-3861-g33876c5ea8b671f1d79177a4d577897f4a546e69 Author: Viljar Indus Date: Wed Aug 27 10:54:05 2025 +0300 ada: Disable ghost context checks before context is set There are cases where we need to analyze the argument of the pragma in order to determine the ghostliness of the pragma. However during that analysis the ghost region of the pragma is not set yet so we cannot perform the ghost context checks at that moment. This patch provides the mechanism for disabling ghost context checks and disables them for pragma arguments that determine the ghostliness of the pragma. gcc/ada/ChangeLog: * ghost.adb (Check_Ghost_Context): Avoid context checks when they are globally disabled. * sem.ads (Ghost_Context_Checks_Disabled): New flag to control whether ghost context checks are activated or not. * sem_prag.adb (Analyze_Pragma): Disable ghost context checks for pragmas that determine their ghostliness based on one of its arguments. Diff: --- gcc/ada/ghost.adb| 4 gcc/ada/sem.ads | 12 gcc/ada/sem_prag.adb | 39 +++ 3 files changed, 55 insertions(+) diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb index 4f1a0d9d6a46..ae20ef972c82 100644 --- a/gcc/ada/ghost.adb +++ b/gcc/ada/ghost.adb @@ -932,6 +932,10 @@ package body Ghost is -- Start of processing for Check_Ghost_Context begin + if Ghost_Context_Checks_Disabled then + return; + end if; + -- Class-wide pre/postconditions of ignored pragmas are preanalyzed -- to report errors on wrong conditions; however, ignored pragmas may -- also have references to ghost entities and we must disable checking diff --git a/gcc/ada/sem.ads b/gcc/ada/sem.ads index 611309775279..63cf1daad37d 100644 --- a/gcc/ada/sem.ads +++ b/gcc/ada/sem.ads @@ -307,6 +307,18 @@ package Sem is -- case. We could perhaps do a more accurate job and retain some of the -- warnings, but it is quite a tricky job. + Ghost_Context_Checks_Disabled : Boolean := False; + -- This flag controls whether ghost context related checks are enabled or + -- disabled. Typically they are enabled however they need to be disabled in + -- instances where the ghost region context has not been set. + -- + -- Typically this is done for pragmas where the ghostliness of the pragma + -- is determined by an entity specified as one of the arguments. In these + -- cases we need to analyze that argument before the pragma itself to + -- determine the ghostliness of the pragma. However at that point we have + -- not set the ghost region for the pragma in order to determine the ghost + -- context of the argument. + --- -- Handling of Check Suppression -- --- diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index 661d4401d7a2..00c9b17ff6ee 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -6439,7 +6439,14 @@ package body Sem_Prag is end if; end if; + -- We are going to check the entity that determines the ghost + -- region of that pragma. We need to disable the checks for ghost + -- context since the ghost region can only be set after analyzing + -- this entity. + + Ghost_Context_Checks_Disabled := True; Analyze (Argx); + Ghost_Context_Checks_Disabled := False; if Nkind (Argx) not in N_Direct_Name and then (Nkind (Argx) /= N_Attribute_Reference @@ -9221,8 +9228,15 @@ package body Sem_Prag is Check_Optional_Identifier (Arg2, Name_Entity); Check_Arg_Is_Local_Name (Arg2); + -- We are going to check the entity that determines the ghost + -- region of that pragma. We need to disable the checks for ghost + -- context since the ghost region can only be set after analyzing + -- this entity. + + Ghost_Context_Checks_Disabled := True; Id := Get_Pragma_Arg (Arg2); Analyze (Id); + Ghost_Context_Checks_Disabled := False; if not Is_Entity_Name (Id) then Error_Pragma_Arg ("entity name required", Arg2); @@ -12022,7 +12036,15 @@ package body Sem_Prag is Check_Optional_Identifier (Arg2, Name_On); E_Id := Get_Pragma_Arg (Arg2); + +-- We are going to check the entity that determines the ghost +-- region of that pragma. We need to disable the checks for ghost +-- context since the ghost region can only be set after analyzing +-- this entity. + +Ghost_Context_Checks_Disabled := True; Analyze (E_Id); +Ghost_Context_Checks_Disabled := False; if not Is_
[gcc r16-3875] ada: Refactor ghost argument consistency checks
https://gcc.gnu.org/g:6657536db098d5c388df84162e1f92d159f6f451 commit r16-3875-g6657536db098d5c388df84162e1f92d159f6f451 Author: Viljar Indus Date: Fri Aug 29 15:09:24 2025 +0300 ada: Refactor ghost argument consistency checks Create a new method for checking and emitting errors on pragmas Unused, Unrefefrenced, Unreferenced_Objects, Inline and No_Return that support specifying multiple entities as arguments. Emit an error when one argument is ghost and the other is not and when one argument has a ghost policy check and the other has ghost policy ignore. Update the Suppressed_Ghost_Policy_Check_Pragma list pragma Inline that should be there to avoid an incorrect invalid pragma context error. gcc/ada/ChangeLog: * sem_prag.adb (Check_Inconsistent_Argument_Ghostliness): new method for handling the ghost constency errors between different arguments. Use this method in the processing for pragmas Unused, Unrefefrenced, Unreferenced_Objects, Inline and No_Return. * sem_prag.ads (Suppressed_Ghost_Policy_Check_Pragma): add missing entry for pragma Inline. Diff: --- gcc/ada/sem_prag.adb | 329 ++- gcc/ada/sem_prag.ads | 1 + 2 files changed, 172 insertions(+), 158 deletions(-) diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index a17d9d2b8138..9289e02b56ad 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -5054,6 +5054,16 @@ package body Sem_Prag is -- Common checks for pragmas that appear within a main program -- (Priority, Main_Storage, Time_Slice, Relative_Deadline, CPU). + procedure Check_Inconsistent_Argument_Ghostliness +(Arg1 : Entity_Id; + Arg2 : Entity_Id; + Ghost_Error_Posted : in out Boolean); + -- Reports an error and sets Ghost_Error_Posted when: + -- * One argument is ghost and the other is not ghost + -- * One argument is checked ghost and the other is ignored ghost + -- + -- Checks are avoided when Ghost_Error_Posted is already set. + procedure Check_Interrupt_Or_Attach_Handler; -- Common processing for first argument of pragma Interrupt_Handler or -- pragma Attach_Handler. @@ -6033,9 +6043,10 @@ package body Sem_Prag is -- Flag set when an error concerning the illegal mix of Ghost and -- non-Ghost variables is emitted. - Ghost_Id : Entity_Id := Empty; - -- The entity of the first Ghost variable encountered while - -- processing the arguments of the pragma. + First_Arg_Id : Entity_Id := Empty; + -- The entity of the first variable encountered while processing the + -- arguments of the pragma. This is used as a reference for assessing + -- the ghostliness of other arguments. begin GNAT_Pragma; @@ -6073,41 +6084,22 @@ package body Sem_Prag is Set_Has_Pragma_Unused (Arg_Id); end if; - -- A pragma that applies to a Ghost entity becomes Ghost for - -- the purposes of legality checks and removal of ignored - -- Ghost code. - - Mark_Ghost_Pragma (N, Arg_Id); - - -- Capture the entity of the first Ghost variable being + -- Capture the entity of the first variable being -- processed for error detection purposes. - if Is_Ghost_Entity (Arg_Id) then - if No (Ghost_Id) then -Ghost_Id := Arg_Id; - end if; - - -- Otherwise the variable is non-Ghost. It is illegal to mix - -- references to Ghost and non-Ghost entities - -- (SPARK RM 6.9). - - elsif Present (Ghost_Id) -and then not Ghost_Error_Posted - then - Ghost_Error_Posted := True; - - Error_Msg_Name_1 := Pname; - Error_Msg_N - ("pragma % cannot mention ghost and non-ghost " -& "variables", N); + if No (First_Arg_Id) then + First_Arg_Id := Arg_Id; - Error_Msg_Sloc := Sloc (Ghost_Id); - Error_Msg_NE ("\& # declared as ghost", N, Ghost_Id); + -- A pragma that applies to a Ghost entity becomes Ghost + -- for the purposes of legality checks and removal of + -- ignored Ghost code. - Error_Msg_Sloc := Sloc (Arg_Id); - Error_Msg_NE ("\& # declared as non-ghost", N, Arg_Id); + Mark_Ghost_Pragma (N, Arg_Id); end if; + C
[gcc r16-3879] ada: Add Assertion_Policy checks for assertion levels
https://gcc.gnu.org/g:33f64b23787acff88f0970715342fa8e797016c5 commit r16-3879-g33f64b23787acff88f0970715342fa8e797016c5 Author: Viljar Indus Date: Tue Sep 2 13:11:30 2025 +0300 ada: Add Assertion_Policy checks for assertion levels Implement SPARK RM 6.9(19) check: An Assertion_Policy pragma specifying an Assertion_Level policy shall not occur within a ghost subprogram or package associated to an assertion level which depends on this level. gcc/ada/ChangeLog: * sem_prag.adb (Analyze_Pragma): Add ghost level check to Assertion_Policy. Diff: --- gcc/ada/sem_prag.adb | 16 1 file changed, 16 insertions(+) diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index 9175490eca27..172dc3d6f3ec 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -14845,6 +14845,22 @@ package body Sem_Prag is ("invalid assertion kind for pragma%", Arg); end if; + + -- An Assertion_Policy pragma specifying an + -- Assertion_Level policy shall not occur within a ghost + -- subprogram or package associated to an assertion level + -- which depends on this level (SPARK RM 6.9(19)). + + if Ghost_Config.Ghost_Mode > None + and then Is_Same_Or_Depends_On_Level + (Ghost_Config.Ghost_Mode_Assertion_Level, + Level) + then +Error_Msg_Name_2 := Chars (Level); +Error_Pragma + ("pragma % cannot appear within ghost subprogram or " + & "package that depends on %"); + end if; end if; Check_Arg_Is_One_Of (Arg, Policy_Names);
[gcc r16-3884] ada: Fix wrong finalization of aliased array of bounded vector
https://gcc.gnu.org/g:10cddb6ca47def63d7ab86678082ff09416f2812 commit r16-3884-g10cddb6ca47def63d7ab86678082ff09416f2812 Author: Eric Botcazou Date: Wed Sep 3 09:17:39 2025 +0200 ada: Fix wrong finalization of aliased array of bounded vector The problem is that Apply_Discriminant_Check introduces an unnecessary temporary for an assignment where both sides have the same constrained subtype but the left-hand side is an aliased component. This comes from an approximation in the implementation introduced long time ago to deal with aliased unconstrained objects in Ada 95, more specifically to still generate a check when both sides have the same unconstrained subtype in this case; it is replaced by an explicit test that the common subtype is constrained. gcc/ada/ChangeLog: * checks.adb (Apply_Discriminant_Check): Remove undocumented test on Is_Aliased_View applied to the left-hand side to skip the check in the case where the subtypes are the same, and replace it with a test that the subtypes are constrained. Diff: --- gcc/ada/checks.adb | 15 ++- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb index a9bebee3e139..c30e5f1bf199 100644 --- a/gcc/ada/checks.adb +++ b/gcc/ada/checks.adb @@ -1585,21 +1585,18 @@ package body Checks is return; end if; - -- Suppress checks if the subtypes are the same. The check must be - -- preserved in an assignment to a formal, because the constraint is - -- given by the actual. + -- Suppress checks if the subtypes are the same and constrained. The + -- check must be preserved in an assignment to a formal, because the + -- constraint is given by the actual. if Nkind (Original_Node (N)) /= N_Allocator +and then (if Do_Access then Designated_Type (Typ) else Typ) = S_Typ +and then Is_Constrained (S_Typ) and then (No (Lhs) or else not Is_Entity_Name (Lhs) or else No (Param_Entity (Lhs))) then - if (Etype (N) = Typ - or else (Do_Access and then Designated_Type (Typ) = S_Typ)) - and then (No (Lhs) or else not Is_Aliased_View (Lhs)) - then -return; - end if; + return; -- We can also eliminate checks on allocators with a subtype mark that -- coincides with the context type. The context type may be a subtype
[gcc r16-3886] ada: Fix internal error on aspect in complex object declaration
https://gcc.gnu.org/g:de0ae1b5103293bc07f35964c2b7da5edbe7eb3c commit r16-3886-gde0ae1b5103293bc07f35964c2b7da5edbe7eb3c Author: Eric Botcazou Date: Fri Aug 22 14:51:58 2025 +0200 ada: Fix internal error on aspect in complex object declaration The sufficient conditions are that the aspect be deferred and the object be rewritten as a renaming because of the complex initialization expression. gcc/ada/ChangeLog: * gcc-interface/trans.cc (gnat_to_gnu) : Deal with objects whose elaboration is deferred. (process_freeze_entity): Deal with renamed objects whose elaboration is deferred. Diff: --- gcc/ada/gcc-interface/trans.cc | 30 -- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc index e8baa5ca55cd..ea083f79a084 100644 --- a/gcc/ada/gcc-interface/trans.cc +++ b/gcc/ada/gcc-interface/trans.cc @@ -6893,9 +6893,22 @@ gnat_to_gnu (Node_Id gnat_node) && (Is_Array_Type (Etype (gnat_temp)) || Is_Record_Type (Etype (gnat_temp)) || Is_Concurrent_Type (Etype (gnat_temp) - gnat_to_gnu_entity (gnat_temp, - gnat_to_gnu (Renamed_Object (gnat_temp)), - true); + { + gnu_expr = gnat_to_gnu (Renamed_Object (gnat_temp)); + + /* The elaboration of object renamings present in the source code +never needs to be deferred. But regular objects may be turned +into renamings during expansion and their elaboration may need +to be deferred, in which case we expect the renamed references +to have been stabilized, so we do not do it again here. */ + if (Present (Freeze_Node (gnat_temp))) + { + gcc_assert (!Comes_From_Source (gnat_node)); + save_gnu_tree (gnat_node, gnu_expr, true); + } + else + gnat_to_gnu_entity (gnat_temp, gnu_expr, true); + } break; case N_Exception_Renaming_Declaration: @@ -9818,10 +9831,15 @@ process_freeze_entity (Node_Id gnat_node) } else { + /* For an object whose elaboration is deferred, the GCC tree of the +declaration, if any, is the initialization expression. */ + const Node_Id gnat_decl = Declaration_Node (gnat_entity); tree gnu_init - = (Nkind (Declaration_Node (gnat_entity)) == N_Object_Declaration - && present_gnu_tree (Declaration_Node (gnat_entity))) - ? get_gnu_tree (Declaration_Node (gnat_entity)) : NULL_TREE; + = (Nkind (gnat_decl) == N_Object_Declaration + || Nkind (gnat_decl) == N_Object_Renaming_Declaration) + && Present (Freeze_Node (gnat_entity)) + && present_gnu_tree (gnat_decl) + ? get_gnu_tree (gnat_decl) : NULL_TREE; gnu_new = gnat_to_gnu_entity (gnat_entity, gnu_init, true); }
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: Sauvegarde
https://gcc.gnu.org/g:f4f692cbe2df5eada3106860109835a6ea68c1ba commit f4f692cbe2df5eada3106860109835a6ea68c1ba Author: Mikael Morin Date: Thu Sep 4 17:10:58 2025 +0200 gimple-simulate: Sauvegarde Diff: --- gcc/gimple-simulate.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc index 721d34bea9aa..adf02ed29610 100644 --- a/gcc/gimple-simulate.cc +++ b/gcc/gimple-simulate.cc @@ -890,7 +890,8 @@ pick_subref_at (tree var_ref, unsigned min_offset, else { unsigned field_width = get_constant_type_size (field_type); - gcc_assert (field_width >= min_size); + if (field_width < min_size) + break; } ref = build3 (COMPONENT_REF, field_type,
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] gimple-simulate: Correction assertion évaluation LSHIFT_EXPR et RSHIFT_EXPR
https://gcc.gnu.org/g:4425aca695b084e862b9ecdeaaf0e3725d2b480a commit 4425aca695b084e862b9ecdeaaf0e3725d2b480a Author: Mikael Morin Date: Fri Aug 29 10:14:50 2025 +0200 gimple-simulate: Correction assertion évaluation LSHIFT_EXPR et RSHIFT_EXPR Diff: --- gcc/gimple-simulate.cc | 41 - 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc index 4fc64d342089..0951731a1d2c 100644 --- a/gcc/gimple-simulate.cc +++ b/gcc/gimple-simulate.cc @@ -2105,7 +2105,9 @@ simul_scope::evaluate_binary (enum tree_code code, tree type, tree lhs, && TYPE_PRECISION (TREE_TYPE (lhs)) == TYPE_PRECISION (TREE_TYPE (rhs)) && TYPE_UNSIGNED (TREE_TYPE (lhs)) -== TYPE_UNSIGNED (TREE_TYPE (rhs; +== TYPE_UNSIGNED (TREE_TYPE (rhs))) + || code == LSHIFT_EXPR + || code == RSHIFT_EXPR); tree lval = val_lhs.to_tree (TREE_TYPE (lhs)); tree rval = val_rhs.to_tree (TREE_TYPE (rhs)); tree t = fold_binary (code, type, lval, rval); @@ -5723,6 +5725,43 @@ simul_scope_evaluate_binary_tests () wide_int wi_ne5 = val_ne5.get_known (); ASSERT_PRED1 (wi::fits_uhwi_p, wi_ne5); ASSERT_EQ (wi_ne5.to_uhwi (), 1); + + + tree l6 = create_var (long_integer_type_node, "l6"); + + vec decls6{}; + decls6.safe_push (l6); + + context_builder builder6 {}; + builder6.add_decls (&decls6); + simul_scope ctx6 = builder6.build (mem, printer); + + wide_int wi11_6 = wi::shwi (11, TYPE_PRECISION (long_integer_type_node)); + data_value cst11_6 (long_integer_type_node); + cst11_6.set_known (wi11_6); + data_storage *strg_l6 = ctx6.find_reachable_var (l6); + gcc_assert (strg_l6 != nullptr); + strg_l6->set (cst11_6); + + tree int3 = build_int_cst (integer_type_node, 3); + data_value lshift_6 = ctx6.evaluate_binary (LSHIFT_EXPR, + long_integer_type_node, + l6, int3); + + ASSERT_EQ (lshift_6.classify (), VAL_KNOWN); + wide_int wi_lshift6 = lshift_6.get_known (); + ASSERT_PRED1 (wi::fits_shwi_p, wi_lshift6); + ASSERT_EQ (wi_lshift6.to_shwi (), 88); + + tree int1 = build_int_cst (integer_type_node, 1); + data_value rshift_6 = ctx6.evaluate_binary (RSHIFT_EXPR, + long_integer_type_node, + l6, int1); + + ASSERT_EQ (rshift_6.classify (), VAL_KNOWN); + wide_int wi_rshift6 = rshift_6.get_known (); + ASSERT_PRED1 (wi::fits_shwi_p, wi_rshift6); + ASSERT_EQ (wi_rshift6.to_shwi (), 5); }
[gcc r16-3871] ada: Fix missing finalization for qualified expression in conditional expression
https://gcc.gnu.org/g:c7ef48f2be5aa75ba9108ef1f6ac3a3206a14c9f commit r16-3871-gc7ef48f2be5aa75ba9108ef1f6ac3a3206a14c9f Author: Eric Botcazou Date: Wed Aug 27 00:16:48 2025 +0200 ada: Fix missing finalization for qualified expression in conditional expression A qualified expression around a function call may cause a temporary to be created and, therefore, cannot be bypassed in Expand_Ctrl_Function_Call. gcc/ada/ChangeLog: * exp_util.ads (Unqualified_Unconditional_Parent): New function. * exp_util.adb (Unconditional_Parent): Do not look through qualified expressions. (Unqualified_Unconditional_Parent): New function identical to the original Unconditional_Parent. * exp_aggr.adb (Convert_To_Assignments): Replace Unconditional_Parent with Unqualified_Unconditional_Parent. (Expand_Array_Aggregate): Likewse. * exp_ch4.adb (Expand_N_Case_Expression): Likewise. (Expand_N_If_Expression): Likewise. * exp_ch6.adb (Expand_Ctrl_Function_Call): Do not bypass an enclosing qualified expression in the parent chain. Diff: --- gcc/ada/exp_aggr.adb | 4 ++-- gcc/ada/exp_ch4.adb | 6 -- gcc/ada/exp_ch6.adb | 5 - gcc/ada/exp_util.adb | 33 - gcc/ada/exp_util.ads | 4 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index 6b4f4a19d1f9..d62b7351e862 100644 --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -4283,7 +4283,7 @@ package body Exp_Aggr is -- Set the Expansion_Delayed flag in the cases where the transformation -- will be done top down from above. - Parent_Node := Unconditional_Parent (N); + Parent_Node := Unqualified_Unconditional_Parent (N); if -- Internal aggregates (transformed when expanding the parent), @@ -6254,7 +6254,7 @@ package body Exp_Aggr is -- Set the Expansion_Delayed flag in the cases where the transformation -- will be done top down from above. - Parent_Node := Unconditional_Parent (N); + Parent_Node := Unqualified_Unconditional_Parent (N); if -- Internal aggregates (transformed when expanding the parent), diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index 23a59de6f872..8fba1c4e71fa 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -5198,7 +5198,8 @@ package body Exp_Ch4 is if not Expansion_Delayed (N) then declare -Uncond_Par : constant Node_Id := Unconditional_Parent (N); +Uncond_Par : constant Node_Id := + Unqualified_Unconditional_Parent (N); begin if Nkind (Uncond_Par) = N_Simple_Return_Statement or else Is_Optimizable_Declaration (Uncond_Par) @@ -5807,7 +5808,8 @@ package body Exp_Ch4 is if not Expansion_Delayed (N) then declare -Uncond_Par : constant Node_Id := Unconditional_Parent (N); +Uncond_Par : constant Node_Id := + Unqualified_Unconditional_Parent (N); begin if Nkind (Uncond_Par) = N_Simple_Return_Statement or else Is_Optimizable_Declaration (Uncond_Par) diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index 32e96bed2349..5056b1f990fa 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -5793,11 +5793,14 @@ package body Exp_Ch6 is is Par: constant Node_Id := Parent (N); Uncond_Par : constant Node_Id := Unconditional_Parent (N); + -- Beware that a qualified expression around a function call cannot be + -- considered as transparent (like around an aggregate) because it may + -- cause a temporary to be created. begin -- Optimization: if the returned value is returned again, then no need -- to copy/readjust/finalize, we can just pass the value through (see - -- Expand_N_Simple_Return_Statement), and thus no attachment is needed. + -- Expand_Simple_Function_Return), and thus no attachment is needed. -- Note that simple return statements are distributed into conditional -- expressions, but we may be invoked before this distribution is done. diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index 6ce6c0cd81d6..4135e24424d3 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -14903,6 +14903,37 @@ package body Exp_Util is Node: Node_Id := N; Parent_Node : Node_Id := Parent (Node); + begin + loop + case Nkind (Parent_Node) is +when N_Case_Expression_Alternative => + null; + +when N_Case_Expression => + exit when Node = Expression (Parent_Node); + +when N_If_Expression => + exit when Node = First (Expressions (Parent_Node)); + +
[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction fonction gfc_nullify_descriptor
https://gcc.gnu.org/g:9adca0663067add718969f5a440afabb1d593255 commit 9adca0663067add718969f5a440afabb1d593255 Author: Mikael Morin Date: Wed Jul 16 16:49:28 2025 +0200 Extraction fonction gfc_nullify_descriptor Diff: --- gcc/fortran/trans-descriptor.cc | 8 gcc/fortran/trans-descriptor.h | 3 +++ gcc/fortran/trans-expr.cc | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 76997a28f0bb..434091d399e9 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "trans.h" #include "trans-const.h" #include "trans-types.h" +#include "trans-array.h" /**/ @@ -685,3 +686,10 @@ gfc_conv_descriptor_cosize (tree desc, int rank, int corank) { return gfc_conv_descriptor_size_1 (desc, rank, rank + corank - 1); } + + +void +gfc_nullify_descriptor (stmtblock_t *block, tree descr) +{ + gfc_conv_descriptor_data_set (block, descr, null_pointer_node); +} diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index c035ec638edd..2328d0dad6f6 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -96,4 +96,7 @@ gfc_get_descriptor_offsets_for_info (const_tree desc_type, tree *data_off, tree *stride_suboff, tree *lower_suboff, tree *upper_suboff); +/* Build a null array descriptor constructor. */ +void gfc_nullify_descriptor (stmtblock_t *block, tree); + #endif /* GFC_TRANS_DESCRIPTOR_H */ diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 251a9b430cfa..f129b9e4d0c5 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -11101,7 +11101,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) if (expr2->expr_type == EXPR_NULL) { /* Just set the data pointer to null. */ - gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node); + gfc_nullify_descriptor (&lse.pre, lse.expr); } else if (rank_remap) {
[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 r15-10326] AVR: Support AVR32EB14/20/28/32.
https://gcc.gnu.org/g:f0767ec84b4381fb22b6226acb76bbd9bbd18d6f commit r15-10326-gf0767ec84b4381fb22b6226acb76bbd9bbd18d6f Author: Georg-Johann Lay Date: Mon Sep 15 14:20:59 2025 +0200 AVR: Support AVR32EB14/20/28/32. Add support for some recent AVR devices. gcc/ * config/avr/avr-mcus.def: Add avr32eb14, avr32eb20, avr32eb28, avr32eb32. * doc/avr-mmcu.texi: Rebuild. (cherry picked from commit 45f605a74fd7e96294477db064cc58033c3fba49) Diff: --- gcc/config/avr/avr-mcus.def | 4 gcc/doc/avr-mmcu.texi | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gcc/config/avr/avr-mcus.def b/gcc/config/avr/avr-mcus.def index 2e7c8ac736e8..896623d039e3 100644 --- a/gcc/config/avr/avr-mcus.def +++ b/gcc/config/avr/avr-mcus.def @@ -411,6 +411,10 @@ AVR_MCU ("avr16eb14",ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR AVR_MCU ("avr16eb20",ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR16EB20__", 0x7800, 0x0, 0x4000, 0x8000) AVR_MCU ("avr16eb28",ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR16EB28__", 0x7800, 0x0, 0x4000, 0x8000) AVR_MCU ("avr16eb32",ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR16EB32__", 0x7800, 0x0, 0x4000, 0x8000) +AVR_MCU ("avr32eb14",ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32EB14__", 0x7400, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32eb20",ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32EB20__", 0x7400, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32eb28",ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32EB28__", 0x7400, 0x0, 0x8000, 0x8000) +AVR_MCU ("avr32eb32",ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR32EB32__", 0x7400, 0x0, 0x8000, 0x8000) AVR_MCU ("avr16ea28",ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR16EA28__", 0x7800, 0x0, 0x4000, 0x8000) AVR_MCU ("avr16ea32",ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR16EA32__", 0x7800, 0x0, 0x4000, 0x8000) AVR_MCU ("avr16ea48",ARCH_AVRXMEGA3, AVR_CVT, "__AVR_AVR16EA48__", 0x7800, 0x0, 0x4000, 0x8000) diff --git a/gcc/doc/avr-mmcu.texi b/gcc/doc/avr-mmcu.texi index 5efcc8198808..1938994d74f9 100644 --- a/gcc/doc/avr-mmcu.texi +++ b/gcc/doc/avr-mmcu.texi @@ -54,7 +54,7 @@ @item @anchor{avrxmega3}avrxmega3 ``XMEGA'' devices with up to 64@tie{}KiB of combined program memory and RAM, and with program memory visible in the RAM address space. -@*@var{mcu}@tie{}= @code{attiny202}, @code{attiny204}, @code{attiny212}, @code{attiny214}, @code{attiny402}, @code{attiny404}, @code{attiny406}, @code{attiny412}, @code{attiny414}, @code{attiny416}, @code{attiny416auto}, @code{attiny417}, @code{attiny424}, @code{attiny426}, @code{attiny427}, @code{attiny804}, @code{attiny806}, @code{attiny807}, @code{attiny814}, @code{attiny816}, @code{attiny817}, @code{attiny824}, @code{attiny826}, @code{attiny827}, @code{attiny1604}, @code{attiny1606}, @code{attiny1607}, @code{attiny1614}, @code{attiny1616}, @code{attiny1617}, @code{attiny1624}, @code{attiny1626}, @code{attiny1627}, @code{attiny3214}, @code{attiny3216}, @code{attiny3217}, @code{attiny3224}, @code{attiny3226}, @code{attiny3227}, @code{atmega808}, @code{atmega809}, @code{atmega1608}, @code{atmega1609}, @code{atmega3208}, @code{atmega3209}, @code{atmega4808}, @code{atmega4809}, @code{avr16dd14}, @code{avr16dd20}, @code{avr16dd28}, @code{avr16dd32}, @code{avr16du14}, @code{avr16du20}, @code{avr16du28}, @code{avr16du32}, @code{avr16ea28}, @code{avr16ea32}, @code{avr16ea48}, @code{avr16eb14}, @code{avr16eb20}, @code{avr16eb28}, @code{avr16eb32}, @code{avr32da28}, @code{avr32da28s}, @code{avr32da32}, @code{avr32da32s}, @code{avr32da48}, @code{avr32da48s}, @code{avr32db28}, @code{avr32db32}, @code{avr32db48}, @code{avr32dd14}, @code{avr32dd20}, @code{avr32dd28}, @code{avr32dd32}, @code{avr32du14}, @code{avr32du20}, @code{avr32du28}, @code{avr32du32}, @code{avr32ea28}, @code{avr32ea32}, @code{avr32ea48}, @code{avr32sd20}, @code{avr32sd28}, @code{avr32sd32}. +@*@var{mcu}@tie{}= @code{attiny202}, @code{attiny204}, @code{attiny212}, @code{attiny214}, @code{attiny402}, @code{attiny404}, @code{attiny406}, @code{attiny412}, @code{attiny414}, @code{attiny416}, @code{attiny416auto}, @code{attiny417}, @code{attiny424}, @code{attiny426}, @code{attiny427}, @code{attiny804}, @code{attiny806}, @code{attiny807}, @code{attiny814}, @code{attiny816}, @code{attiny817}, @code{attiny824}, @code{attiny826}, @code{attiny827}, @code{attiny1604}, @code{attiny1606}, @code{attiny1607}, @code{attiny1614}, @code{attiny1616}, @code{attiny1617}, @code{attiny1624}, @code{attiny1626}, @code{attiny1627}, @code{attiny3214}, @code{attiny3216}, @code{attiny3217}, @code{attiny3224}, @code{attiny3226}, @code{attiny3227}, @code{atmega808}, @code{atmega809}, @code{atmega1608}, @code{atmega1609}, @code{atmega3208}, @code{atmega3209}, @code{atmega4808}, @co
[gcc r16-3859] match.pd: Add missing type check to reduc(ctor) pattern [PR121772]
https://gcc.gnu.org/g:a7a9b7badc0ba95b510c7e61da6439fca78e31d3 commit r16-3859-ga7a9b7badc0ba95b510c7e61da6439fca78e31d3 Author: Alex Coplan Date: Tue Sep 9 12:57:14 2025 +0100 match.pd: Add missing type check to reduc(ctor) pattern [PR121772] In this PR we have a reduction of a vector constructor, where the type of the constructor is int16x8_t and the elements are int16x4_t; i.e. it is representing a concatenation of two vectors. This triggers a match.pd pattern which looks like it was written to handle reductions of vector constructors where the elements of the ctor are scalars, not vectors. There is no type check to enforce this property, which leads to the pattern replacing a reduction to scalar with an int16x4_t vector in this case, which of course is a type error, leading to an invalid GIMPLE ICE. This patch adds a type check to the pattern, only going ahead with the transformation if the element type of the ctor matches that of the reduction. gcc/ChangeLog: PR tree-optimization/121772 * match.pd: Add type check to reduc(ctor) pattern. gcc/testsuite/ChangeLog: PR tree-optimization/121772 * gcc.target/aarch64/torture/pr121772.c: New test. Diff: --- gcc/match.pd| 1 + gcc/testsuite/gcc.target/aarch64/torture/pr121772.c | 5 + 2 files changed, 6 insertions(+) diff --git a/gcc/match.pd b/gcc/match.pd index dbbb7b512754..8107ee6ec83c 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -11085,6 +11085,7 @@ and, ? gimple_assign_rhs1 (SSA_NAME_DEF_STMT (@0)) : @0); tree elt = ctor_single_nonzero_element (ctor); } (if (elt + && types_match (type, TREE_TYPE (elt)) && !HONOR_SNANS (type) && !HONOR_SIGNED_ZEROS (type)) { elt; } diff --git a/gcc/testsuite/gcc.target/aarch64/torture/pr121772.c b/gcc/testsuite/gcc.target/aarch64/torture/pr121772.c new file mode 100644 index ..3b4cf4d7d189 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/torture/pr121772.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +#include +int16_t f(int16x4_t b) { + return vaddvq_s16(vcombine_s16(b, vdup_n_s16 (0))); +}
[gcc r13-9886] c++: Fix mangling of _Float16 template args [PR121801]
https://gcc.gnu.org/g:19dd22fc18efe6b50188638582cd418e1c301a15 commit r13-9886-g19dd22fc18efe6b50188638582cd418e1c301a15 Author: Matthias Kretz Date: Fri Sep 5 12:16:34 2025 +0200 c++: Fix mangling of _Float16 template args [PR121801] Signed-off-by: Matthias Kretz gcc/testsuite/ChangeLog: PR c++/121801 * g++.dg/abi/pr121801.C: New test. gcc/cp/ChangeLog: PR c++/121801 * mangle.cc (write_real_cst): Handle 16-bit real and assert that reals have 16 bits or a multiple of 32 bits. (cherry picked from commit 19d1c7c28f4fd0557dd868a7a4041b00ceada890) Diff: --- gcc/cp/mangle.cc| 15 ++- gcc/testsuite/g++.dg/abi/pr121801.C | 13 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index 7076608dc49c..add3fb4e516a 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -1999,11 +1999,24 @@ write_real_cst (const tree value) int i, limit, dir; tree type = TREE_TYPE (value); - int words = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type)) / 32; + int bits = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type)); + int words = bits / 32; real_to_target (target_real, &TREE_REAL_CST (value), TYPE_MODE (type)); + if (words == 0) +{ + /* _Float16 and std::bfloat16_t are the only supported types smaller than +32 bits. */ + gcc_assert (bits == 16); + sprintf (buffer, "%04lx", (unsigned long) target_real[0]); + write_chars (buffer, 4); + return; +} + + gcc_assert (bits % 32 == 0); + /* The value in target_real is in the target word order, so we must write it out backward if that happens to be little-endian. write_number cannot be used, it will diff --git a/gcc/testsuite/g++.dg/abi/pr121801.C b/gcc/testsuite/g++.dg/abi/pr121801.C new file mode 100644 index ..cd35186d8881 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/pr121801.C @@ -0,0 +1,13 @@ +// PR c++/121801 +// { dg-do compile { target { c++20 && float16 } } } +// { dg-add-options float16 } + +template<_Float16 T> void f() {} + +void uses() { + f<_Float16(1)>(); + f<_Float16(2)>(); +} + +// { dg-final { scan-assembler "_Z1fILDF16_3c00EEvv" } } +// { dg-final { scan-assembler "_Z1fILDF16_4000EEvv" } }
[gcc r16-3855] expr, tree: Ensure get_range_pos_neg is called only on scalar integral types [PR121904]
https://gcc.gnu.org/g:bd83c6227c6c2ccb5df88937a338b501fd550de6 commit r16-3855-gbd83c6227c6c2ccb5df88937a338b501fd550de6 Author: Jakub Jelinek Date: Mon Sep 15 10:34:33 2025 +0200 expr, tree: Ensure get_range_pos_neg is called only on scalar integral types [PR121904] The gcc.c-torture/compile/20111209-1.c testcase which uses typedef char* char_ptr32 __attribute__ ((mode(SI))); ICEs on s390x since my change to optimize extensions by cheaper of signed or unsigned extension if sign bit is known from VRP not to be set. The problem is that get_range_pos_neg uses ranger into int_range_max and so ICEs on pointers. All the other current callers call it from places where only scalar integral types can appear (scalar division/modulo, overflow ifns, etc.) I think, this spot was just testing SCALAR_INT_MODE_P. The following patch adds check for INTEGRAL_TYPE_P, I think ranger will not do anything useful for pointers here anyway and what is a negative pointer is also fuzzy. I've changed both get_range_pos_neg to punt on that and the caller, either of those changes are sufficient to fix the ICE, but I think it doesn't hurt to do it in both places. 2025-09-15 Jakub Jelinek PR middle-end/121904 * tree.cc (get_range_pos_neg): Return 3 if arg doesn't have scalar integral type. * expr.cc (expand_expr_real_2) : Only choose between sign and zero extension based on costs for scalar integral inner types. Diff: --- gcc/expr.cc | 1 + gcc/tree.cc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/expr.cc b/gcc/expr.cc index 4f7b457aa678..4a699101bb5a 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -9960,6 +9960,7 @@ expand_expr_real_2 (const_sepops ops, rtx target, machine_mode tmode, else if (SCALAR_INT_MODE_P (GET_MODE (op0)) && optimize >= 2 && SCALAR_INT_MODE_P (mode) + && INTEGRAL_TYPE_P (TREE_TYPE (treeop0)) && (GET_MODE_SIZE (as_a (mode)) > GET_MODE_SIZE (as_a (GET_MODE (op0 && get_range_pos_neg (treeop0, diff --git a/gcc/tree.cc b/gcc/tree.cc index 2a3ab23f1dc7..5d52a3886cef 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -14708,7 +14708,7 @@ verify_type (const_tree t) int get_range_pos_neg (tree arg, gimple *stmt) { - if (arg == error_mark_node) + if (arg == error_mark_node || !INTEGRAL_TYPE_P (TREE_TYPE (arg))) return 3; int prec = TYPE_PRECISION (TREE_TYPE (arg));
[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: bb29203f9fb6... Correction régression class_dummy_11.f90 Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- bb29203... Correction régression class_dummy_11.f90 b89e87c... Correction régression transfer_class_5 eaecebe... Correction régression pdt_31 db83f26... Régénération fichiers générés 6d58b67... Correction matmull.m4 c08d542... Retour en arrière partiel eoshift0.c ebe1140... Régénération fichiers générés 7e427d3... Correction cshift0.m4 3186080... Régénération fichiers générés af34812... Réduction utilisations macro GFC_DESCRIPTOR_STRIDE 722d3c1... Régénération fichiers générés 6eb9f42... Ajout macros GFC_DESCRIPTOR1_ELEM, PTR_ADD_OFFSET, etc 45b390f... Régénération fichiers générés ef435aa... Décalage indexs matmul 81e99d9... Régénération fichiers générés dc39da4... Introduction macro PTR_INCREMENT_BYTES 94b80b8... Régénération des fichiers générés b8241e1... Correction quotation macros m4 d23f1b6... Remplacement macro GFC_DIMENSION_SET -> GFC_DESCRIPTOR_DIME 6e6cfa7... Renseignement span f5fa330... Extraction gfc_create_unallocated_library_result_descriptor 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..
[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)] 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);