diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/ChangeLog | 75 | ||||
| -rw-r--r-- | gcc/DATESTAMP | 2 | ||||
| -rw-r--r-- | gcc/cgraph.h | 5 | ||||
| -rw-r--r-- | gcc/config/aarch64/aarch64-simd.md | 24 | ||||
| -rw-r--r-- | gcc/fold-const.cc | 16 | ||||
| -rw-r--r-- | gcc/fold-const.h | 1 | ||||
| -rw-r--r-- | gcc/fortran/ChangeLog | 14 | ||||
| -rw-r--r-- | gcc/fortran/intrinsic.texi | 2 | ||||
| -rw-r--r-- | gcc/fortran/primary.cc | 35 | ||||
| -rw-r--r-- | gcc/fortran/trans-intrinsic.cc | 8 | ||||
| -rw-r--r-- | gcc/symtab.cc | 15 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 39 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.dg/fold-vecperm-1.c | 4 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr122502.c | 21 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/aarch64/pr121853_1.c | 64 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/aarch64/pr121853_2.c | 14 | ||||
| -rw-r--r-- | gcc/testsuite/gfortran.dg/pdt_65.f03 | 135 | ||||
| -rw-r--r-- | gcc/tree-scalar-evolution.cc | 10 |
18 files changed, 442 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 53c6bd0..00f62e1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,78 @@ +2025-10-31 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + PR tree-optimization/122437 + * fold-const.h (div_if_zero_remainder): Remove. + +2025-10-31 Tamar Christina <tamar.christina@arm.com> + + PR target/121853 + * config/aarch64/aarch64-simd.md (extendbfsf2): New. + +2025-10-31 Richard Biener <rguenther@suse.de> + + PR tree-optimization/122502 + * tree-scalar-evolution.cc (final_value_replacement_loop): + Avoid folding from within FOR_EACH_IMM_USE_STMT due to active + ranger. + +2025-10-31 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + PR tree-optimization/122437 + * fold-const.cc (div_if_zero_remainder): Remove. + +2025-10-31 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + PR tree-optimization/122497 + * tree-scalar-evolution.cc (final_value_replacement_loop): Call replace_uses_by + only after the replacement statement was created. + +2025-10-31 Lulu Cheng <chenglulu@loongson.cn> + + * config/loongarch/lasx.md: Support. + * config/loongarch/loongarch.cc + (loongarch_expand_vec_widen_hilo): Remove unused code. + * config/loongarch/lsx.md: Support. + +2025-10-31 Lulu Cheng <chenglulu@loongson.cn> + + * config/loongarch/lasx.md (ILASX_HB): Move to ... + * config/loongarch/lsx.md (ILSX_HB): Move to ... + * config/loongarch/simd.md (ILSX_HB): ... here. + (ILASX_HB): ... here. + (IVEC_HB): New iterator. + (WVEC_QUARTER): New attr. + (wvec_quarter): Likewise. + (simdfmt_qw): Likewise. + (<su>dot_prod<wvec_quarter><mode>): New template. + +2025-10-31 Lulu Cheng <chenglulu@loongson.cn> + + * config/loongarch/lasx.md (hi_lo): Move to ... + * config/loongarch/simd.md (hi_lo): ... here. + * config/loongarch/loongarch.cc + (loongarch_expand_vec_widen_hilo): Add 128-bit data processing. + * config/loongarch/lsx.md + (vec_widen_<su><optab>_<hi_lo>_<mode>): New define_expand. + (vec_widen_<su>mult_<hi_lo>_<mode>): Likewise. + +2025-10-31 Lulu Cheng <chenglulu@loongson.cn> + + * config/loongarch/lasx.md (vec_widen_<su>add_hi_<mode>): + Move. + (vec_widen_<su>add_lo_<mode>): Move. + (vec_widen_<su>sub_hi_<mode>): Move. + (vec_widen_<su>sub_lo_<mode>): Move. + (vec_widen_<su>mult_hi_<mode>): Move. + (vec_widen_<su>mult_lo_<mode>): Move. + (hi_lo): New define_int_attr. + (vec_widen_<su><optab>_<hi_lo>_<mode>): New define_expand. + (vec_widen_<su>mult_<hi_lo>_<mode>): Likewise. + * config/loongarch/loongarch-protos.h + (loongarch_expand_vec_widen_hilo): Modify the function + parameter list. + * config/loongarch/loongarch.cc + (loongarch_expand_vec_widen_hilo): Optimized. + 2025-10-30 David Faust <david.faust@oracle.com> PR debug/122248 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 986fa53..38eec11 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20251031 +20251101 diff --git a/gcc/cgraph.h b/gcc/cgraph.h index a937d0a..aa2207b 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -38,6 +38,8 @@ class ipa_opt_pass_d; typedef ipa_opt_pass_d *ipa_opt_pass; /* Toplevel consists of functions, variables and assembly. + Make sure toplevel_type_names in symtab.cc is kept in sync + with this. TODO: add labels and CONST_DECLs. */ enum toplevel_type { @@ -45,7 +47,8 @@ enum toplevel_type TOPLEVEL_ASM, SYMTAB_SYMBOL, SYMTAB_FUNCTION, - SYMTAB_VARIABLE + SYMTAB_VARIABLE, + TOPLEVEL_MAX }; /* Section names are stored as reference counted strings in GGC safe hashtable diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index a121a18..e7c459d 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -3223,6 +3223,7 @@ DONE; } ) + (define_insn "extend<mode><Vwide>2" [(set (match_operand:<VWIDE> 0 "register_operand" "=w") (float_extend:<VWIDE> @@ -3232,6 +3233,29 @@ [(set_attr "type" "neon_fp_cvt_widen_s")] ) +/* A BF->SF is a shift left of 16, however shifts are expensive and the generic + middle-end expansion would force through DI move. Instead use EXT to do the + shift to get better throughput and don't go through GPRs. */ + +(define_expand "extendbfsf2" + [(set (match_operand:SF 0 "register_operand" "=w") + (float_extend:SF + (match_operand:BF 1 "register_operand" "w")))] + "TARGET_SIMD" +{ + rtx tmp0 = aarch64_gen_shareable_zero (V8BFmode); + rtx op0 = force_lowpart_subreg (V8BFmode, operands[1], BFmode); + rtx res = gen_reg_rtx (V8BFmode); + emit_insn (gen_aarch64_extv8bf (res, tmp0, op0, gen_int_mode (7, SImode))); + /* Subregs between floating point modes aren't allowed to change size, so go + through V4SFmode. */ + res = force_lowpart_subreg (V4SFmode, res, V8BFmode); + res = force_lowpart_subreg (SFmode, res, V4SFmode); + emit_move_insn (operands[0], res); + DONE; +}) + + ;; Float narrowing operations. (define_insn "aarch64_float_trunc_rodd_df" diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 1311c6e..861d73c 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -264,22 +264,6 @@ protected_set_expr_location_unshare (tree x, location_t loc) return x; } -/* If ARG2 divides ARG1 with zero remainder, carries out the exact - division and returns the quotient. Otherwise returns - NULL_TREE. */ - -tree -div_if_zero_remainder (const_tree arg1, const_tree arg2) -{ - widest_int quo; - - if (wi::multiple_of_p (wi::to_widest (arg1), wi::to_widest (arg2), - SIGNED, &quo)) - return wide_int_to_tree (TREE_TYPE (arg1), quo); - - return NULL_TREE; -} - /* This is nonzero if we should defer warnings about undefined overflow. This facility exists because these warnings are a special case. The code to estimate loop iterations does not want diff --git a/gcc/fold-const.h b/gcc/fold-const.h index 00975dc..87e7ec1 100644 --- a/gcc/fold-const.h +++ b/gcc/fold-const.h @@ -153,7 +153,6 @@ extern tree build_simple_mem_ref_loc (location_t, tree); extern poly_offset_int mem_ref_offset (const_tree); extern tree build_invariant_address (tree, tree, poly_int64); extern tree constant_boolean_node (bool, tree); -extern tree div_if_zero_remainder (const_tree, const_tree); extern bool tree_swap_operands_p (const_tree, const_tree); extern enum tree_code swap_tree_comparison (enum tree_code); diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index e7c7907..0d937eb 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,17 @@ +2025-10-31 Yuao Ma <c8ef@outlook.com> + + * intrinsic.texi: Fix typo. + * trans-intrinsic.cc (conv_intrinsic_atomic_cas): Remove unreachable + code. + +2025-10-31 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/122452 + * primary.cc (gfc_match_rvalue): Give priority to specific + procedures in a generic interface with the same name as a + PDT template. If found, use as the procedure instead of the + constructor generated from the PDT template. + 2025-10-30 Mikael Morin <mikael@gcc.gnu.org> * trans-array.cc: Cleanup obsolete comment. diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index 9012c2a..b2d1e45 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -2239,7 +2239,7 @@ is different, the value is converted to the kind of @var{ATOM}. program atomic use iso_fortran_env logical(atomic_logical_kind) :: atom[*], prev - call atomic_cas (atom[1], prev, .false., .true.)) + call atomic_cas (atom[1], prev, .false., .true.) end program atomic @end smallexample diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc index 0722c76d..1dcb1c3 100644 --- a/gcc/fortran/primary.cc +++ b/gcc/fortran/primary.cc @@ -3835,6 +3835,9 @@ gfc_match_rvalue (gfc_expr **result) gfc_typespec *ts; bool implicit_char; gfc_ref *ref; + gfc_symtree *pdt_st; + gfc_symbol *found_specific = NULL; + m = gfc_match ("%%loc"); if (m == MATCH_YES) @@ -4082,22 +4085,36 @@ gfc_match_rvalue (gfc_expr **result) break; } + gfc_gobble_whitespace (); + found_specific = NULL; + + /* Even if 'name' is that of a PDT template, priority has to be given to + possible specific procedures in the generic interface. */ + gfc_find_sym_tree (gfc_dt_upper_string (name), NULL, 1, &pdt_st); + if (sym->generic && sym->generic->next + && gfc_peek_ascii_char() != '(') + { + gfc_actual_arglist *arg = actual_arglist; + for (; arg && pdt_st; arg = arg->next) + gfc_resolve_expr (arg->expr); + found_specific = gfc_search_interface (sym->generic, 0, + &actual_arglist); + } + /* Check to see if this is a PDT constructor. The format of these constructors is rather unusual: name [(type_params)](component_values) where, component_values excludes the type_params. With the present gfortran representation this is rather awkward because the two are not distinguished, other than by their attributes. */ - if (sym->attr.generic) + if (sym->attr.generic && pdt_st != NULL && found_specific == NULL) { - gfc_symtree *pdt_st; gfc_symbol *pdt_sym; gfc_actual_arglist *ctr_arglist = NULL, *tmp; gfc_component *c; - /* Obtain the template. */ - gfc_find_sym_tree (gfc_dt_upper_string (name), NULL, 1, &pdt_st); - if (pdt_st && pdt_st->n.sym && pdt_st->n.sym->attr.pdt_template) + /* Use the template. */ + if (pdt_st->n.sym && pdt_st->n.sym->attr.pdt_template) { bool type_spec_list = false; pdt_sym = pdt_st->n.sym; @@ -4155,8 +4172,12 @@ gfc_match_rvalue (gfc_expr **result) tmp = tmp->next; } - gfc_find_sym_tree (gfc_dt_lower_string (pdt_sym->name), - NULL, 1, &symtree); + if (found_specific) + gfc_find_sym_tree (found_specific->name, + NULL, 1, &symtree); + else + gfc_find_sym_tree (gfc_dt_lower_string (pdt_sym->name), + NULL, 1, &symtree); if (!symtree) { gfc_get_ha_sym_tree (gfc_dt_lower_string (pdt_sym->name) , diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index 89a03d8..5b9111d3 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -12844,14 +12844,6 @@ conv_intrinsic_atomic_cas (gfc_code *code) new_val = gfc_build_addr_expr (NULL_TREE, tmp); } - /* Convert a constant to a pointer. */ - if (!POINTER_TYPE_P (TREE_TYPE (comp))) - { - tmp = gfc_create_var (TREE_TYPE (TREE_TYPE (old)), "comp"); - gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), comp)); - comp = gfc_build_addr_expr (NULL_TREE, tmp); - } - gfc_init_se (&argse, NULL); gfc_get_caf_token_offset (&argse, &token, &offset, caf_decl, atom, atom_expr); diff --git a/gcc/symtab.cc b/gcc/symtab.cc index 20dfe09..fb2aca5 100644 --- a/gcc/symtab.cc +++ b/gcc/symtab.cc @@ -873,7 +873,16 @@ symtab_node::dump_referring (FILE *file) fprintf (file, "\n"); } -static const char * const symtab_type_names[] = {"symbol", "function", "variable"}; +static const char * const toplevel_type_names[] = +{ + "base", + "asm", + "symbol", + "function", + "variable", +}; + +static_assert (ARRAY_SIZE(toplevel_type_names)==TOPLEVEL_MAX); /* Dump the visibility of the symbol. */ @@ -889,7 +898,7 @@ symtab_node::get_visibility_string () const const char * symtab_node::get_symtab_type_string () const { - return symtab_type_names[type]; + return toplevel_type_names[type]; } /* Dump base fields of symtab nodes to F. Not to be used directly. */ @@ -904,7 +913,7 @@ symtab_node::dump_base (FILE *f) fprintf (f, "%s (%s)", dump_asm_name (), name ()); if (dump_flags & TDF_ADDRESS) dump_addr (f, " @", (void *)this); - fprintf (f, "\n Type: %s", symtab_type_names[type]); + fprintf (f, "\n Type: %s", toplevel_type_names[type]); if (definition) fprintf (f, " definition"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index daf99d1..013121d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,42 @@ +2025-10-31 Tamar Christina <tamar.christina@arm.com> + + PR target/121853 + * gcc.target/aarch64/pr121853_1.c: New test. + * gcc.target/aarch64/pr121853_2.c: New test. + +2025-10-31 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/122452 + * gfortran.dg/pdt_65.f03: New test. + +2025-10-31 Richard Biener <rguenther@suse.de> + + PR tree-optimization/122502 + * gcc.dg/torture/pr122502.c: New testcase. + +2025-10-31 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + * gcc.dg/tree-ssa/pr122478.c: Swap `1` and `"optimized"`. + +2025-10-31 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + PR tree-optimization/122497 + * gcc.dg/torture/pr122497-1.c: New test. + +2025-10-31 Lulu Cheng <chenglulu@loongson.cn> + + * gcc.dg/vect/slp-widen-mult-half.c: Remove '-mlasx'. + * gcc.dg/vect/tree-vect.h: Check whether the runtime + environment supports LSX instructions. + * gcc.dg/vect/vect-widen-mult-const-s16.c: Dito. + * gcc.dg/vect/vect-widen-mult-const-u16.c: Dito. + * gcc.dg/vect/vect-widen-mult-half-u8.c: Dito. + * gcc.dg/vect/vect-widen-mult-half.c: Dito. + * gcc.dg/vect/vect-widen-mult-u16.c: Dito. + * gcc.dg/vect/vect-widen-mult-u8-s16-s32.c: Dito. + * gcc.dg/vect/vect-widen-mult-u8-u32.c: Dito. + * gcc.dg/vect/vect-widen-mult-u8.c: Dito. + 2025-10-30 Yap Zhi Heng <yapzhhg@gmail.com> * rust/compile/tuplepattern-restpattern-typecheck-err.rs: New file. diff --git a/gcc/testsuite/gcc.dg/fold-vecperm-1.c b/gcc/testsuite/gcc.dg/fold-vecperm-1.c index 5d4456b..878d392 100644 --- a/gcc/testsuite/gcc.dg/fold-vecperm-1.c +++ b/gcc/testsuite/gcc.dg/fold-vecperm-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-tree-forwprop3" } */ typedef int v4si __attribute__((vector_size(16))); typedef short v8hi __attribute__((vector_size(16))); @@ -20,4 +20,4 @@ int128 concat (int128 a, int128 b) { return res; } -/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 1 "forwprop3" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pr122502.c b/gcc/testsuite/gcc.dg/torture/pr122502.c new file mode 100644 index 0000000..5e2cb2e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr122502.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +short int *ts; + +void +c2 (unsigned long long int s4, int ns) +{ + short int *b2 = (short int *)&ns; + + while (ns != 0) + { + int xn; + + for (xn = 0; xn < 3; ++xn) + for (*b2 = 0; *b2 < 2; ++*b2) + s4 += xn; + if (s4 != 0) + b2 = ts; + ++ns; + } +} diff --git a/gcc/testsuite/gcc.target/aarch64/pr121853_1.c b/gcc/testsuite/gcc.target/aarch64/pr121853_1.c new file mode 100644 index 0000000..24b2fdc --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr121853_1.c @@ -0,0 +1,64 @@ +/* { dg-do run } */ +/* { dg-additional-options "-O2 -std=c99" } */ + +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +__attribute__ ((noipa)) +float convert(__bf16 value) { + return (float)value; +} + +static inline uint32_t f32_bits(float f) { + uint32_t u; memcpy(&u, &f, sizeof u); return u; +} +static inline __bf16 bf16_from_bits(uint16_t u) { + __bf16 b; memcpy(&b, &u, sizeof b); return b; +} + +/* Fixed bf16 inputs (as raw 16-bit payloads) covering edge cases. */ +static const uint16_t inputs[] = { + 0x0000, // +0 + 0x8000, // -0 + 0x7F80, // +inf + 0xFF80, // -inf + 0x7FC0, // qNaN (+) (quiet bit set in bf16) + 0xFFC0, // qNaN (-) + 0x7F01, // sNaN (+) (will be quieted by conversion) + 0xFF01, // sNaN (-) + 0x0001, // smallest +subnormal + 0x007F, // largest +subnormal + 0x8001, // smallest -subnormal + 0x807F, // largest -subnormal + 0x0080, // smallest +normal + 0x3F80, // +1.0 + 0xBF80, // -1.0 + 0x3F00, // +0.5 + 0xBF00, // -0.5 + 0x3FC0, // +1.5 + 0x7F7F, // max finite + + 0xFF7F, // max finite - +}; + +int main(void) { + const size_t N = sizeof(inputs)/sizeof(inputs[0]); + size_t fails = 0; + + for (size_t i = 0; i < N; ++i) { + __bf16 in = bf16_from_bits(inputs[i]); + float out = convert(in); + uint32_t got = f32_bits(out); + uint32_t exp = inputs[i] << 16; + + if (got != exp) { + printf("FAIL[%zu]: in_bf16=0x%04X exp_f32=0x%08X got_f32=0x%08X\n", + i, inputs[i], exp, got); + ++fails; + } + } + + if (fails != 0) + __builtin_abort (); +} + diff --git a/gcc/testsuite/gcc.target/aarch64/pr121853_2.c b/gcc/testsuite/gcc.target/aarch64/pr121853_2.c new file mode 100644 index 0000000..e9fb401 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr121853_2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O1" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +float convert(__bf16 value) { + return (float)value; +} + +/* +** convert: +** movi v[0-9]+.4s, 0 +** ext v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, #14 +** ret +*/ diff --git a/gcc/testsuite/gfortran.dg/pdt_65.f03 b/gcc/testsuite/gfortran.dg/pdt_65.f03 new file mode 100644 index 0000000..d5e45c2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pdt_65.f03 @@ -0,0 +1,135 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! +! Test fix for PR122452 +! +! Contributed by Damian Rouson <damian@archaeologic.codes> +! +module kind_parameters_m + integer, parameter :: default_real = kind(1e0) + integer, parameter :: double_precision = kind(1d0) +end module + +module tensor_m + use kind_parameters_m, only : default_real, double_precision + implicit none + + private + public :: tensor_t + + type tensor_t(k) + integer, kind :: k = default_real + real(k), allocatable, private :: values_(:) + contains + generic :: values => default_real_values, double_precision_values + procedure, private, non_overridable :: default_real_values, double_precision_values + generic :: num_components => default_real_num_components, double_precision_num_components + procedure, private :: default_real_num_components, double_precision_num_components + end type + + interface tensor_t + + pure module function construct_default_real(values) result(tensor) + implicit none + real, intent(in) :: values(:) + type(tensor_t) tensor + end function + + pure module function construct_double_precision(values) result(tensor) + implicit none + double precision, intent(in) :: values(:) + type(tensor_t(double_precision)) tensor + end function + + end interface + + interface + + pure module function default_real_values(self) result(tensor_values) + implicit none + class(tensor_t), intent(in) :: self + real, allocatable :: tensor_values(:) + end function + + pure module function double_precision_values(self) result(tensor_values) + implicit none + class(tensor_t(double_precision)), intent(in) :: self + double precision, allocatable :: tensor_values(:) + end function + + pure module function default_real_num_components(self) result(n) + implicit none + class(tensor_t), intent(in) :: self + integer n + end function + + pure module function double_precision_num_components(self) result(n) + implicit none + class(tensor_t(double_precision)), intent(in) :: self + integer n + end function + + end interface + +end module tensor_m + +submodule(tensor_m) tensor_s +contains + + pure module function construct_default_real(values) result(tensor) + implicit none + real, intent(in) :: values(:) + type(tensor_t) tensor + tensor = tensor_t ()(values) + end function + + pure module function construct_double_precision(values) result(tensor) + implicit none + double precision, intent(in) :: values(:) + type(tensor_t(double_precision)) tensor + tensor = tensor_t (double_precision)(values) + end function + + pure module function default_real_values(self) result(tensor_values) + implicit none + class(tensor_t), intent(in) :: self + real, allocatable :: tensor_values(:) + tensor_values = self%values_ + end function + + pure module function double_precision_values(self) result(tensor_values) + implicit none + class(tensor_t(double_precision)), intent(in) :: self + double precision, allocatable :: tensor_values(:) + tensor_values = self%values_ + end function + + + pure module function default_real_num_components(self) result(n) + implicit none + class(tensor_t), intent(in) :: self + integer n + n = default_real + end function + + pure module function double_precision_num_components(self) result(n) + implicit none + class(tensor_t(double_precision)), intent(in) :: self + integer n + n = double_precision + end function + +end submodule tensor_s + + + use tensor_m + type(tensor_t(kind(0e0))) :: a + type(tensor_t(kind(0D0))) :: b + a = tensor_t ([1e0,2e0]) + print *, a%num_components (), a%values () + b = tensor_t ([3d0,4d0]) + print *, b%num_components (), b%values () +end +! { dg-final { scan-tree-dump-times "construct_" 4 "original" } } +! { dg-final { scan-tree-dump-times "_components" 4 "original" } } +! { dg-final { scan-tree-dump-times "_values" 4 "original" } } diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc index 7907893..9f82abc 100644 --- a/gcc/tree-scalar-evolution.cc +++ b/gcc/tree-scalar-evolution.cc @@ -3995,11 +3995,17 @@ final_value_replacement_loop (class loop *loop) { gimple *use_stmt; imm_use_iterator imm_iter; + auto_vec<gimple *, 4> to_fold; FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, rslt) + if (!stmt_can_throw_internal (cfun, use_stmt)) + to_fold.safe_push (use_stmt); + /* Delay folding until after the immediate use walk is completed + as we have an active ranger and that might walk immediate + uses of rslt again. See PR122502. */ + for (gimple *use_stmt : to_fold) { gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt); - if (!stmt_can_throw_internal (cfun, use_stmt) - && fold_stmt (&gsi, follow_all_ssa_edges)) + if (fold_stmt (&gsi, follow_all_ssa_edges)) update_stmt (gsi_stmt (gsi)); } } |
