aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog75
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/c/c-decl.cc4
-rw-r--r--gcc/c/c-parser.cc33
-rw-r--r--gcc/c/c-tree.h2
-rw-r--r--gcc/c/c-typeck.cc35
-rw-r--r--gcc/cgraph.h5
-rw-r--r--gcc/config/aarch64/aarch64-simd.md24
-rw-r--r--gcc/config/xtensa/xtensa.md34
-rw-r--r--gcc/cp/module.cc2
-rw-r--r--gcc/doc/extend.texi8
-rw-r--r--gcc/fold-const.h1
-rw-r--r--gcc/fortran/ChangeLog14
-rw-r--r--gcc/fortran/intrinsic.texi2
-rw-r--r--gcc/fortran/primary.cc35
-rw-r--r--gcc/fortran/resolve.cc33
-rw-r--r--gcc/fortran/trans-intrinsic.cc8
-rw-r--r--gcc/lra-constraints.cc5
-rw-r--r--gcc/symtab.cc15
-rw-r--r--gcc/testsuite/ChangeLog39
-rw-r--r--gcc/testsuite/g++.dg/modules/convop-2_a.H10
-rw-r--r--gcc/testsuite/g++.dg/modules/convop-2_b.C5
-rw-r--r--gcc/testsuite/gcc.dg/fold-vecperm-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/gnu-compoundlit-1.c26
-rw-r--r--gcc/testsuite/gcc.dg/gnu-compoundlit-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/pr68090.c7
-rw-r--r--gcc/testsuite/gcc.dg/pr97986-1.c27
-rw-r--r--gcc/testsuite/gcc.dg/pr97986-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/vla-init-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/vla-init-5.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr121853_1.c64
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr121853_2.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr122321.c150
-rw-r--r--gcc/testsuite/gfortran.dg/pdt_65.f03135
-rw-r--r--gcc/testsuite/gfortran.dg/pure_result.f9049
35 files changed, 843 insertions, 63 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/c/c-decl.cc b/gcc/c/c-decl.cc
index 2b31a43..1e1da2d 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -6536,6 +6536,10 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const,
return error_mark_node;
}
+ if ((TREE_STATIC (decl) || C_DECL_DECLARED_CONSTEXPR (decl))
+ && C_TYPE_VARIABLE_SIZE (type))
+ error_at (loc, "storage size isn%'t constant");
+
if (TREE_STATIC (decl)
&& !verify_type_context (loc, TCTX_STATIC_STORAGE, type))
return error_mark_node;
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 0cf3f92..9b3a786 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -1767,7 +1767,7 @@ static tree c_parser_simple_asm_expr (c_parser *);
static tree c_parser_gnu_attributes (c_parser *);
static struct c_expr c_parser_initializer (c_parser *, tree);
static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
- struct obstack *, tree);
+ struct obstack *, bool);
static void c_parser_initelt (c_parser *, struct obstack *);
static void c_parser_initval (c_parser *, struct c_expr *,
struct obstack *);
@@ -6459,7 +6459,9 @@ static struct c_expr
c_parser_initializer (c_parser *parser, tree decl)
{
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
- return c_parser_braced_init (parser, NULL_TREE, false, NULL, decl);
+ return c_parser_braced_init (parser, NULL_TREE, false, NULL,
+ decl != error_mark_node
+ && C_DECL_VARIABLE_SIZE (decl));
else
{
struct c_expr ret;
@@ -6499,12 +6501,12 @@ location_t last_init_list_comma;
compound literal, and NULL_TREE for other initializers and for
nested braced lists. NESTED_P is true for nested braced lists,
false for the list of a compound literal or the list that is the
- top-level initializer in a declaration. DECL is the declaration for
- the top-level initializer for a declaration, otherwise NULL_TREE. */
+ top-level initializer in a declaration. VARSIZE_P indicates
+ wether the object to be initialized has a variable size. */
static struct c_expr
c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
- struct obstack *outer_obstack, tree decl)
+ struct obstack *outer_obstack, bool varsize_p)
{
struct c_expr ret;
struct obstack braced_init_obstack;
@@ -6532,7 +6534,7 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
}
else
{
- if (decl && decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
+ if (varsize_p)
error_at (brace_loc,
"variable-sized object may not be initialized except "
"with an empty initializer");
@@ -6826,7 +6828,7 @@ c_parser_initval (c_parser *parser, struct c_expr *after,
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
init = c_parser_braced_init (parser, NULL_TREE, true,
- braced_init_obstack, NULL_TREE);
+ braced_init_obstack, false);
else
{
init = c_parser_expr_no_commas (parser, after);
@@ -11793,15 +11795,9 @@ c_parser_postfix_expression (c_parser *parser)
else
{
tree type_expr = NULL_TREE;
+ tree type = groktypename (t1, &type_expr, NULL);
expr.value = c_build_va_arg (start_loc, e1.value, loc,
- groktypename (t1, &type_expr, NULL));
- if (type_expr)
- {
- expr.value = build2 (C_MAYBE_CONST_EXPR,
- TREE_TYPE (expr.value), type_expr,
- expr.value);
- C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
- }
+ type, type_expr);
set_c_expr_source_range (&expr, start_loc, end_loc);
}
}
@@ -13516,10 +13512,11 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
|| (scspecs && scspecs->storage_class == csc_static)
|| constexpr_p), constexpr_p, &richloc);
type = groktypename (type_name, &type_expr, &type_expr_const);
+ bool varsize_p = false;
if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
{
- error_at (type_loc, "compound literal has variable size");
- type = error_mark_node;
+ pedwarn (type_loc, OPT_Wpedantic, "compound literal has variable size");
+ varsize_p = true;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
@@ -13544,7 +13541,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
(TYPE_QUALS (type_no_array)
| TYPE_QUAL_CONST));
}
- init = c_parser_braced_init (parser, type, false, NULL, NULL_TREE);
+ init = c_parser_braced_init (parser, type, false, NULL, varsize_p);
if (constexpr_p)
finish_underspecified_init (NULL_TREE, underspec_state);
finish_init ();
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index f367cda..ff63d69 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -917,7 +917,7 @@ extern tree c_omp_finish_mapper_clauses (tree);
extern tree c_omp_mapper_lookup (tree, tree);
extern tree c_omp_extract_mapper_directive (tree);
extern tree c_omp_map_array_section (location_t, tree);
-extern tree c_build_va_arg (location_t, tree, location_t, tree);
+extern tree c_build_va_arg (location_t, tree, location_t, tree, tree);
extern tree c_finish_transaction (location_t, tree, int);
extern bool c_tree_equal (tree, tree);
extern tree c_build_function_call_vec (location_t, const vec<location_t>&,
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index bc0fb6b..2cef463 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -12734,7 +12734,9 @@ retry:
if (constructor_max_index != NULL_TREE
&& (tree_int_cst_lt (constructor_max_index, constructor_index)
- || integer_all_onesp (constructor_max_index)))
+ || integer_all_onesp (constructor_max_index))
+ /* For VLA we got an error already. */
+ && !C_TYPE_VARIABLE_SIZE (constructor_type))
{
pedwarn_init (loc, 0,
"excess elements in array initializer");
@@ -18435,7 +18437,8 @@ c_build_qualified_type (tree type, int type_quals, tree orig_qual_type,
/* Build a VA_ARG_EXPR for the C parser. */
tree
-c_build_va_arg (location_t loc1, tree expr, location_t loc2, tree type)
+c_build_va_arg (location_t loc1, tree expr, location_t loc2, tree type,
+ tree type_expr)
{
if (error_operand_p (type))
return error_mark_node;
@@ -18459,10 +18462,36 @@ c_build_va_arg (location_t loc1, tree expr, location_t loc2, tree type)
type);
return error_mark_node;
}
+ else if (TREE_CODE (type) == ARRAY_TYPE && C_TYPE_VARIABLE_SIZE (type)
+ && !flag_isoc99)
+ {
+ error_at (loc2, "second argument to %<va_arg%> is an array type %qT",
+ type);
+ return error_mark_node;
+ }
else if (warn_cxx_compat && TREE_CODE (type) == ENUMERAL_TYPE)
warning_at (loc2, OPT_Wc___compat,
"C++ requires promoted type, not enum type, in %<va_arg%>");
- return build_va_arg (loc2, expr, type);
+
+ if (flag_isoc99 && TREE_CODE (type) == ARRAY_TYPE)
+ {
+ warning_at (loc2, 0, "second argument to %<va_arg%> is an array type %qT",
+ type);
+ /* We create a trap but evaluate side effects first. */
+ tree trapfn = builtin_decl_explicit (BUILT_IN_TRAP);
+ trapfn = build_call_expr_loc (loc2, trapfn, 0);
+ tree e2 = build2 (COMPOUND_EXPR, void_type_node, expr, trapfn);
+ /* Return a compound literal of the right type. */
+ tree e1 = build_compound_literal (loc2, type, NULL, true, 0, NULL);
+ expr = build2 (COMPOUND_EXPR, type, e2, e1);
+ }
+ else
+ expr = build_va_arg (loc2, expr, type);
+
+ if (type_expr)
+ expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), type_expr, expr);
+
+ return expr;
}
/* Return truthvalue of whether T1 is the same tree structure as T2.
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/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 4ba7f54..c713451 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -43,6 +43,7 @@
UNSPEC_FRAME_BLOCKAGE
UNSPEC_CEIL
UNSPEC_FLOOR
+ UNSPEC_ROUND
])
(define_c_enum "unspecv" [
@@ -104,8 +105,11 @@
;; This iterator and attribute allow FP-to-integer rounding of two types
;; to be generated from one template.
-(define_int_iterator ANY_ROUND [UNSPEC_CEIL UNSPEC_FLOOR])
-(define_int_attr m_round [(UNSPEC_CEIL "ceil") (UNSPEC_FLOOR "floor")])
+(define_int_iterator ANY_ROUND [UNSPEC_CEIL UNSPEC_FLOOR UNSPEC_ROUND])
+(define_int_attr m_round [(UNSPEC_CEIL "ceil") (UNSPEC_FLOOR "floor")
+ (UNSPEC_ROUND "round")])
+(define_int_attr c_round [(UNSPEC_CEIL "1") (UNSPEC_FLOOR "1")
+ (UNSPEC_ROUND "flag_unsafe_math_optimizations")])
;; Attributes.
@@ -691,13 +695,15 @@
})
(define_insn "negsf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (match_operand:SF 1 "register_operand" "f")))]
+ [(set (match_operand:SF 0 "register_operand")
+ (neg:SF (match_operand:SF 1 "register_operand")))
+ (clobber (match_scratch:SI 2))]
"TARGET_HARD_FLOAT"
- "neg.s\t%0, %1"
- [(set_attr "type" "farith")
- (set_attr "mode" "SF")
- (set_attr "length" "3")])
+ {@ [cons: =0, 1, =2; attrs: type, length]
+ [D, D, &a; arith , 7] movi.n\t%2, 1\;slli\t%2, %2, 31\;add.n\t%0, %1, %2
+ [f, f, X; farith, 3] neg.s\t%0, %1
+ }
+ [(set_attr "mode" "SF")])
;; Logical instructions.
@@ -1139,7 +1145,7 @@
(define_insn "*fix<s_fix>_truncsfsi2_scaled"
[(set (match_operand:SI 0 "register_operand" "=a")
(any_fix:SI (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "fix_scaling_operand" "F"))))]
+ (match_operand:SF 2 "fix_scaling_operand" ""))))]
"TARGET_HARD_FLOAT"
"<m_fix>.s\t%0, %1, %U2"
[(set_attr "type" "fconv")
@@ -1158,7 +1164,7 @@
(define_insn "*float<s_float>sisf2_scaled"
[(set (match_operand:SF 0 "register_operand" "=f")
(mult:SF (any_float:SF (match_operand:SI 1 "register_operand" "a"))
- (match_operand:SF 2 "float_scaling_operand" "F")))]
+ (match_operand:SF 2 "float_scaling_operand" "")))]
"TARGET_HARD_FLOAT"
"<m_float>.s\t%0, %1, %V2"
[(set_attr "type" "fconv")
@@ -1168,7 +1174,7 @@
(define_insn "l<m_round>sfsi2"
[(set (match_operand:SI 0 "register_operand" "=a")
(unspec:SI [(match_operand:SF 1 "register_operand" "f")] ANY_ROUND))]
- "TARGET_HARD_FLOAT"
+ "TARGET_HARD_FLOAT && <c_round>"
"<m_round>.s\t%0, %1, 0"
[(set_attr "type" "fconv")
(set_attr "mode" "SF")
@@ -1178,7 +1184,7 @@
[(set (match_operand:SI 0 "register_operand" "=a")
(unspec:SI [(plus:SF (match_operand:SF 1 "register_operand" "f")
(match_dup 1))] ANY_ROUND))]
- "TARGET_HARD_FLOAT"
+ "TARGET_HARD_FLOAT && <c_round>"
"<m_round>.s\t%0, %1, 1"
[(set_attr "type" "fconv")
(set_attr "mode" "SF")
@@ -1187,8 +1193,8 @@
(define_insn "*l<m_round>sfsi2_scaled"
[(set (match_operand:SI 0 "register_operand" "=a")
(unspec:SI [(mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "fix_scaling_operand" "F"))] ANY_ROUND))]
- "TARGET_HARD_FLOAT"
+ (match_operand:SF 2 "fix_scaling_operand" ""))] ANY_ROUND))]
+ "TARGET_HARD_FLOAT && <c_round>"
"<m_round>.s\t%0, %1, %U2"
[(set_attr "type" "fconv")
(set_attr "mode" "SF")
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 81357a8..31f5c81 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -6733,6 +6733,7 @@ trees_out::core_vals (tree t)
WT (((lang_tree_node *)t)->baselink.binfo);
WT (((lang_tree_node *)t)->baselink.functions);
WT (((lang_tree_node *)t)->baselink.access_binfo);
+ WT (((lang_tree_node *)t)->baselink.common.chain);
break;
case CONSTRAINT_INFO:
@@ -7302,6 +7303,7 @@ trees_in::core_vals (tree t)
RT (((lang_tree_node *)t)->baselink.binfo);
RTU (((lang_tree_node *)t)->baselink.functions);
RT (((lang_tree_node *)t)->baselink.access_binfo);
+ RT (((lang_tree_node *)t)->baselink.common.chain);
break;
case CONSTRAINT_INFO:
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 8aaedae..30eae4b 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -1131,6 +1131,14 @@ such an initializer, as shown here:
char **foo = (char *[]) @{ "x", "y", "z" @};
@end smallexample
+As a GNU extension, GCC allows compound literals with a variable size.
+In this case, only empty initialization is allowed.
+
+@smallexample
+int n = 4;
+char (*p)[n] = &(char[n])@{ @};
+@end smallexample
+
Compound literals for scalar types and union types are also allowed. In
the following example the variable @code{i} is initialized to the value
@code{2}, the result of incrementing the unnamed object created by
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/resolve.cc b/gcc/fortran/resolve.cc
index ecd2ada..03e26f0 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -15385,6 +15385,39 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
return false;
}
+ /* F2018:C1585: "The function result of a pure function shall not be both
+ polymorphic and allocatable, or have a polymorphic allocatable ultimate
+ component." */
+ if (sym->attr.pure && sym->result && sym->ts.u.derived)
+ {
+ if (sym->ts.type == BT_CLASS
+ && sym->attr.class_ok
+ && CLASS_DATA (sym->result)
+ && CLASS_DATA (sym->result)->attr.allocatable)
+ {
+ gfc_error ("Result variable %qs of pure function at %L is "
+ "polymorphic allocatable",
+ sym->result->name, &sym->result->declared_at);
+ return false;
+ }
+
+ if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->components)
+ {
+ gfc_component *c = sym->ts.u.derived->components;
+ for (; c; c = c->next)
+ if (c->ts.type == BT_CLASS
+ && CLASS_DATA (c)
+ && CLASS_DATA (c)->attr.allocatable)
+ {
+ gfc_error ("Result variable %qs of pure function at %L has "
+ "polymorphic allocatable component %qs",
+ sym->result->name, &sym->result->declared_at,
+ c->name);
+ return false;
+ }
+ }
+ }
+
if (sym->attr.is_bind_c && sym->attr.is_c_interop != 1)
{
gfc_formal_arglist *curr_arg;
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/lra-constraints.cc b/gcc/lra-constraints.cc
index 48ce7578..1bbf21f 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -523,6 +523,11 @@ update_equiv (int regno)
{
rtx x;
+ /* If REGNO is beyond the length of the equivalence array structure,
+ then there's nothing to update. */
+ if (regno >= ira_reg_equiv_len)
+ return;
+
if ((x = ira_reg_equiv[regno].memory) != NULL_RTX)
ira_reg_equiv[regno].memory
= simplify_replace_fn_rtx (x, NULL_RTX, loc_equivalence_callback,
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/g++.dg/modules/convop-2_a.H b/gcc/testsuite/g++.dg/modules/convop-2_a.H
new file mode 100644
index 0000000..62bb210
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/convop-2_a.H
@@ -0,0 +1,10 @@
+// PR c++/122381
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+template <typename T> struct color_ref {
+ operator int() const { return 0; }
+ int foo(color_ref x) {
+ return x.operator int();
+ }
+};
diff --git a/gcc/testsuite/g++.dg/modules/convop-2_b.C b/gcc/testsuite/g++.dg/modules/convop-2_b.C
new file mode 100644
index 0000000..d1e829e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/convop-2_b.C
@@ -0,0 +1,5 @@
+// PR c++/122381
+// { dg-additional-options "-fmodules" }
+
+import "convop-2_a.H";
+template struct color_ref<int>;
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/gnu-compoundlit-1.c b/gcc/testsuite/gcc.dg/gnu-compoundlit-1.c
new file mode 100644
index 0000000..a7f3496
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu-compoundlit-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu23" } */
+
+int g(int n, int (*p)[n]);
+int f(int n)
+{
+ return g(n, &(int[n]){ });
+}
+
+void h(int n)
+{
+ (int[n]){ 1 }; /* { dg-error "empty initializer" } */
+}
+
+void i(int n)
+{
+ (static int[3]){ };
+ (static int[n]){ }; /* { dg-error "storage size" } */
+ (constexpr int[3]){ };
+ (constexpr int[n]){ }; /* { dg-error "storage size" } */
+ (register int[3]){ }; /* { dg-error "register" } */
+ (register int[n]){ }; /* { dg-error "register" } */
+ (_Thread_local int[3]){ }; /* { dg-error "_Thread_local" } */
+ (_Thread_local int[n]){ }; /* { dg-error "_Thread_local" } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/gnu-compoundlit-2.c b/gcc/testsuite/gcc.dg/gnu-compoundlit-2.c
new file mode 100644
index 0000000..dcc5775
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu-compoundlit-2.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-std=gnu23 -Wall" } */
+
+[[gnu::noinline,gnu::noipa]]
+static bool f(int n)
+{
+ struct foo { char a[n]; };
+ struct foo x = { };
+
+ return 0 == __builtin_memcmp(&x, &(struct foo){ }, sizeof x);
+}
+
+int main()
+{
+ if (!f(7))
+ __builtin_abort();
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr68090.c b/gcc/testsuite/gcc.dg/pr68090.c
index 87b3b93..84e0ca4 100644
--- a/gcc/testsuite/gcc.dg/pr68090.c
+++ b/gcc/testsuite/gcc.dg/pr68090.c
@@ -1,13 +1,18 @@
/* PR c/68090 */
/* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "--pedantic-error" } */
void
fn (int i)
{
(int[(0, 1)]) { 0 }; /* { dg-error "compound literal has variable size" } */
+ /* { dg-error "variable-size" "" { target *-*-* } .-1 } */
(int[i]) { 0 }; /* { dg-error "compound literal has variable size" } */
+ /* { dg-error "variable-size" "" { target *-*-* } .-1 } */
(int[(0, i)]) { 0 }; /* { dg-error "compound literal has variable size" } */
+ /* { dg-error "variable-size" "" { target *-*-* } .-1 } */
(int [][i]){ 0 }; /* { dg-error "compound literal has variable size" } */
+ /* { dg-error "variable-size" "" { target *-*-* } .-1 } */
(int [][(1, 2)]){ 0 }; /* { dg-error "compound literal has variable size" } */
+ /* { dg-error "variable-size" "" { target *-*-* } .-1 } */
}
diff --git a/gcc/testsuite/gcc.dg/pr97986-1.c b/gcc/testsuite/gcc.dg/pr97986-1.c
new file mode 100644
index 0000000..87ee3d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97986-1.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-std=gnu23" } */
+
+#include <stdarg.h>
+
+int f(int n, ...)
+{
+ __label__ b, d;
+ va_list ap;
+ va_start(ap, n);
+ _Static_assert(5 == sizeof(va_arg(ap, char[5]))); /* { dg-warning "array type" } */
+ void g(void) { n++; goto b; }
+ int *a = va_arg((g(), ap), int[n]); /* { dg-warning "array type" } */
+b:
+ void h(void) { n++; goto d; }
+ typeof(va_arg(ap, int[(h(), n)])) c; /* { dg-warning "array type" } */
+d:
+ return n;
+}
+
+int main()
+{
+ if (9 != f(7))
+ __builtin_abort();
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr97986-2.c b/gcc/testsuite/gcc.dg/pr97986-2.c
new file mode 100644
index 0000000..fc23a57
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97986-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c90" } */
+
+#include <stdarg.h>
+
+
+int f(int n, ...)
+{
+ va_list ap;
+ va_start(ap, n);
+ _Static_assert(5 == sizeof(va_arg(ap, char[5])));
+ va_arg(ap, int[n]); /* { dg-error "array type" } */
+ int * a = va_arg(ap, int[3]); /* { dg-error "invalid use of non-lvalue array" } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/vla-init-4.c b/gcc/testsuite/gcc.dg/vla-init-4.c
index 06351d0..7d1aa5b 100644
--- a/gcc/testsuite/gcc.dg/vla-init-4.c
+++ b/gcc/testsuite/gcc.dg/vla-init-4.c
@@ -4,4 +4,4 @@
/* { dg-options "" } */
const int i = 1;
-void foo() { char *p = (char [i]){ "" }; } /* { dg-error "compound literal has variable size" } */
+void foo() { char *p = (char [i]){ "" }; } /* { dg-error "variable-sized object" } */
diff --git a/gcc/testsuite/gcc.dg/vla-init-5.c b/gcc/testsuite/gcc.dg/vla-init-5.c
index aa9f491..2c249ec 100644
--- a/gcc/testsuite/gcc.dg/vla-init-5.c
+++ b/gcc/testsuite/gcc.dg/vla-init-5.c
@@ -4,4 +4,4 @@
/* { dg-options "" } */
const int i = 1;
-void foo() { void *p = (char [][i]){ "" }; } /* { dg-error "compound literal has variable size" } */
+void foo() { void *p = (char [][i]){ "" }; } /* { dg-error "variable-sized object" } */
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/gcc.target/riscv/rvv/autovec/pr122321.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr122321.c
new file mode 100644
index 0000000..0e34bc1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr122321.c
@@ -0,0 +1,150 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -w -O0" { target rv64 } } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -w -O0" { target rv32 } } */
+
+
+typedef int a;
+typedef signed char b;
+typedef char c;
+typedef short d;
+typedef unsigned short e;
+typedef a f;
+typedef unsigned g;
+typedef long h;
+h j, k, l, m, n, o;
+int p, q, r, s;
+short t;
+volatile a u;
+a v[];
+char w, x;
+a *y, *z;
+a **aa;
+__attribute__((always_inline)) b __attribute__((vector_size(16)))
+ab(f __attribute__((vector_size(8 * sizeof(f)))), d ac,
+ d __attribute__((vector_size(2 * sizeof(d)))), d) {
+ return __builtin_shufflevector(
+ (b __attribute__((vector_size(16)))) __builtin_convertvector(
+ (d __attribute__((vector_size(16 *sizeof(d))))){
+ ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac},
+ c __attribute__((vector_size(16)))) |
+ __builtin_convertvector(
+ (d __attribute__((vector_size(16 *sizeof(d))))){
+ ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac},
+ c __attribute__((vector_size(16)))),
+ __builtin_convertvector(
+ (d __attribute__((vector_size(16 *sizeof(d))))){
+ ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac},
+ b __attribute__((vector_size(16)))),
+ 3, 21, 0, 2, 2, 7, 1, 8, 4, 0, 8, 0, 8, 9, 5, 6);
+}
+__attribute__((always_inline)) g
+ad(d ae, h __attribute__((vector_size(32 * sizeof(h))))) {
+ g f = 6318;
+ return (8 ? ae / 786856318u : 0) & ae;
+}
+a(af)(a, int);
+void(ag)(long);
+char(ah)(char, char);
+char(ai)(char);
+short(aj)(short, short);
+int ak(long, int *, int *, char, int);
+void al(signed, a *, int *, long);
+char am(int *, short, short);
+void an(int *, long, int);
+void ao(int, int *, a *);
+a ap() {
+ int *aq, *ar, *as;
+ short at;
+ char au, av, aw = 2;
+ long ax, ay, az = j;
+ int ba, i;
+ g __attribute__((vector_size(16 * sizeof(g)))) bb = {80};
+ b __attribute__((vector_size(4))) bc = {6};
+ int bd[1];
+ char *be = &w;
+ int bf, bg = q;
+ a **bh[] = {
+ &y, &z, &z, &y, &y, &y, &y, &y, &z, &z, &y, &z, &y, &y, &y, &y, &z, &y,
+ &z, &y, &y, &y, &z, &z, &z, &y, &z, &z, &z, &y, &z, &z, &y, &z, &z, &y,
+ &z, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z, &z, &y, &y, 0, &z, 0,
+ &z, 0, &y, &z, &z, 0, &z, 0, &z, &z, &z, &y, &z, &z, &y, &z, &z, &y,
+ 0, &z, 0, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z, &z, &y, &y, 0,
+ &z, 0, &z, 0, &y, &z, &z, 0, &z, 0, &z, &z, &z, &y, &z, &z, &y, &z,
+ &z, &y, 0, &z, 0, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z, &z, &y,
+ &y, 0, &z, 0, &z, 0, &y, &z, &z, 0, &z, 0, &z, &z, &z, &y, &z, &z,
+ &y, &z, &z, &y, 0, &z, 0, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z,
+ &z, &y, &y, 0, &z, 0, &z, 0, &y, &z, &z, 0, 0, &z, 0, &z, &z, &z,
+ &y, &z, &z, &y, &z, &z, &y, 0, &z, 0, 0, &z, &z};
+ for (; i; i++)
+ bd[i] = p;
+ h __attribute__((vector_size(32 * sizeof(h))))
+ bi = {2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681,
+ 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681,
+ 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681},
+ bj = __builtin_convertvector(
+ (c __attribute__((vector_size(32)))){
+ aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw,
+ aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw},
+ h __attribute__((vector_size(32 * sizeof(h))))),
+ bk = __builtin_convertvector(
+ __builtin_shufflevector(bb, bb, 4, 8, 7, 9, 1, 10, 4, 7, 0, 4, 3, 5, 6, 7,
+ 6, 2, 2, 20, 6, 4, 7, 7, 9, 7, 4, 9, 8, 6, 1, 0,
+ 6, 9),
+ h __attribute__((vector_size(32 * sizeof(h)))));
+ bb = __builtin_convertvector(
+ ab(__builtin_shufflevector(
+ __builtin_shufflevector(
+ __builtin_convertvector(
+ __builtin_shufflevector(bb, bb, 1, 31, 8, 2, 3, 7, 4, 0, 7,
+ 3, 4, 6, 7, 1, 9, 3, 8, 7, 1, 8, 5,
+ 3, 9, 9, 0, 3, 2, 8, 5, 2, 5, 3),
+ f __attribute__((vector_size(32 * sizeof(f))))),
+ (f __attribute__((vector_size(32 * sizeof(f))))){
+ 800761418310502961587690471176286910032020044212442466872080013589354162852207417903424527024812447907811618435019152886919380169872910001752451018659493155196043018716516518746289614523948734758456011127254301274351182132760058399143431214610613191313926994549901191890929084305862034120561651877003645},
+ 32, 44),
+ (f __attribute__((vector_size(2 * sizeof(f))))){o}, 1, 0, 3, 0, 2,
+ 1, 3, 3),
+ ad(__builtin_clzg((g)aw, (f)bb[9]),
+ (h __attribute__((vector_size(32 * sizeof(h))))){
+ bi[0] ?: bk[0], bi[1] ? 1 : bk[1], bi[2] ? 2 : bk[2],
+ bi[3] ? 3 : bk[3], bi[4] ? 4 : bk[4], bi[5] ? 5 : bk[5],
+ bi[6] ? 6 : bk[6], bi[7] ? 7 : bk[7], bi[8] ? 8 : bk[8],
+ bi[9] ? 9 : bk[9], bi[0] ? 10 : bk[0], bi[1] ? 1 : bk[1],
+ bi[2] ? 2 : bk[2], bi[3] ? 3 : bk[3], bi[4] ? 4 : bk[4],
+ bi[5] ? 5 : bk[5], bi[6] ? 6 : bk[6], bi[7] ? 7 : bk[7],
+ bi[8] ? 8 : bk[8], bi[9] ? 9 : bk[9], bi[0] ? 20 : bk[0],
+ bi[1] ? 1 : bk[1], bi[2] ? 2 : bk[2], bi[3] ? 3 : bk[3],
+ bi[4] ? bj[4] : 4, bi[5] ?: 5, bi[6] ?: 6,
+ bi[7] ? 0 : 7, bi[8] ?: 8, bi[9] ? 0 : 9,
+ bi[0] ? 0 : 30, bi[1] ?: 1}),
+ (d __attribute__((vector_size(2 * sizeof(d)))))
+ __builtin_shufflevector(
+ __builtin_convertvector(
+ __builtin_shufflevector(bb, bb, 2, 7, 21, 6),
+ e __attribute__((vector_size(4 * sizeof(e))))),
+ __builtin_convertvector(
+ (c __attribute__((vector_size(4)))){aw, aw},
+ e __attribute__((vector_size(4 * sizeof(e))))),
+ 5, 1) +
+ (__builtin_convertvector(
+ __builtin_shufflevector(bb, bb, 4, 5),
+ e __attribute__((vector_size(2 * sizeof(e))))) <=
+ __builtin_convertvector(
+ (c __attribute__((vector_size(2)))){aw},
+ e __attribute__((vector_size(2 * sizeof(e)))))),
+ n ? bb[5] << n : aw),
+ g __attribute__((vector_size(16 * sizeof(g)))));
+ ag(aw & t);
+ at = aj(aw, v[1]);
+ au = ah(at, aw);
+ ba = af((1 == ax != aw) <= aw <= au, aw);
+ ao(0, &bd[0], &r);
+ o = ay;
+ an(aq, aw, k);
+ av = am(ar, l, k);
+ *be = ai(*be);
+ al(x, as, &bd[0], aw);
+ bg = ak(u, &s, &bf, aw, aw);
+ as = *aa;
+ return m;
+}
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/testsuite/gfortran.dg/pure_result.f90 b/gcc/testsuite/gfortran.dg/pure_result.f90
new file mode 100644
index 0000000..a4d30aa
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pure_result.f90
@@ -0,0 +1,49 @@
+! { dg-do compile }
+! PR fortran/78640 - constraints on pure function results
+!
+! F2018:C1585, F2023:C1594:
+! "The function result of a pure function shall not be both polymorphic and
+! allocatable, or have a polymorphic allocatable ultimate component."
+
+program pr78640
+ implicit none
+
+ type foo_t
+ end type
+
+ type bar_t
+ integer, allocatable :: dummy
+ class(*), allocatable :: c
+ end type bar_t
+
+contains
+
+ pure function f() result(foo) ! { dg-error "is polymorphic allocatable" }
+ class(foo_t), allocatable :: foo
+ foo = foo_t()
+ end function
+
+ pure function f2() ! { dg-error "is polymorphic allocatable" }
+ class(foo_t), allocatable :: f2
+ f2 = foo_t()
+ end function
+
+ pure function g() result(foo) ! { dg-error "is polymorphic allocatable" }
+ class(*), allocatable :: foo
+ foo = foo_t()
+ end function
+
+ pure function g2() ! { dg-error "is polymorphic allocatable" }
+ class(*), allocatable :: g2
+ g2 = foo_t()
+ end function
+
+ pure function h() result(bar) ! { dg-error "polymorphic allocatable component" }
+ type(bar_t) :: bar
+ end function
+
+ pure function h2() ! { dg-error "polymorphic allocatable component" }
+ type(bar_t) :: h2
+ end function
+
+end