aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-04-15 14:51:21 +0200
committerMartin Liska <mliska@suse.cz>2021-04-15 14:51:21 +0200
commite524607beb2e179c7b981eca37eefd1aee71b5b3 (patch)
treea51183dd802994df10dd7af7a05c6495fa02ed27 /gcc
parentecb7b9c41347dba4087efe3c87d195e70297594c (diff)
parentca7d451d985b31a0b593b50115971e70ae0767da (diff)
downloadgcc-e524607beb2e179c7b981eca37eefd1aee71b5b3.zip
gcc-e524607beb2e179c7b981eca37eefd1aee71b5b3.tar.gz
gcc-e524607beb2e179c7b981eca37eefd1aee71b5b3.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog120
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/attribs.c77
-rw-r--r--gcc/attribs.h3
-rw-r--r--gcc/c/c-typeck.c10
-rw-r--r--gcc/config/aarch64/aarch64-d.c23
-rw-r--r--gcc/config/aarch64/aarch64-protos.h1
-rw-r--r--gcc/config/aarch64/aarch64.c54
-rw-r--r--gcc/config/aarch64/aarch64.h3
-rw-r--r--gcc/config/aarch64/aarch64.md53
-rw-r--r--gcc/config/arm/arm-d.c42
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.h3
-rw-r--r--gcc/config/i386/i386-d.c48
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/i386.h4
-rw-r--r--gcc/config/mips/mips-d.c30
-rw-r--r--gcc/config/mips/mips-protos.h1
-rw-r--r--gcc/config/mips/mips.h3
-rw-r--r--gcc/config/pa/pa-d.c28
-rw-r--r--gcc/config/pa/pa-protos.h1
-rw-r--r--gcc/config/pa/pa.h3
-rw-r--r--gcc/config/riscv/riscv-d.c46
-rw-r--r--gcc/config/riscv/riscv-protos.h1
-rw-r--r--gcc/config/riscv/riscv.h3
-rw-r--r--gcc/config/rs6000/rs6000-d.c30
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.h3
-rw-r--r--gcc/config/s390/s390-builtins.def85
-rw-r--r--gcc/config/s390/s390-d.c30
-rw-r--r--gcc/config/s390/s390-protos.h1
-rw-r--r--gcc/config/s390/s390.c35
-rw-r--r--gcc/config/s390/s390.h3
-rw-r--r--gcc/config/sparc/sparc-d.c28
-rw-r--r--gcc/config/sparc/sparc-protos.h1
-rw-r--r--gcc/config/sparc/sparc.h3
-rw-r--r--gcc/cp/ChangeLog42
-rw-r--r--gcc/cp/pt.c11
-rw-r--r--gcc/cp/semantics.c10
-rw-r--r--gcc/cp/typeck.c15
-rw-r--r--gcc/cse.c5
-rw-r--r--gcc/cselib.c5
-rw-r--r--gcc/d/ChangeLog37
-rw-r--r--gcc/d/d-builtins.cc19
-rw-r--r--gcc/d/d-target.cc14
-rw-r--r--gcc/d/d-target.def33
-rw-r--r--gcc/d/decl.cc6
-rw-r--r--gcc/d/typeinfo.cc5
-rw-r--r--gcc/d/types.cc19
-rw-r--r--gcc/doc/invoke.texi1
-rw-r--r--gcc/doc/tm.texi22
-rw-r--r--gcc/doc/tm.texi.in6
-rw-r--r--gcc/fortran/ChangeLog5
-rw-r--r--gcc/fortran/symbol.c2
-rw-r--r--gcc/fortran/trans-array.c204
-rw-r--r--gcc/fortran/trans-expr.c98
-rw-r--r--gcc/fortran/trans.c36
-rw-r--r--gcc/fortran/trans.h6
-rw-r--r--gcc/gimple-builder.h2
-rw-r--r--gcc/jump.c5
-rw-r--r--gcc/lra-constraints.c17
-rw-r--r--gcc/lto/lto.c2
-rw-r--r--gcc/print-rtl.c32
-rw-r--r--gcc/reload.c5
-rw-r--r--gcc/rtl.c10
-rw-r--r--gcc/rtl.h17
-rw-r--r--gcc/testsuite/ChangeLog64
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction85.C16
-rw-r--r--gcc/testsuite/g++.dg/parse/uneval1.C14
-rw-r--r--gcc/testsuite/g++.dg/template/dependent-tmpl2.C10
-rw-r--r--gcc/testsuite/g++.dg/template/ref11.C9
-rw-r--r--gcc/testsuite/g++.target/aarch64/advsimd-intrinsics/advsimd-intrinsics.exp72
-rw-r--r--gcc/testsuite/g++.target/aarch64/advsimd-intrinsics/pr98852.C110
-rw-r--r--gcc/testsuite/gcc.dg/pr86058.c9
-rw-r--r--gcc/testsuite/gcc.dg/pr93210.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/pr98852.c129
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr100056.c58
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr99246.c17
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/pr99929_1.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/pr99929_2.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100066.c13
-rw-r--r--gcc/testsuite/gcc.target/s390/zvector/imm-range-error-1.c26
-rw-r--r--gcc/testsuite/gcc.target/s390/zvector/vec_msum_u128-1.c45
-rw-r--r--gcc/tree-cfg.c2
-rw-r--r--gcc/tree-ssa-propagate.c2
85 files changed, 1825 insertions, 267 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0eebc87..90860a7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,123 @@
+2021-04-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR rtl-optimization/99929
+ * rtl.h (same_vector_encodings_p): New function.
+ * cse.c (exp_equiv_p): Check that CONST_VECTORs have the same encoding.
+ * cselib.c (rtx_equal_for_cselib_1): Likewise.
+ * jump.c (rtx_renumbered_equal_p): Likewise.
+ * lra-constraints.c (operands_match_p): Likewise.
+ * reload.c (operands_match_p): Likewise.
+ * rtl.c (rtx_equal_p_cb, rtx_equal_p): Likewise.
+
+2021-04-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * print-rtl.c (rtx_writer::print_rtx_operand_codes_E_and_V): Print
+ more information about variable-length CONST_VECTORs.
+
+2021-04-14 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/100066
+ * lra-constraints.c (split_reg): Check paradoxical_subreg_p for
+ ordered modes when choosing splitting mode for hard reg.
+
+2021-04-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/99246
+ * config/aarch64/aarch64.c (aarch64_expand_sve_const_vector_sel):
+ New function.
+ (aarch64_expand_sve_const_vector): Use it for nelts_per_pattern==2.
+
+2021-04-14 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ * config/s390/s390-builtins.def (O_M5, O_M12, ...): Add new macros
+ for mask operand types.
+ (s390_vec_permi_s64, s390_vec_permi_b64, s390_vec_permi_u64)
+ (s390_vec_permi_dbl, s390_vpdi): Use the M5 type for the immediate
+ operand.
+ (s390_vec_msum_u128, s390_vmslg): Use the M12 type for the
+ immediate operand.
+ * config/s390/s390.c (s390_const_operand_ok): Check the new
+ operand types and generate a list of valid values.
+
+2021-04-14 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * doc/tm.texi: Regenerate.
+ * doc/tm.texi.in (D language and ABI): Add @hook for
+ TARGET_D_REGISTER_OS_TARGET_INFO.
+
+2021-04-14 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * config/aarch64/aarch64-d.c (aarch64_d_handle_target_float_abi): New
+ function.
+ (aarch64_d_register_target_info): New function.
+ * config/aarch64/aarch64-protos.h (aarch64_d_register_target_info):
+ Declare.
+ * config/aarch64/aarch64.h (TARGET_D_REGISTER_CPU_TARGET_INFO):
+ Define.
+ * config/arm/arm-d.c (arm_d_handle_target_float_abi): New function.
+ (arm_d_register_target_info): New function.
+ * config/arm/arm-protos.h (arm_d_register_target_info): Declare.
+ * config/arm/arm.h (TARGET_D_REGISTER_CPU_TARGET_INFO): Define.
+ * config/i386/i386-d.c (ix86_d_handle_target_float_abi): New function.
+ (ix86_d_register_target_info): New function.
+ * config/i386/i386-protos.h (ix86_d_register_target_info): Declare.
+ * config/i386/i386.h (TARGET_D_REGISTER_CPU_TARGET_INFO): Define.
+ * config/mips/mips-d.c (mips_d_handle_target_float_abi): New function.
+ (mips_d_register_target_info): New function.
+ * config/mips/mips-protos.h (mips_d_register_target_info): Declare.
+ * config/mips/mips.h (TARGET_D_REGISTER_CPU_TARGET_INFO): Define.
+ * config/pa/pa-d.c (pa_d_handle_target_float_abi): New function.
+ (pa_d_register_target_info): New function.
+ * config/pa/pa-protos.h (pa_d_register_target_info): Declare.
+ * config/pa/pa.h (TARGET_D_REGISTER_CPU_TARGET_INFO): Define.
+ * config/riscv/riscv-d.c (riscv_d_handle_target_float_abi): New
+ function.
+ (riscv_d_register_target_info): New function.
+ * config/riscv/riscv-protos.h (riscv_d_register_target_info): Declare.
+ * config/riscv/riscv.h (TARGET_D_REGISTER_CPU_TARGET_INFO): Define.
+ * config/rs6000/rs6000-d.c (rs6000_d_handle_target_float_abi): New
+ function.
+ (rs6000_d_register_target_info): New function.
+ * config/rs6000/rs6000-protos.h (rs6000_d_register_target_info):
+ Declare.
+ * config/rs6000/rs6000.h (TARGET_D_REGISTER_CPU_TARGET_INFO): Define.
+ * config/s390/s390-d.c (s390_d_handle_target_float_abi): New function.
+ (s390_d_register_target_info): New function.
+ * config/s390/s390-protos.h (s390_d_register_target_info): Declare.
+ * config/s390/s390.h (TARGET_D_REGISTER_CPU_TARGET_INFO): Define.
+ * config/sparc/sparc-d.c (sparc_d_handle_target_float_abi): New
+ function.
+ (sparc_d_register_target_info): New function.
+ * config/sparc/sparc-protos.h (sparc_d_register_target_info): Declare.
+ * config/sparc/sparc.h (TARGET_D_REGISTER_CPU_TARGET_INFO): Define.
+ * doc/tm.texi: Regenerate.
+ * doc/tm.texi.in (D language and ABI): Add @hook for
+ TARGET_D_REGISTER_CPU_TARGET_INFO.
+
+2021-04-14 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * config/i386/i386-d.c (ix86_d_has_stdcall_convention): New function.
+ * config/i386/i386-protos.h (ix86_d_has_stdcall_convention): Declare.
+ * config/i386/i386.h (TARGET_D_HAS_STDCALL_CONVENTION): Define.
+ * doc/tm.texi: Regenerate.
+ * doc/tm.texi.in (D language and ABI): Add @hook for
+ TARGET_D_HAS_STDCALL_CONVENTION.
+
+2021-04-14 Richard Biener <rguenther@suse.de>
+
+ * tree-cfg.c (verify_gimple_assign_ternary): Verify that
+ VEC_COND_EXPRs have a gimple_val condition.
+ * tree-ssa-propagate.c (valid_gimple_rhs_p): VEC_COND_EXPR
+ can no longer have a GENERIC condition.
+
+2021-04-14 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/100067
+ * config/arm/arm.c (arm_configure_build_target): Strip isa_all_fpbits
+ from the isa_delta when -mfpu has been used.
+ (arm_options_perform_arch_sanity_checks): It's the architecture that
+ lacks an FPU not the processor.
+
2021-04-13 Richard Biener <rguenther@suse.de>
PR tree-optimization/100053
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 3219cc3..e9d3aa7 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20210414
+20210415
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 16c6b12..3ffa1b6 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -1366,6 +1366,83 @@ comp_type_attributes (const_tree type1, const_tree type2)
return targetm.comp_type_attributes (type1, type2);
}
+/* PREDICATE acts as a function of type:
+
+ (const_tree attr, const attribute_spec *as) -> bool
+
+ where ATTR is an attribute and AS is its possibly-null specification.
+ Return a list of every attribute in attribute list ATTRS for which
+ PREDICATE is true. Return ATTRS itself if PREDICATE returns true
+ for every attribute. */
+
+template<typename Predicate>
+tree
+remove_attributes_matching (tree attrs, Predicate predicate)
+{
+ tree new_attrs = NULL_TREE;
+ tree *ptr = &new_attrs;
+ const_tree start = attrs;
+ for (const_tree attr = attrs; attr; attr = TREE_CHAIN (attr))
+ {
+ tree name = get_attribute_name (attr);
+ const attribute_spec *as = lookup_attribute_spec (name);
+ const_tree end;
+ if (!predicate (attr, as))
+ end = attr;
+ else if (start == attrs)
+ continue;
+ else
+ end = TREE_CHAIN (attr);
+
+ for (; start != end; start = TREE_CHAIN (start))
+ {
+ *ptr = tree_cons (TREE_PURPOSE (start),
+ TREE_VALUE (start), NULL_TREE);
+ TREE_CHAIN (*ptr) = NULL_TREE;
+ ptr = &TREE_CHAIN (*ptr);
+ }
+ start = TREE_CHAIN (attr);
+ }
+ gcc_assert (!start || start == attrs);
+ return start ? attrs : new_attrs;
+}
+
+/* If VALUE is true, return the subset of ATTRS that affect type identity,
+ otherwise return the subset of ATTRS that don't affect type identity. */
+
+tree
+affects_type_identity_attributes (tree attrs, bool value)
+{
+ auto predicate = [value](const_tree, const attribute_spec *as) -> bool
+ {
+ return bool (as && as->affects_type_identity) == value;
+ };
+ return remove_attributes_matching (attrs, predicate);
+}
+
+/* Remove attributes that affect type identity from ATTRS unless the
+ same attributes occur in OK_ATTRS. */
+
+tree
+restrict_type_identity_attributes_to (tree attrs, tree ok_attrs)
+{
+ auto predicate = [ok_attrs](const_tree attr,
+ const attribute_spec *as) -> bool
+ {
+ if (!as || !as->affects_type_identity)
+ return true;
+
+ for (tree ok_attr = lookup_attribute (as->name, ok_attrs);
+ ok_attr;
+ ok_attr = lookup_attribute (as->name, TREE_CHAIN (ok_attr)))
+ if (simple_cst_equal (TREE_VALUE (ok_attr), TREE_VALUE (attr)) == 1)
+ return true;
+
+ return false;
+ };
+ return remove_attributes_matching (attrs, predicate);
+}
+
/* Return a type like TTYPE except that its TYPE_ATTRIBUTE
is ATTRIBUTE.
diff --git a/gcc/attribs.h b/gcc/attribs.h
index 898e73d..df78eb1 100644
--- a/gcc/attribs.h
+++ b/gcc/attribs.h
@@ -65,6 +65,9 @@ extern bool attribute_value_equal (const_tree, const_tree);
warning to be generated). */
extern int comp_type_attributes (const_tree, const_tree);
+extern tree affects_type_identity_attributes (tree, bool = true);
+extern tree restrict_type_identity_attributes_to (tree, tree);
+
/* Default versions of target-overridable functions. */
extern tree merge_decl_attributes (tree, tree);
extern tree merge_type_attributes (tree, tree);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 21eab00..51a62c8 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -740,10 +740,16 @@ c_common_type (tree t1, tree t2)
t2 = TYPE_MAIN_VARIANT (t2);
if (TYPE_ATTRIBUTES (t1) != NULL_TREE)
- t1 = build_type_attribute_variant (t1, NULL_TREE);
+ {
+ tree attrs = affects_type_identity_attributes (TYPE_ATTRIBUTES (t1));
+ t1 = build_type_attribute_variant (t1, attrs);
+ }
if (TYPE_ATTRIBUTES (t2) != NULL_TREE)
- t2 = build_type_attribute_variant (t2, NULL_TREE);
+ {
+ tree attrs = affects_type_identity_attributes (TYPE_ATTRIBUTES (t2));
+ t2 = build_type_attribute_variant (t2, attrs);
+ }
/* Save time if the two types are the same. */
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 4fce593..416bb7c 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -31,3 +31,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index d5d5417..c203338 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -1011,6 +1011,7 @@ std::string aarch64_get_extension_string_for_isa_flags (uint64_t, uint64_t);
/* Defined in aarch64-d.c */
extern void aarch64_d_target_versions (void);
+extern void aarch64_d_register_target_info (void);
rtl_opt_pass *make_pass_fma_steering (gcc::context *);
rtl_opt_pass *make_pass_track_speculation (gcc::context *);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 6405504..04b55d9 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -5166,6 +5166,56 @@ aarch64_expand_sve_ld1rq (rtx dest, rtx src)
return true;
}
+/* SRC is an SVE CONST_VECTOR that contains N "foreground" values followed
+ by N "background" values. Try to move it into TARGET using:
+
+ PTRUE PRED.<T>, VL<N>
+ MOV TRUE.<T>, #<foreground>
+ MOV FALSE.<T>, #<background>
+ SEL TARGET.<T>, PRED.<T>, TRUE.<T>, FALSE.<T>
+
+ The PTRUE is always a single instruction but the MOVs might need a
+ longer sequence. If the background value is zero (as it often is),
+ the sequence can sometimes collapse to a PTRUE followed by a
+ zero-predicated move.
+
+ Return the target on success, otherwise return null. */
+
+static rtx
+aarch64_expand_sve_const_vector_sel (rtx target, rtx src)
+{
+ gcc_assert (CONST_VECTOR_NELTS_PER_PATTERN (src) == 2);
+
+ /* Make sure that the PTRUE is valid. */
+ machine_mode mode = GET_MODE (src);
+ machine_mode pred_mode = aarch64_sve_pred_mode (mode);
+ unsigned int npatterns = CONST_VECTOR_NPATTERNS (src);
+ if (aarch64_svpattern_for_vl (pred_mode, npatterns)
+ == AARCH64_NUM_SVPATTERNS)
+ return NULL_RTX;
+
+ rtx_vector_builder pred_builder (pred_mode, npatterns, 2);
+ rtx_vector_builder true_builder (mode, npatterns, 1);
+ rtx_vector_builder false_builder (mode, npatterns, 1);
+ for (unsigned int i = 0; i < npatterns; ++i)
+ {
+ true_builder.quick_push (CONST_VECTOR_ENCODED_ELT (src, i));
+ pred_builder.quick_push (CONST1_RTX (BImode));
+ }
+ for (unsigned int i = 0; i < npatterns; ++i)
+ {
+ false_builder.quick_push (CONST_VECTOR_ENCODED_ELT (src, i + npatterns));
+ pred_builder.quick_push (CONST0_RTX (BImode));
+ }
+ expand_operand ops[4];
+ create_output_operand (&ops[0], target, mode);
+ create_input_operand (&ops[1], true_builder.build (), mode);
+ create_input_operand (&ops[2], false_builder.build (), mode);
+ create_input_operand (&ops[3], pred_builder.build (), pred_mode);
+ expand_insn (code_for_vcond_mask (mode, mode), 4, ops);
+ return target;
+}
+
/* Return a register containing CONST_VECTOR SRC, given that SRC has an
SVE data mode and isn't a legitimate constant. Use TARGET for the
result if convenient.
@@ -5300,6 +5350,10 @@ aarch64_expand_sve_const_vector (rtx target, rtx src)
if (GET_MODE_NUNITS (mode).is_constant ())
return NULL_RTX;
+ if (nelts_per_pattern == 2)
+ if (rtx res = aarch64_expand_sve_const_vector_sel (target, src))
+ return res;
+
/* Expand each pattern individually. */
gcc_assert (npatterns > 1);
rtx_vector_builder builder;
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index d0bae61..bfffbcd 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -26,8 +26,9 @@
#define TARGET_CPU_CPP_BUILTINS() \
aarch64_cpu_cpp_builtins (pfile)
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS aarch64_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO aarch64_d_register_target_info
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 9a7ed78..962640b 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4431,6 +4431,59 @@
[(set_attr "type" "logic_shift_imm")]
)
+(define_split
+ [(set (match_operand:GPI 0 "register_operand")
+ (LOGICAL:GPI
+ (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand")
+ (match_operand:QI 2 "aarch64_shift_imm_<mode>"))
+ (match_operand:GPI 3 "const_int_operand"))
+ (zero_extend:GPI (match_operand 4 "register_operand"))))]
+ "can_create_pseudo_p ()
+ && ((paradoxical_subreg_p (operands[1])
+ && rtx_equal_p (SUBREG_REG (operands[1]), operands[4]))
+ || (REG_P (operands[1])
+ && REG_P (operands[4])
+ && REGNO (operands[1]) == REGNO (operands[4])))
+ && (trunc_int_for_mode (GET_MODE_MASK (GET_MODE (operands[4]))
+ << INTVAL (operands[2]), <MODE>mode)
+ == INTVAL (operands[3]))"
+ [(set (match_dup 5) (zero_extend:GPI (match_dup 4)))
+ (set (match_dup 0) (LOGICAL:GPI (ashift:GPI (match_dup 5) (match_dup 2))
+ (match_dup 5)))]
+ "operands[5] = gen_reg_rtx (<MODE>mode);"
+)
+
+(define_split
+ [(set (match_operand:GPI 0 "register_operand")
+ (LOGICAL:GPI
+ (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand")
+ (match_operand:QI 2 "aarch64_shift_imm_<mode>"))
+ (match_operand:GPI 4 "const_int_operand"))
+ (and:GPI (match_dup 1) (match_operand:GPI 3 "const_int_operand"))))]
+ "can_create_pseudo_p ()
+ && pow2_or_zerop (UINTVAL (operands[3]) + 1)
+ && (trunc_int_for_mode (UINTVAL (operands[3])
+ << INTVAL (operands[2]), <MODE>mode)
+ == INTVAL (operands[4]))"
+ [(set (match_dup 5) (and:GPI (match_dup 1) (match_dup 3)))
+ (set (match_dup 0) (LOGICAL:GPI (ashift:GPI (match_dup 5) (match_dup 2))
+ (match_dup 5)))]
+ "operands[5] = gen_reg_rtx (<MODE>mode);"
+)
+
+(define_split
+ [(set (match_operand:GPI 0 "register_operand")
+ (LOGICAL:GPI
+ (ashift:GPI (sign_extend:GPI (match_operand 1 "register_operand"))
+ (match_operand:QI 2 "aarch64_shift_imm_<mode>"))
+ (sign_extend:GPI (match_dup 1))))]
+ "can_create_pseudo_p ()"
+ [(set (match_dup 3) (sign_extend:GPI (match_dup 1)))
+ (set (match_dup 0) (LOGICAL:GPI (ashift:GPI (match_dup 3) (match_dup 2))
+ (match_dup 3)))]
+ "operands[3] = gen_reg_rtx (<MODE>mode);"
+)
+
(define_insn "*<optab>_rol<mode>3"
[(set (match_operand:GPI 0 "register_operand" "=r")
(LOGICAL:GPI (rotate:GPI
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 2cb9f4b..5f43ef9 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -53,3 +53,45 @@ arm_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 952a825..2521541 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -397,6 +397,7 @@ extern void arm_cpu_cpp_builtins (struct cpp_reader *);
/* Defined in arm-d.c */
extern void arm_d_target_versions (void);
+extern void arm_d_register_target_info (void);
extern bool arm_is_constant_pool_ref (rtx);
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 113c015..c70af57 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -47,8 +47,9 @@ extern char arm_arch_name[];
/* Target CPU builtins. */
#define TARGET_CPU_CPP_BUILTINS() arm_cpu_cpp_builtins (pfile)
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS arm_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO arm_d_register_target_info
#include "config/arm/arm-opts.h"
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index b79be85..da5958c 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -44,3 +44,51 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
+/* Implement TARGET_D_HAS_STDCALL_CONVENTION for x86 targets. */
+
+bool
+ix86_d_has_stdcall_convention (unsigned int *link_system,
+ unsigned int *link_windows)
+{
+ if (ix86_abi == MS_ABI)
+ {
+ *link_system = 1;
+ *link_windows = (!TARGET_64BIT) ? 1 : 0;
+ }
+ else
+ {
+ *link_system = 0;
+ *link_windows = 0;
+ }
+
+ return true;
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69e..7782cf11 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,8 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
+extern bool ix86_d_has_stdcall_convention (unsigned int *, unsigned int *);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index fab1b3c..97700d7 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -802,8 +802,10 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
+#define TARGET_D_HAS_STDCALL_CONVENTION ix86_d_has_stdcall_convention
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index dc57127..e03f486 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -56,3 +56,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 72bbbe2..2cf4ed5 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -388,5 +388,6 @@ extern void mips_expand_vec_cond_expr (machine_mode, machine_mode, rtx *);
/* Routines implemented in mips-d.c */
extern void mips_d_target_versions (void);
+extern void mips_d_register_target_info (void);
#endif /* ! GCC_MIPS_PROTOS_H */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index b4a60a5..47aac9d 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -658,8 +658,9 @@ struct mips_cpu_info {
} \
while (0)
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS mips_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO mips_d_register_target_info
/* Default target_flags if no switches are specified */
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index 663e749..41b2f18 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -39,3 +39,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h
index 0e1e471..5bf6fef 100644
--- a/gcc/config/pa/pa-protos.h
+++ b/gcc/config/pa/pa-protos.h
@@ -115,3 +115,4 @@ extern const int pa_magic_milli[];
/* Routines implemented in pa-d.c */
extern void pa_d_target_versions (void);
+extern void pa_d_register_target_info (void);
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 3ec015a..fbb9604 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -1302,8 +1302,9 @@ do { \
#define NEED_INDICATE_EXEC_STACK 0
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS pa_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO pa_d_register_target_info
/* Output default function prologue for hpux. */
#define TARGET_ASM_FUNCTION_PROLOGUE pa_output_function_prologue
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index b20b778..8883cec 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -39,3 +39,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index cc0be7e..43d7224 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -80,6 +80,7 @@ void riscv_cpu_cpp_builtins (cpp_reader *);
/* Routines implemented in riscv-d.c */
extern void riscv_d_target_versions (void);
+extern void riscv_d_register_target_info (void);
/* Routines implemented in riscv-builtins.c. */
extern void riscv_atomic_assign_expand_fenv (tree *, tree *, tree *);
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 3cc3e86..d17096e 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -27,8 +27,9 @@ along with GCC; see the file COPYING3. If not see
/* Target CPU builtins. */
#define TARGET_CPU_CPP_BUILTINS() riscv_cpu_cpp_builtins (pfile)
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS riscv_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO riscv_d_register_target_info
#ifdef TARGET_BIG_ENDIAN_DEFAULT
#define DEFAULT_ENDIAN_SPEC "b"
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index 6bfe813..755de42 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -45,3 +45,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index c44fd3d..a06a147 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -298,6 +298,7 @@ extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT,
/* Declare functions in rs6000-d.c */
extern void rs6000_d_target_versions (void);
+extern void rs6000_d_register_target_info (void);
#ifdef NO_DOLLAR_IN_LABEL
const char * rs6000_xcoff_strip_dollar (const char *);
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 233a92b..164d359 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -641,8 +641,9 @@ extern unsigned char rs6000_recip_bits[];
#define TARGET_CPU_CPP_BUILTINS() \
rs6000_cpu_cpp_builtins (pfile)
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS rs6000_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO rs6000_d_register_target_info
/* This is used by rs6000_cpu_cpp_builtins to indicate the byte order
we're compiling for. Some configurations may need to override it. */
diff --git a/gcc/config/s390/s390-builtins.def b/gcc/config/s390/s390-builtins.def
index 129d712..f77ab75 100644
--- a/gcc/config/s390/s390-builtins.def
+++ b/gcc/config/s390/s390-builtins.def
@@ -29,6 +29,9 @@
#undef O_U16
#undef O_U32
+#undef O_M5
+#undef O_M12
+
#undef O_S2
#undef O_S3
#undef O_S4
@@ -37,6 +40,7 @@
#undef O_S12
#undef O_S16
#undef O_S32
+
#undef O_ELEM
#undef O_LIT
@@ -85,6 +89,16 @@
#undef O3_U32
#undef O4_U32
+#undef O1_M5
+#undef O2_M5
+#undef O3_M5
+#undef O4_M5
+
+#undef O1_M12
+#undef O2_M12
+#undef O3_M12
+#undef O4_M12
+
#undef O1_S2
#undef O2_S2
#undef O3_S2
@@ -140,31 +154,34 @@
#undef O_UIMM_P
#undef O_SIMM_P
-#define O_U1 1 /* unsigned 1 bit literal */
-#define O_U2 2 /* unsigned 2 bit literal */
-#define O_U3 3 /* unsigned 3 bit literal */
-#define O_U4 4 /* unsigned 4 bit literal */
-#define O_U5 5 /* unsigned 5 bit literal */
-#define O_U8 6 /* unsigned 8 bit literal */
-#define O_U12 7 /* unsigned 16 bit literal */
-#define O_U16 8 /* unsigned 16 bit literal */
-#define O_U32 9 /* unsigned 32 bit literal */
-
-#define O_S2 10 /* signed 2 bit literal */
-#define O_S3 11 /* signed 3 bit literal */
-#define O_S4 12 /* signed 4 bit literal */
-#define O_S5 13 /* signed 5 bit literal */
-#define O_S8 14 /* signed 8 bit literal */
-#define O_S12 15 /* signed 12 bit literal */
-#define O_S16 16 /* signed 16 bit literal */
-#define O_S32 17 /* signed 32 bit literal */
-
-#define O_ELEM 18 /* Element selector requiring modulo arithmetic. */
-#define O_LIT 19 /* Operand must be a literal fitting the target type. */
+#define O_U1 1 /* unsigned 1 bit literal */
+#define O_U2 2 /* unsigned 2 bit literal */
+#define O_U3 3 /* unsigned 3 bit literal */
+#define O_U4 4 /* unsigned 4 bit literal */
+#define O_U5 5 /* unsigned 5 bit literal */
+#define O_U8 6 /* unsigned 8 bit literal */
+#define O_U12 7 /* unsigned 16 bit literal */
+#define O_U16 8 /* unsigned 16 bit literal */
+#define O_U32 9 /* unsigned 32 bit literal */
+
+#define O_M5 10 /* matches bitmask of 5 */
+#define O_M12 11 /* matches bitmask of 12 */
+
+#define O_S2 12 /* signed 2 bit literal */
+#define O_S3 13 /* signed 3 bit literal */
+#define O_S4 14 /* signed 4 bit literal */
+#define O_S5 15 /* signed 5 bit literal */
+#define O_S8 16 /* signed 8 bit literal */
+#define O_S12 17 /* signed 12 bit literal */
+#define O_S16 18 /* signed 16 bit literal */
+#define O_S32 19 /* signed 32 bit literal */
+
+#define O_ELEM 20 /* Element selector requiring modulo arithmetic. */
+#define O_LIT 21 /* Operand must be a literal fitting the target type. */
#define O_SHIFT 5
-#define O_UIMM_P(X) ((X) >= O_U1 && (X) <= O_U32)
+#define O_UIMM_P(X) ((X) >= O_U1 && (X) <= O_M12)
#define O_SIMM_P(X) ((X) >= O_S2 && (X) <= O_S32)
#define O_IMM_P(X) ((X) == O_LIT || ((X) >= O_U1 && (X) <= O_S32))
@@ -213,6 +230,16 @@
#define O3_U32 (O_U32 << (2 * O_SHIFT))
#define O4_U32 (O_U32 << (3 * O_SHIFT))
+#define O1_M5 O_M5
+#define O2_M5 (O_M5 << O_SHIFT)
+#define O3_M5 (O_M5 << (2 * O_SHIFT))
+#define O4_M5 (O_M5 << (3 * O_SHIFT))
+
+#define O1_M12 O_M12
+#define O2_M12 (O_M12 << O_SHIFT)
+#define O3_M12 (O_M12 << (2 * O_SHIFT))
+#define O4_M12 (O_M12 << (3 * O_SHIFT))
+
#define O1_S2 O_S2
#define O2_S2 (O_S2 << O_SHIFT)
@@ -644,12 +671,12 @@ OB_DEF_VAR (s390_vec_perm_dbl, s390_vperm, 0,
B_DEF (s390_vperm, vec_permv16qi, 0, B_VX, 0, BT_FN_UV16QI_UV16QI_UV16QI_UV16QI)
OB_DEF (s390_vec_permi, s390_vec_permi_s64, s390_vec_permi_dbl, B_VX, BT_FN_OV4SI_OV4SI_OV4SI_INT)
-OB_DEF_VAR (s390_vec_permi_s64, s390_vpdi, 0, O3_U2, BT_OV_V2DI_V2DI_V2DI_INT)
-OB_DEF_VAR (s390_vec_permi_b64, s390_vpdi, 0, O3_U2, BT_OV_BV2DI_BV2DI_BV2DI_INT)
-OB_DEF_VAR (s390_vec_permi_u64, s390_vpdi, 0, O3_U2, BT_OV_UV2DI_UV2DI_UV2DI_INT)
-OB_DEF_VAR (s390_vec_permi_dbl, s390_vpdi, 0, O3_U2, BT_OV_V2DF_V2DF_V2DF_INT)
+OB_DEF_VAR (s390_vec_permi_s64, s390_vpdi, 0, O3_M5, BT_OV_V2DI_V2DI_V2DI_INT)
+OB_DEF_VAR (s390_vec_permi_b64, s390_vpdi, 0, O3_M5, BT_OV_BV2DI_BV2DI_BV2DI_INT)
+OB_DEF_VAR (s390_vec_permi_u64, s390_vpdi, 0, O3_M5, BT_OV_UV2DI_UV2DI_UV2DI_INT)
+OB_DEF_VAR (s390_vec_permi_dbl, s390_vpdi, 0, O3_M5, BT_OV_V2DF_V2DF_V2DF_INT)
-B_DEF (s390_vpdi, vec_permiv2di, 0, B_VX, O3_U2, BT_FN_UV2DI_UV2DI_UV2DI_INT)
+B_DEF (s390_vpdi, vec_permiv2di, 0, B_VX, O3_M5, BT_FN_UV2DI_UV2DI_UV2DI_INT)
OB_DEF (s390_vec_splat, s390_vec_splat2_s8, s390_vec_splat2_dbl,B_VX, BT_FN_OV4SI_OV4SI_UCHAR)
OB_DEF_VAR (s390_vec_splat2_s8, s390_vrepb, 0, O2_U4, BT_OV_V16QI_V16QI_UCHAR)
@@ -2287,8 +2314,8 @@ OB_DEF_VAR (s390_vec_test_mask_dbl, s390_vtm, 0,
B_DEF (s390_vtm, vec_test_mask_intv16qi,0, B_VX, 0, BT_FN_INT_UV16QI_UV16QI)
-B_DEF (s390_vec_msum_u128, vec_msumv2di, 0, B_VXE, O4_U2, BT_FN_UV16QI_UV2DI_UV2DI_UV16QI_INT)
-B_DEF (s390_vmslg, vmslg, 0, B_VXE, O4_U4, BT_FN_INT128_UV2DI_UV2DI_INT128_INT)
+B_DEF (s390_vec_msum_u128, vec_msumv2di, 0, B_VXE, O4_M12, BT_FN_UV16QI_UV2DI_UV2DI_UV16QI_INT)
+B_DEF (s390_vmslg, vmslg, 0, B_VXE, O4_M12, BT_FN_INT128_UV2DI_UV2DI_INT128_INT)
OB_DEF (s390_vec_eqv, s390_vec_eqv_b8, s390_vec_eqv_dbl_c, B_VXE, BT_FN_OV4SI_OV4SI_OV4SI)
OB_DEF_VAR (s390_vec_eqv_b8, s390_vnx, 0, 0, BT_OV_BV16QI_BV16QI_BV16QI)
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 2f945eb..1a99063 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -41,3 +41,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index acbdf66..289e018 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -173,6 +173,7 @@ extern bool s390_const_operand_ok (tree, int, int, tree);
/* s390-d.c routines */
extern void s390_d_target_versions (void);
+extern void s390_d_register_target_info (void);
/* Pass management. */
namespace gcc { class context; }
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index f7b1c03..a9c945c 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -734,15 +734,38 @@ s390_const_operand_ok (tree arg, int argnum, int op_flags, tree decl)
{
if (O_UIMM_P (op_flags))
{
- int bitwidths[] = { 1, 2, 3, 4, 5, 8, 12, 16, 32 };
- int bitwidth = bitwidths[op_flags - O_U1];
+ unsigned HOST_WIDE_INT bitwidths[] = { 1, 2, 3, 4, 5, 8, 12, 16, 32, 4, 4 };
+ unsigned HOST_WIDE_INT bitmasks[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 12 };
+ unsigned HOST_WIDE_INT bitwidth = bitwidths[op_flags - O_U1];
+ unsigned HOST_WIDE_INT bitmask = bitmasks[op_flags - O_U1];
if (!tree_fits_uhwi_p (arg)
- || tree_to_uhwi (arg) > (HOST_WIDE_INT_1U << bitwidth) - 1)
+ || tree_to_uhwi (arg) > (HOST_WIDE_INT_1U << bitwidth) - 1
+ || (bitmask && tree_to_uhwi (arg) & ~bitmask))
{
- error ("constant argument %d for builtin %qF is out of range "
- "(0..%wu)", argnum, decl,
- (HOST_WIDE_INT_1U << bitwidth) - 1);
+ if (bitmask)
+ {
+ gcc_assert (bitmask < 16);
+ char values[120] = "";
+
+ for (unsigned HOST_WIDE_INT i = 0; i <= bitmask; i++)
+ {
+ char buf[5];
+ if (i & ~bitmask)
+ continue;
+ int ret = snprintf (buf, 5, HOST_WIDE_INT_PRINT_UNSIGNED, i & bitmask);
+ gcc_assert (ret < 5);
+ strcat (values, buf);
+ if (i < bitmask)
+ strcat (values, ", ");
+ }
+ error ("constant argument %d for builtin %qF is invalid (%s)",
+ argnum, decl, values);
+ }
+ else
+ error ("constant argument %d for builtin %qF is out of range (0..%wu)",
+ argnum, decl, (HOST_WIDE_INT_1U << bitwidth) - 1);
+
return false;
}
}
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 991af96..3b87616 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -247,8 +247,9 @@ enum processor_flags
/* Target CPU builtins. */
#define TARGET_CPU_CPP_BUILTINS() s390_cpu_cpp_builtins (pfile)
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS s390_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO s390_d_register_target_info
#ifdef DEFAULT_TARGET_64BIT
#define TARGET_DEFAULT (MASK_64BIT | MASK_ZARCH | MASK_HARD_DFP \
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 0eb663b..cfb8dae 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -48,3 +48,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index ef94d4f..ad875cc 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -113,5 +113,6 @@ extern rtl_opt_pass *make_pass_work_around_errata (gcc::context *);
/* Routines implemented in sparc-d.c */
extern void sparc_d_target_versions (void);
+extern void sparc_d_register_target_info (void);
#endif /* __SPARC_PROTOS_H__ */
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index cec2f5a..4834575 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -27,8 +27,9 @@ along with GCC; see the file COPYING3. If not see
#define TARGET_CPU_CPP_BUILTINS() sparc_target_macros ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS sparc_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO sparc_d_register_target_info
/* Specify this in a cover file to provide bi-architecture (32/64) support. */
/* #define SPARC_BI_ARCH */
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9145630..e508222 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,45 @@
+2021-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/100078
+ PR c++/93085
+ * pt.c (uses_outer_template_parms): Also look at default
+ template argument.
+
+2021-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/93314
+ * semantics.c (finish_id_expression_1): Clear cp_unevaluated_operand
+ for a non-static data member in a constant-expression.
+
+2021-04-14 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/83476
+ PR c++/99885
+ * pt.c (deducible_expression): Look through implicit
+ INDIRECT_REFs as well.
+
+2021-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/99478
+ * parser.c (cp_parser_lambda_expression): Reject lambda
+ in template parameter type.
+
+2021-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/90674
+ * decl.c (duplicate_decls): Don't propagate
+ DECL_INITIALIZED_IN_CLASS_P to a specialization.
+
+2021-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/88742
+ PR c++/49951
+ PR c++/58123
+ * semantics.c (set_cleanup_locs): New.
+ (do_poplevel): Call it.
+ * parser.c (cp_parser_compound_statement): Consume the }
+ before finish_compound_stmt.
+
2021-04-13 Jason Merrill <jason@redhat.com>
PR c++/100032
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 59df794..0f119a5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10856,6 +10856,7 @@ uses_outer_template_parms (tree decl)
for (int i = TREE_VEC_LENGTH (parms) - 1; i >= 0; --i)
{
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+ tree defarg = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
if (TREE_CODE (parm) == PARM_DECL
&& for_each_template_parm (TREE_TYPE (parm),
template_parm_outer_level,
@@ -10864,6 +10865,10 @@ uses_outer_template_parms (tree decl)
if (TREE_CODE (parm) == TEMPLATE_DECL
&& uses_outer_template_parms (parm))
return true;
+ if (defarg
+ && for_each_template_parm (defarg, template_parm_outer_level,
+ &depth, NULL, /*nondeduced*/true))
+ return true;
}
}
tree ci = get_constraints (decl);
@@ -21902,8 +21907,10 @@ static bool uses_deducible_template_parms (tree type);
static bool
deducible_expression (tree expr)
{
- /* Strip implicit conversions. */
- while (CONVERT_EXPR_P (expr) || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
+ /* Strip implicit conversions and implicit INDIRECT_REFs. */
+ while (CONVERT_EXPR_P (expr)
+ || TREE_CODE (expr) == VIEW_CONVERT_EXPR
+ || REFERENCE_REF_P (expr))
expr = TREE_OPERAND (expr, 0);
return (TREE_CODE (expr) == TEMPLATE_PARM_INDEX);
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 1257722..4520181 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4093,6 +4093,12 @@ finish_id_expression_1 (tree id_expression,
cp_warn_deprecated_use_scopes (scope);
+ /* In a constant-expression context, turn off cp_unevaluated_operand
+ so finish_non_static_data_member will complain (93314). */
+ auto eval = make_temp_override (cp_unevaluated_operand);
+ if (integral_constant_expression_p && TREE_CODE (decl) == FIELD_DECL)
+ cp_unevaluated_operand = 0;
+
if (TYPE_P (scope))
decl = finish_qualified_id_expr (scope,
decl,
@@ -4106,6 +4112,10 @@ finish_id_expression_1 (tree id_expression,
}
else if (TREE_CODE (decl) == FIELD_DECL)
{
+ auto eval = make_temp_override (cp_unevaluated_operand);
+ if (integral_constant_expression_p)
+ cp_unevaluated_operand = 0;
+
/* Since SCOPE is NULL here, this is an unqualified name.
Access checking has been performed during name lookup
already. Turn off checking to avoid duplicate errors. */
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 11dee7d..50d0f1e 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -261,6 +261,17 @@ original_type (tree t)
return cp_build_qualified_type (t, quals);
}
+/* Merge the attributes of type OTHER_TYPE into the attributes of type TYPE
+ and return a variant of TYPE with the merged attributes. */
+
+static tree
+merge_type_attributes_from (tree type, tree other_type)
+{
+ tree attrs = targetm.merge_type_attributes (type, other_type);
+ attrs = restrict_type_identity_attributes_to (attrs, TYPE_ATTRIBUTES (type));
+ return cp_build_type_attribute_variant (type, attrs);
+}
+
/* Return the common type for two arithmetic types T1 and T2 under the
usual arithmetic conversions. The default conversions have already
been applied, and enumerated types converted to their compatible
@@ -320,9 +331,9 @@ cp_common_type (tree t1, tree t2)
/* When we get here we should have two vectors of the same size.
Just prefer the unsigned one if present. */
if (TYPE_UNSIGNED (t1))
- return build_type_attribute_variant (t1, attributes);
+ return merge_type_attributes_from (t1, t2);
else
- return build_type_attribute_variant (t2, attributes);
+ return merge_type_attributes_from (t2, t1);
}
/* If only one is real, use it as the result. */
diff --git a/gcc/cse.c b/gcc/cse.c
index 37c6959..df191d5 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -2637,6 +2637,11 @@ exp_equiv_p (const_rtx x, const_rtx y, int validate, bool for_gcse)
CASE_CONST_UNIQUE:
return x == y;
+ case CONST_VECTOR:
+ if (!same_vector_encodings_p (x, y))
+ return false;
+ break;
+
case LABEL_REF:
return label_ref_label (x) == label_ref_label (y);
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 2d34a91..779874e 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -1048,6 +1048,11 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
case DEBUG_EXPR:
return 0;
+ case CONST_VECTOR:
+ if (!same_vector_encodings_p (x, y))
+ return false;
+ break;
+
case DEBUG_IMPLICIT_PTR:
return DEBUG_IMPLICIT_PTR_DECL (x)
== DEBUG_IMPLICIT_PTR_DECL (y);
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 11206f2..fe89d7b 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,40 @@
+2021-04-14 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * d-target.cc (Target::_init): Call new targetdm hook to register OS
+ specific target info keys.
+ * d-target.def (d_register_os_target_info): New hook.
+
+2021-04-14 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * d-builtins.cc (d_add_builtin_version): Remove all setting of
+ target-specific global.params.
+ * typeinfo.cc (create_typeinfo): Don't add argType fields to
+ TypeInfo_Struct.
+
+2021-04-14 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/99914
+ * decl.cc (DeclVisitor::visit (StructDeclaration *)): Don't set
+ DECL_INSTANTIATED on static initializer declarations.
+ (DeclVisitor::visit (ClassDeclaration *)): Likewise.
+ (DeclVisitor::visit (EnumDeclaration *)): Likewise.
+ (d_finish_decl): Move call to set_linkage_for_decl to...
+ (declare_extern_var): ...here.
+
+2021-04-14 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * d-target.cc (Target::_init): Call new targetdm hook to register CPU
+ specific target info keys.
+ * d-target.def (d_register_cpu_target_info): New hook.
+
+2021-04-14 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * d-target.cc (Target::systemLinkage): Return LINKwindows if
+ d_has_stdcall_convention applies to LINKsystem.
+ * d-target.def (d_has_stdcall_convention): New hook.
+ * types.cc (TypeVisitor::visit (TypeFunction *)): Insert "stdcall"
+ function attribute if d_has_stdcall_convention applies to LINKwindows.
+
2021-04-10 Iain Buclaw <ibuclaw@gdcproject.org>
* dmd/MERGE: Merge upstream dmd 0450061c8.
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index ce09861..400bce0 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -418,25 +418,6 @@ d_eval_constant_expression (const Loc &loc, tree cst)
void
d_add_builtin_version (const char* ident)
{
- /* For now, we need to tell the D frontend what platform is being targeted.
- This should be removed once the frontend has been fixed. */
- if (strcmp (ident, "linux") == 0)
- global.params.isLinux = true;
- else if (strcmp (ident, "OSX") == 0)
- global.params.isOSX = true;
- else if (strcmp (ident, "Windows") == 0)
- global.params.isWindows = true;
- else if (strcmp (ident, "FreeBSD") == 0)
- global.params.isFreeBSD = true;
- else if (strcmp (ident, "OpenBSD") == 0)
- global.params.isOpenBSD = true;
- else if (strcmp (ident, "Solaris") == 0)
- global.params.isSolaris = true;
- /* The is64bit field only refers to x86_64 target. */
- else if (strcmp (ident, "X86_64") == 0)
- global.params.is64bit = true;
- /* No other fields are required to be set for the frontend. */
-
VersionCondition::addPredefinedGlobalIdent (ident);
}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index a1dc2ee..be354d9 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -198,6 +198,8 @@ Target::_init (const Param &)
/* Initialize target info tables, the keys required by the language are added
last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
d_add_target_info_handlers (d_language_target_info);
}
@@ -435,11 +437,21 @@ TargetCPP::derivedClassOffset(ClassDeclaration *base_class)
return base_class->structsize;
}
-/* Return the default system linkage for the target. */
+/* Return the default `extern (System)' linkage for the target. */
LINK
Target::systemLinkage (void)
{
+ unsigned link_system, link_windows;
+
+ if (targetdm.d_has_stdcall_convention (&link_system, &link_windows))
+ {
+ /* In [attribute/linkage], `System' is the same as `Windows' on Windows
+ platforms, and `C' on other platforms. */
+ if (link_system)
+ return LINKwindows;
+ }
+
return LINKc;
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a1..aa6bf55 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
@@ -71,5 +91,18 @@ as the name of the symbol indicating the end address of the module info\n\
section",
const char *, NULL)
+/* The "stdcall" convention is really supported on 32-bit x86/Windows only.
+ The following hook is a helper to determine whether to apply the attribute
+ on declarations with `extern(System)' and `extern(Windows)' linkage. */
+DEFHOOK
+(d_has_stdcall_convention,
+ "Returns @code{true} if the target supports the stdcall calling convention.\n\
+The hook should also set @var{link_system} to @code{1} if the @code{stdcall}\n\
+attribute should be applied to functions with @code{extern(System)} linkage,\n\
+and @var{link_windows} to @code{1} to apply @code{stdcall} to functions with\n\
+@code{extern(Windows)} linkage.",
+ bool, (unsigned int *link_system, unsigned int *link_windows),
+ hook_bool_uintp_uintp_false)
+
/* Close the 'struct gcc_targetdm' definition. */
HOOK_VECTOR_END (C90_EMPTY_HACK)
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index b07068e..8948e40 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -387,7 +387,6 @@ public:
/* Generate static initializer. */
d->sinit = aggregate_initializer_decl (d);
DECL_INITIAL (d->sinit) = layout_struct_initializer (d);
- DECL_INSTANTIATED (d->sinit) = (d->isInstantiated () != NULL);
d_finish_decl (d->sinit);
/* Put out the members. There might be static constructors in the members
@@ -500,7 +499,6 @@ public:
/* Generate static initializer. */
DECL_INITIAL (d->sinit) = layout_class_initializer (d);
- DECL_INSTANTIATED (d->sinit) = (d->isInstantiated () != NULL);
d_finish_decl (d->sinit);
/* Put out the TypeInfo. */
@@ -611,7 +609,6 @@ public:
/* Generate static initializer. */
d->sinit = enum_initializer_decl (d);
DECL_INITIAL (d->sinit) = build_expr (tc->sym->defaultval, true);
- DECL_INSTANTIATED (d->sinit) = (d->isInstantiated () != NULL);
d_finish_decl (d->sinit);
}
@@ -1379,6 +1376,8 @@ declare_extern_var (tree ident, tree type)
/* The decl has not been defined -- yet. */
DECL_EXTERNAL (decl) = 1;
+ set_linkage_for_decl (decl);
+
return decl;
}
@@ -1540,7 +1539,6 @@ d_finish_decl (tree decl)
set_decl_tls_model (decl, decl_default_tls_model (decl));
relayout_decl (decl);
- set_linkage_for_decl (decl);
if (flag_checking && DECL_INITIAL (decl))
{
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index f8ffcbf..503480b 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -1562,9 +1562,6 @@ create_typeinfo (Type *type, Module *mod)
case TK_STRUCT_TYPE:
if (!tinfo_types[tk])
{
- /* Some ABIs add extra TypeInfo fields on the end. */
- tree argtype = global.params.is64bit ? ptr_type_node : NULL_TREE;
-
ident = Identifier::idPool ("TypeInfo_Struct");
make_internal_typeinfo (tk, ident,
array_type_node, array_type_node,
@@ -1572,7 +1569,7 @@ create_typeinfo (Type *type, Module *mod)
ptr_type_node, ptr_type_node,
d_uint_type, ptr_type_node,
ptr_type_node, d_uint_type,
- ptr_type_node, argtype, argtype, NULL);
+ ptr_type_node, NULL);
}
t->vtinfo = TypeInfoStructDeclaration::create (t);
break;
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index ec61740..3b121f5 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "attribs.h"
#include "d-tree.h"
+#include "d-target.h"
/* Return the signed or unsigned version of TYPE, an integral type, the
@@ -800,13 +801,19 @@ public:
switch (t->linkage)
{
case LINKwindows:
- /* [attribute/linkage]
+ {
+ /* [attribute/linkage]
- The Windows convention is distinct from the C convention only
- on Win32, where it is equivalent to the stdcall convention. */
- if (!global.params.is64bit)
- t->ctype = insert_type_attribute (t->ctype, "stdcall");
- break;
+ The Windows convention is distinct from the C convention only
+ on Win32, where it is equivalent to the stdcall convention. */
+ unsigned link_system, link_windows;
+ if (targetdm.d_has_stdcall_convention (&link_system, &link_windows))
+ {
+ if (link_windows)
+ t->ctype = insert_type_attribute (t->ctype, "stdcall");
+ }
+ break;
+ }
case LINKc:
case LINKcpp:
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 671db2d..23e155f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13049,7 +13049,6 @@ also use other heuristics to decide whether if-conversion is likely to be
profitable.
@item max-rtl-if-conversion-predictable-cost
-@itemx max-rtl-if-conversion-unpredictable-cost
RTL if-conversion will try to remove conditional branches around a block
and replace them with conditionally executed instructions. These parameters
give the maximum permissible cost for the sequence that would be generated
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b272fa4..97c8eeb 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10808,6 +10808,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
@@ -10828,6 +10842,14 @@ as the name of the symbol indicating the end address of the module info
section
@end deftypevr
+@deftypefn {D Target Hook} bool TARGET_D_HAS_STDCALL_CONVENTION (unsigned int *@var{link_system}, unsigned int *@var{link_windows})
+Returns @code{true} if the target supports the stdcall calling convention.
+The hook should also set @var{link_system} to @code{1} if the @code{stdcall}
+attribute should be applied to functions with @code{extern(System)} linkage,
+and @var{link_windows} to @code{1} to apply @code{stdcall} to functions with
+@code{extern(Windows)} linkage.
+@end deftypefn
+
@node Named Address Spaces
@section Adding support for named address spaces
@cindex named address spaces
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index bf724dc..e2d49ee 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7357,12 +7357,18 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
@hook TARGET_D_MINFO_END_NAME
+@hook TARGET_D_HAS_STDCALL_CONVENTION
+
@node Named Address Spaces
@section Adding support for named address spaces
@cindex named address spaces
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 8fc1159..1f8578c 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,8 @@
+2021-04-14 Martin Liska <mliska@suse.cz>
+
+ * intrinsic.texi: The table has first column empty and it makes
+ trouble when processing makeinfo --xml output.
+
2021-04-09 Tobias Burnus <tobias@codesourcery.com>
PR fortran/99817
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index e982374..6d61bf4 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -4391,7 +4391,7 @@ get_iso_c_binding_dt (int sym_id)
if (dt_list->from_intmod != INTMOD_NONE
&& dt_list->intmod_sym_id == sym_id)
return dt_list;
-
+
dt_list = dt_list->dt_next;
}
}
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index be5eb89..ca90142 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -1403,9 +1403,6 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss,
desc = gfc_create_var (type, "atmp");
GFC_DECL_PACKED_ARRAY (desc) = 1;
- info->descriptor = desc;
- size = gfc_index_one_node;
-
/* Emit a DECL_EXPR for the variable sized array type in
GFC_TYPE_ARRAY_DATAPTR_TYPE so the gimplification of its type
sizes works correctly. */
@@ -1416,9 +1413,40 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss,
gfc_add_expr_to_block (pre, build1 (DECL_EXPR,
arraytype, TYPE_NAME (arraytype)));
- /* Fill in the array dtype. */
- tmp = gfc_conv_descriptor_dtype (desc);
- gfc_add_modify (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
+ if (class_expr != NULL_TREE)
+ {
+ tree class_data;
+ tree dtype;
+
+ /* Create a class temporary. */
+ tmp = gfc_create_var (TREE_TYPE (class_expr), "ctmp");
+ gfc_add_modify (pre, tmp, class_expr);
+
+ /* Assign the new descriptor to the _data field. This allows the
+ vptr _copy to be used for scalarized assignment since the class
+ temporary can be found from the descriptor. */
+ class_data = gfc_class_data_get (tmp);
+ tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
+ TREE_TYPE (desc), desc);
+ gfc_add_modify (pre, class_data, tmp);
+
+ /* Take the dtype from the class expression. */
+ dtype = gfc_conv_descriptor_dtype (gfc_class_data_get (class_expr));
+ tmp = gfc_conv_descriptor_dtype (class_data);
+ gfc_add_modify (pre, tmp, dtype);
+
+ /* Point desc to the class _data field. */
+ desc = class_data;
+ }
+ else
+ {
+ /* Fill in the array dtype. */
+ tmp = gfc_conv_descriptor_dtype (desc);
+ gfc_add_modify (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
+ }
+
+ info->descriptor = desc;
+ size = gfc_index_one_node;
/*
Fill in the bounds and stride. This is a packed array, so:
@@ -3424,134 +3452,73 @@ conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i,
static bool
build_class_array_ref (gfc_se *se, tree base, tree index)
{
- tree type;
tree size;
- tree offset;
tree decl = NULL_TREE;
tree tmp;
gfc_expr *expr = se->ss->info->expr;
- gfc_ref *ref;
- gfc_ref *class_ref = NULL;
+ gfc_expr *class_expr;
gfc_typespec *ts;
+ gfc_symbol *sym;
- if (se->expr && DECL_P (se->expr) && DECL_LANG_SPECIFIC (se->expr)
- && GFC_DECL_SAVED_DESCRIPTOR (se->expr)
- && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (se->expr))))
- decl = se->expr;
+ tmp = !VAR_P (base) ? gfc_get_class_from_expr (base) : NULL_TREE;
+
+ if (tmp != NULL_TREE)
+ decl = tmp;
else
{
- if (expr == NULL
+ /* The base expression does not contain a class component, either
+ because it is a temporary array or array descriptor. Class
+ array functions are correctly resolved above. */
+ if (!expr
|| (expr->ts.type != BT_CLASS
- && !gfc_is_class_array_function (expr)
&& !gfc_is_class_array_ref (expr, NULL)))
return false;
- if (expr->symtree && expr->symtree->n.sym->ts.type == BT_CLASS)
- ts = &expr->symtree->n.sym->ts;
- else
- ts = NULL;
-
- for (ref = expr->ref; ref; ref = ref->next)
- {
- if (ref->type == REF_COMPONENT
- && ref->u.c.component->ts.type == BT_CLASS
- && ref->next && ref->next->type == REF_COMPONENT
- && strcmp (ref->next->u.c.component->name, "_data") == 0
- && ref->next->next
- && ref->next->next->type == REF_ARRAY
- && ref->next->next->u.ar.type != AR_ELEMENT)
- {
- ts = &ref->u.c.component->ts;
- class_ref = ref;
- break;
- }
- }
+ /* Obtain the expression for the class entity or component that is
+ followed by an array reference, which is not an element, so that
+ the span of the array can be obtained. */
+ class_expr = gfc_find_and_cut_at_last_class_ref (expr, false, &ts);
- if (ts == NULL)
+ if (!ts)
return false;
- }
- if (class_ref == NULL && expr && expr->symtree->n.sym->attr.function
- && expr->symtree->n.sym == expr->symtree->n.sym->result
- && expr->symtree->n.sym->backend_decl == current_function_decl)
- {
- decl = gfc_get_fake_result_decl (expr->symtree->n.sym, 0);
- }
- else if (expr && gfc_is_class_array_function (expr))
- {
- size = NULL_TREE;
- decl = NULL_TREE;
- for (tmp = base; tmp; tmp = TREE_OPERAND (tmp, 0))
- {
- tree type;
- type = TREE_TYPE (tmp);
- while (type)
- {
- if (GFC_CLASS_TYPE_P (type))
- decl = tmp;
- if (type != TYPE_CANONICAL (type))
- type = TYPE_CANONICAL (type);
- else
- type = NULL_TREE;
- }
- if (VAR_P (tmp))
- break;
+ sym = (!class_expr && expr) ? expr->symtree->n.sym : NULL;
+ if (sym && sym->attr.function
+ && sym == sym->result
+ && sym->backend_decl == current_function_decl)
+ /* The temporary is the data field of the class data component
+ of the current function. */
+ decl = gfc_get_fake_result_decl (sym, 0);
+ else if (sym)
+ {
+ if (decl == NULL_TREE)
+ decl = expr->symtree->n.sym->backend_decl;
+ /* For class arrays the tree containing the class is stored in
+ GFC_DECL_SAVED_DESCRIPTOR of the sym's backend_decl.
+ For all others it's sym's backend_decl directly. */
+ if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
+ decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
}
+ else
+ decl = gfc_get_class_from_gfc_expr (class_expr);
- if (decl == NULL_TREE)
- return false;
+ if (POINTER_TYPE_P (TREE_TYPE (decl)))
+ decl = build_fold_indirect_ref_loc (input_location, decl);
- se->class_vptr = gfc_evaluate_now (gfc_class_vptr_get (decl), &se->pre);
- }
- else if (class_ref == NULL)
- {
- if (decl == NULL_TREE)
- decl = expr->symtree->n.sym->backend_decl;
- /* For class arrays the tree containing the class is stored in
- GFC_DECL_SAVED_DESCRIPTOR of the sym's backend_decl.
- For all others it's sym's backend_decl directly. */
- if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
- decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
- }
- else
- {
- /* Remove everything after the last class reference, convert the
- expression and then recover its tailend once more. */
- gfc_se tmpse;
- ref = class_ref->next;
- class_ref->next = NULL;
- gfc_init_se (&tmpse, NULL);
- gfc_conv_expr (&tmpse, expr);
- gfc_add_block_to_block (&se->pre, &tmpse.pre);
- decl = tmpse.expr;
- class_ref->next = ref;
+ if (!GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
+ return false;
}
- if (POINTER_TYPE_P (TREE_TYPE (decl)))
- decl = build_fold_indirect_ref_loc (input_location, decl);
-
- if (!GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
- return false;
+ se->class_vptr = gfc_evaluate_now (gfc_class_vptr_get (decl), &se->pre);
size = gfc_class_vtab_size_get (decl);
-
/* For unlimited polymorphic entities then _len component needs to be
multiplied with the size. */
size = gfc_resize_class_size_with_len (&se->pre, decl, size);
-
size = fold_convert (TREE_TYPE (index), size);
- /* Build the address of the element. */
- type = TREE_TYPE (TREE_TYPE (base));
- offset = fold_build2_loc (input_location, MULT_EXPR,
- gfc_array_index_type,
- index, size);
- tmp = gfc_build_addr_expr (pvoid_type_node, base);
- tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
- tmp = fold_convert (build_pointer_type (type), tmp);
-
/* Return the element in the se expression. */
- se->expr = build_fold_indirect_ref_loc (input_location, tmp);
+ se->expr = gfc_build_spanned_array_ref (base, index, size);
return true;
}
@@ -10280,23 +10247,10 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
}
else if (expr1->ts.type == BT_CLASS)
{
- tmp = expr1->rank ? gfc_get_class_from_expr (desc) : NULL_TREE;
- if (tmp == NULL_TREE)
- tmp = gfc_get_class_from_gfc_expr (expr1);
-
- if (tmp != NULL_TREE)
- {
- tmp2 = gfc_class_vptr_get (tmp);
- cond = fold_build2_loc (input_location, NE_EXPR,
- logical_type_node, tmp2,
- build_int_cst (TREE_TYPE (tmp2), 0));
- elemsize1 = gfc_class_vtab_size_get (tmp);
- elemsize1 = fold_build3_loc (input_location, COND_EXPR,
- gfc_array_index_type, cond,
- elemsize1, gfc_index_zero_node);
- }
- else
- elemsize1 = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&CLASS_DATA (expr1)->ts));
+ /* Unfortunately, the lhs vptr is set too early in many cases.
+ Play it safe by using the descriptor element length. */
+ tmp = gfc_conv_descriptor_elem_len (desc);
+ elemsize1 = fold_convert (gfc_array_index_type, tmp);
}
else
elemsize1 = NULL_TREE;
@@ -10770,11 +10724,11 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
/* We already set the dtype in the case of deferred character
- length arrays and unlimited polymorphic arrays. */
+ length arrays and class lvalues. */
if (!(GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))
&& ((expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
|| coarray))
- && !UNLIMITED_POLY (expr1))
+ && expr1->ts.type != BT_CLASS)
{
tmp = gfc_conv_descriptor_dtype (desc);
gfc_add_modify (&alloc_block, tmp, gfc_get_dtype (TREE_TYPE (desc)));
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 2fa17b3..213f32b 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -380,15 +380,20 @@ gfc_vptr_size_get (tree vptr)
#undef VTABLE_FINAL_FIELD
-/* Search for the last _class ref in the chain of references of this
- expression and cut the chain there. Albeit this routine is similiar
- to class.c::gfc_add_component_ref (), is there a significant
- difference: gfc_add_component_ref () concentrates on an array ref to
- be the last ref in the chain. This routine is oblivious to the kind
- of refs following. */
+/* IF ts is null (default), search for the last _class ref in the chain
+ of references of the expression and cut the chain there. Although
+ this routine is similiar to class.c:gfc_add_component_ref (), there
+ is a significant difference: gfc_add_component_ref () concentrates
+ on an array ref that is the last ref in the chain and is oblivious
+ to the kind of refs following.
+ ELSE IF ts is non-null the cut is at the class entity or component
+ that is followed by an array reference, which is not an element.
+ These calls come from trans-array.c:build_class_array_ref, which
+ handles scalarized class array references.*/
gfc_expr *
-gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold)
+gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold,
+ gfc_typespec **ts)
{
gfc_expr *base_expr;
gfc_ref *ref, *class_ref, *tail = NULL, *array_ref;
@@ -396,27 +401,59 @@ gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold)
/* Find the last class reference. */
class_ref = NULL;
array_ref = NULL;
- for (ref = e->ref; ref; ref = ref->next)
+
+ if (ts)
{
- if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
- array_ref = ref;
+ if (e->symtree
+ && e->symtree->n.sym->ts.type == BT_CLASS)
+ *ts = &e->symtree->n.sym->ts;
+ else
+ *ts = NULL;
+ }
- if (ref->type == REF_COMPONENT
- && ref->u.c.component->ts.type == BT_CLASS)
+ for (ref = e->ref; ref; ref = ref->next)
+ {
+ if (ts)
{
- /* Component to the right of a part reference with nonzero rank
- must not have the ALLOCATABLE attribute. If attempts are
- made to reference such a component reference, an error results
- followed by an ICE. */
- if (array_ref && CLASS_DATA (ref->u.c.component)->attr.allocatable)
- return NULL;
- class_ref = ref;
+ if (ref->type == REF_COMPONENT
+ && ref->u.c.component->ts.type == BT_CLASS
+ && ref->next && ref->next->type == REF_COMPONENT
+ && !strcmp (ref->next->u.c.component->name, "_data")
+ && ref->next->next
+ && ref->next->next->type == REF_ARRAY
+ && ref->next->next->u.ar.type != AR_ELEMENT)
+ {
+ *ts = &ref->u.c.component->ts;
+ class_ref = ref;
+ break;
+ }
+
+ if (ref->next == NULL)
+ break;
}
+ else
+ {
+ if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
+ array_ref = ref;
- if (ref->next == NULL)
- break;
+ if (ref->type == REF_COMPONENT
+ && ref->u.c.component->ts.type == BT_CLASS)
+ {
+ /* Component to the right of a part reference with nonzero
+ rank must not have the ALLOCATABLE attribute. If attempts
+ are made to reference such a component reference, an error
+ results followed by an ICE. */
+ if (array_ref
+ && CLASS_DATA (ref->u.c.component)->attr.allocatable)
+ return NULL;
+ class_ref = ref;
+ }
+ }
}
+ if (ts && *ts == NULL)
+ return NULL;
+
/* Remove and store all subsequent references after the
CLASS reference. */
if (class_ref)
@@ -10005,17 +10042,20 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
gfc_add_modify (&block, lse->expr, tmp);
}
/* If possible use the rhs vptr copy with trans_scalar_class_assign.... */
- else if (ts.type == BT_CLASS
- && !trans_scalar_class_assign (&block, lse, rse))
+ else if (ts.type == BT_CLASS)
{
gfc_add_block_to_block (&block, &lse->pre);
gfc_add_block_to_block (&block, &rse->pre);
- /* ...otherwise assignment suffices. Note the use of VIEW_CONVERT_EXPR
- for the lhs which ensures that class data rhs cast as a string assigns
- correctly. */
- tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
- TREE_TYPE (rse->expr), lse->expr);
- gfc_add_modify (&block, tmp, rse->expr);
+
+ if (!trans_scalar_class_assign (&block, lse, rse))
+ {
+ /* ...otherwise assignment suffices. Note the use of VIEW_CONVERT_EXPR
+ for the lhs which ensures that class data rhs cast as a string assigns
+ correctly. */
+ tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
+ TREE_TYPE (rse->expr), lse->expr);
+ gfc_add_modify (&block, tmp, rse->expr);
+ }
}
else if (ts.type != BT_CLASS)
{
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index ab53fc5..9e8e861 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -422,6 +422,9 @@ get_array_span (tree type, tree decl)
return NULL_TREE;
}
span = gfc_class_vtab_size_get (decl);
+ /* For unlimited polymorphic entities then _len component needs
+ to be multiplied with the size. */
+ span = gfc_resize_class_size_with_len (NULL, decl, span);
}
else if (GFC_DECL_PTR_ARRAY_P (decl))
{
@@ -439,13 +442,31 @@ get_array_span (tree type, tree decl)
}
+tree
+gfc_build_spanned_array_ref (tree base, tree offset, tree span)
+{
+ tree type;
+ tree tmp;
+ type = TREE_TYPE (TREE_TYPE (base));
+ offset = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_array_index_type,
+ offset, span);
+ tmp = gfc_build_addr_expr (pvoid_type_node, base);
+ tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
+ tmp = fold_convert (build_pointer_type (type), tmp);
+ if ((TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != ARRAY_TYPE)
+ || !TYPE_STRING_FLAG (type))
+ tmp = build_fold_indirect_ref_loc (input_location, tmp);
+ return tmp;
+}
+
+
/* Build an ARRAY_REF with its natural type. */
tree
gfc_build_array_ref (tree base, tree offset, tree decl, tree vptr)
{
tree type = TREE_TYPE (base);
- tree tmp;
tree span = NULL_TREE;
if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0)
@@ -488,18 +509,7 @@ gfc_build_array_ref (tree base, tree offset, tree decl, tree vptr)
/* If a non-null span has been generated reference the element with
pointer arithmetic. */
if (span != NULL_TREE)
- {
- offset = fold_build2_loc (input_location, MULT_EXPR,
- gfc_array_index_type,
- offset, span);
- tmp = gfc_build_addr_expr (pvoid_type_node, base);
- tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
- tmp = fold_convert (build_pointer_type (type), tmp);
- if ((TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != ARRAY_TYPE)
- || !TYPE_STRING_FLAG (type))
- tmp = build_fold_indirect_ref_loc (input_location, tmp);
- return tmp;
- }
+ return gfc_build_spanned_array_ref (base, offset, span);
/* Otherwise use a straightforward array reference. */
else
return build4_loc (input_location, ARRAY_REF, type, base, offset,
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 44cbfb6..8c6f82f 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -424,7 +424,8 @@ tree gfc_class_vptr_get (tree);
tree gfc_class_len_get (tree);
tree gfc_class_len_or_zero_get (tree);
tree gfc_resize_class_size_with_len (stmtblock_t *, tree, tree);
-gfc_expr * gfc_find_and_cut_at_last_class_ref (gfc_expr *, bool is_mold = false);
+gfc_expr * gfc_find_and_cut_at_last_class_ref (gfc_expr *, bool is_mold = false,
+ gfc_typespec **ts = NULL);
/* Get an accessor to the class' vtab's * field, when a class handle is
available. */
tree gfc_class_vtab_hash_get (tree);
@@ -622,6 +623,9 @@ tree gfc_build_addr_expr (tree, tree);
/* Build an ARRAY_REF. */
tree gfc_build_array_ref (tree, tree, tree, tree vptr = NULL_TREE);
+/* Build an array ref using pointer arithmetic. */
+tree gfc_build_spanned_array_ref (tree base, tree offset, tree span);
+
/* Creates a label. Decl is artificial if label_id == NULL_TREE. */
tree gfc_build_label_decl (tree);
diff --git a/gcc/gimple-builder.h b/gcc/gimple-builder.h
index 61cf08c..ae273ce 100644
--- a/gcc/gimple-builder.h
+++ b/gcc/gimple-builder.h
@@ -21,6 +21,8 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_GIMPLE_BUILDER_H
#define GCC_GIMPLE_BUILDER_H
+/* ??? This API is legacy and should not be used in new code. */
+
gassign *build_assign (enum tree_code, tree, int, tree lhs = NULL_TREE);
gassign *build_assign (enum tree_code, gimple *, int, tree lhs = NULL_TREE);
gassign *build_assign (enum tree_code, tree, tree, tree lhs = NULL_TREE);
diff --git a/gcc/jump.c b/gcc/jump.c
index 561dbb7..67b5c33 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -1777,6 +1777,11 @@ rtx_renumbered_equal_p (const_rtx x, const_rtx y)
CASE_CONST_UNIQUE:
return 0;
+ case CONST_VECTOR:
+ if (!same_vector_encodings_p (x, y))
+ return false;
+ break;
+
case LABEL_REF:
/* We can't assume nonlocal labels have their following insns yet. */
if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 62bcfc3..5c2a2d7 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -834,6 +834,11 @@ operands_match_p (rtx x, rtx y, int y_hard_regno)
CASE_CONST_UNIQUE:
return false;
+ case CONST_VECTOR:
+ if (!same_vector_encodings_p (x, y))
+ return false;
+ break;
+
case LABEL_REF:
return label_ref_label (x) == label_ref_label (y);
case SYMBOL_REF:
@@ -5797,10 +5802,14 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn,
mode = lra_reg_info[hard_regno].biggest_mode;
machine_mode reg_rtx_mode = GET_MODE (regno_reg_rtx[hard_regno]);
/* A reg can have a biggest_mode of VOIDmode if it was only ever seen as
- part of a multi-word register. In that case, just use the reg_rtx.
- Otherwise, limit the size to that of the biggest access in the
- function. */
- if (mode == VOIDmode)
+ part of a multi-word register. In that case, just use the reg_rtx
+ mode. Do the same also if the biggest mode was larger than a register
+ or we can not compare the modes. Otherwise, limit the size to that of
+ the biggest access in the function. */
+ if (mode == VOIDmode
+ || !ordered_p (GET_MODE_PRECISION (mode),
+ GET_MODE_PRECISION (reg_rtx_mode))
+ || paradoxical_subreg_p (mode, reg_rtx_mode))
{
original_reg = regno_reg_rtx[hard_regno];
mode = reg_rtx_mode;
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index ceb61bb..5903f75 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -306,7 +306,7 @@ lto_wpa_write_files (void)
cgraph_node *node;
/* Do body modifications needed for streaming before we fork out
worker processes. */
- FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
+ FOR_EACH_FUNCTION (node)
if (!node->clone_of && gimple_has_body_p (node->decl))
lto_prepare_function_for_streaming (node);
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index c7982bc..081fc50 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -370,6 +370,10 @@ rtx_writer::print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx)
print_rtx_head, m_indent * 2, "");
m_sawclose = 0;
}
+ if (GET_CODE (in_rtx) == CONST_VECTOR
+ && !GET_MODE_NUNITS (GET_MODE (in_rtx)).is_constant ()
+ && CONST_VECTOR_DUPLICATE_P (in_rtx))
+ fprintf (m_outfile, " repeat");
fputs (" [", m_outfile);
if (XVEC (in_rtx, idx) != NULL)
{
@@ -377,12 +381,32 @@ rtx_writer::print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx)
if (XVECLEN (in_rtx, idx))
m_sawclose = 1;
+ int barrier = XVECLEN (in_rtx, idx);
+ if (GET_CODE (in_rtx) == CONST_VECTOR
+ && !GET_MODE_NUNITS (GET_MODE (in_rtx)).is_constant ())
+ barrier = CONST_VECTOR_NPATTERNS (in_rtx);
+
for (int j = 0; j < XVECLEN (in_rtx, idx); j++)
{
int j1;
+ if (j == barrier)
+ {
+ fprintf (m_outfile, "\n%s%*s",
+ print_rtx_head, m_indent * 2, "");
+ if (!CONST_VECTOR_STEPPED_P (in_rtx))
+ fprintf (m_outfile, "repeat [");
+ else if (CONST_VECTOR_NPATTERNS (in_rtx) == 1)
+ fprintf (m_outfile, "stepped [");
+ else
+ fprintf (m_outfile, "stepped (interleave %d) [",
+ CONST_VECTOR_NPATTERNS (in_rtx));
+ m_indent += 2;
+ }
+
print_rtx (XVECEXP (in_rtx, idx, j));
- for (j1 = j + 1; j1 < XVECLEN (in_rtx, idx); j1++)
+ int limit = MIN (barrier, XVECLEN (in_rtx, idx));
+ for (j1 = j + 1; j1 < limit; j1++)
if (XVECEXP (in_rtx, idx, j) != XVECEXP (in_rtx, idx, j1))
break;
@@ -393,6 +417,12 @@ rtx_writer::print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx)
}
}
+ if (barrier < XVECLEN (in_rtx, idx))
+ {
+ m_indent -= 2;
+ fprintf (m_outfile, "\n%s%*s]", print_rtx_head, m_indent * 2, "");
+ }
+
m_indent -= 2;
}
if (m_sawclose)
diff --git a/gcc/reload.c b/gcc/reload.c
index 461fd02..e18e27c 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -2310,6 +2310,11 @@ operands_match_p (rtx x, rtx y)
CASE_CONST_UNIQUE:
return 0;
+ case CONST_VECTOR:
+ if (!same_vector_encodings_p (x, y))
+ return false;
+ break;
+
case LABEL_REF:
return label_ref_label (x) == label_ref_label (y);
case SYMBOL_REF:
diff --git a/gcc/rtl.c b/gcc/rtl.c
index 1aa794c..e4ae168 100644
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -466,6 +466,11 @@ rtx_equal_p_cb (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
CASE_CONST_UNIQUE:
return 0;
+ case CONST_VECTOR:
+ if (!same_vector_encodings_p (x, y))
+ return false;
+ break;
+
case DEBUG_IMPLICIT_PTR:
return DEBUG_IMPLICIT_PTR_DECL (x)
== DEBUG_IMPLICIT_PTR_DECL (y);
@@ -608,6 +613,11 @@ rtx_equal_p (const_rtx x, const_rtx y)
CASE_CONST_UNIQUE:
return 0;
+ case CONST_VECTOR:
+ if (!same_vector_encodings_p (x, y))
+ return false;
+ break;
+
case DEBUG_IMPLICIT_PTR:
return DEBUG_IMPLICIT_PTR_DECL (x)
== DEBUG_IMPLICIT_PTR_DECL (y);
diff --git a/gcc/rtl.h b/gcc/rtl.h
index a392721..398d745 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3087,6 +3087,23 @@ vec_series_p (const_rtx x, rtx *base_out, rtx *step_out)
return const_vec_series_p (x, base_out, step_out);
}
+/* Return true if CONST_VECTORs X and Y, which are known to have the same mode,
+ also have the same encoding. This means that they are equal whenever their
+ operands are equal. */
+
+inline bool
+same_vector_encodings_p (const_rtx x, const_rtx y)
+{
+ /* Don't be fussy about the encoding of constant-length vectors,
+ since XVECEXP (X, 0) and XVECEXP (Y, 0) list all the elements anyway. */
+ if (poly_uint64 (CONST_VECTOR_NUNITS (x)).is_constant ())
+ return true;
+
+ return (CONST_VECTOR_NPATTERNS (x) == CONST_VECTOR_NPATTERNS (y)
+ && (CONST_VECTOR_NELTS_PER_PATTERN (x)
+ == CONST_VECTOR_NELTS_PER_PATTERN (y)));
+}
+
/* Return the unpromoted (outer) mode of SUBREG_PROMOTED_VAR_P subreg X. */
inline scalar_int_mode
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1f79bc3..d9e9168 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,67 @@
+2021-04-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/pr99929_1.c: New file.
+ * gcc.target/aarch64/sve/pr99929_2.c: Likewise.
+
+2021-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/100078
+ * g++.dg/template/dependent-tmpl2.C: New test.
+
+2021-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/93314
+ * g++.dg/parse/uneval1.C: New test.
+
+2021-04-14 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/100066
+ * gcc.target/i386/pr100066.c: New.
+
+2021-04-14 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/pr86058.c: Limit to just x86_64.
+
+2021-04-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/99246
+ * gcc.target/aarch64/sve/acle/general/pr99246.c: New test.
+
+2021-04-14 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ * gcc.target/s390/zvector/imm-range-error-1.c: New test.
+ * gcc.target/s390/zvector/vec_msum_u128-1.c: New test.
+
+2021-04-14 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/83476
+ PR c++/99885
+ * g++.dg/cpp1z/class-deduction85.C: New test.
+ * g++.dg/template/ref11.C: New test.
+
+2021-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/99478
+ * g++.dg/cpp2a/lambda-uneval14.C: New test.
+
+2021-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/90674
+ * g++.dg/debug/defaulted1.C: New test.
+
+2021-04-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/88742
+ * g++.dg/debug/cleanup1.C: New test.
+ * c-c++-common/Wimplicit-fallthrough-6.c: Adjust diagnostic line.
+ * c-c++-common/Wimplicit-fallthrough-7.c: Likewise.
+ * g++.dg/cpp2a/constexpr-dtor3.C: Likewise.
+ * g++.dg/ext/constexpr-attr-cleanup1.C: Likewise.
+ * g++.dg/tm/inherit2.C: Likewise.
+ * g++.dg/tm/unsafe1.C: Likewise.
+ * g++.dg/warn/Wimplicit-fallthrough-1.C: Likewise.
+ * g++.dg/gcov/gcov-2.C: Adjust coverage counts.
+
2021-04-13 Martin Sebor <msebor@redhat.com>
PR tree-optimization/82800
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction85.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction85.C
new file mode 100644
index 0000000..0b22f8e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction85.C
@@ -0,0 +1,16 @@
+// PR c++/99885
+// { dg-do compile { target c++17 } }
+
+template <auto const& A>
+struct Foo {};
+
+template <auto const& A>
+struct Bar {
+ constexpr auto foo() const -> Foo<A> {
+ return {};
+ }
+};
+
+constexpr int a = 1;
+constexpr Bar<a> bar;
+Foo foo = bar.foo(); // <-- CTAD failure
diff --git a/gcc/testsuite/g++.dg/parse/uneval1.C b/gcc/testsuite/g++.dg/parse/uneval1.C
new file mode 100644
index 0000000..dfc1bb4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/uneval1.C
@@ -0,0 +1,14 @@
+// PR c++/93314
+
+struct S {
+ int m;
+ static int f() {
+ return sizeof(char[m]); // { dg-error "S::m" }
+ }
+};
+
+int main()
+{
+ return S().f()
+ + sizeof(char[S::m]); // { dg-error "S::m" }
+}
diff --git a/gcc/testsuite/g++.dg/template/dependent-tmpl2.C b/gcc/testsuite/g++.dg/template/dependent-tmpl2.C
new file mode 100644
index 0000000..040ddb4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/dependent-tmpl2.C
@@ -0,0 +1,10 @@
+// PR c++/100078
+// { dg-do compile { target c++11 } }
+
+template <bool> struct enable_if;
+template <typename Data> struct HashMapBucket {
+ template <typename T = Data>
+ static typename enable_if<T ::value>::type selectStructure() {
+ selectStructure();
+ }
+};
diff --git a/gcc/testsuite/g++.dg/template/ref11.C b/gcc/testsuite/g++.dg/template/ref11.C
new file mode 100644
index 0000000..c43c67e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ref11.C
@@ -0,0 +1,9 @@
+// PR c++/83476
+
+int n;
+template <int& V> struct A {};
+template <int& V> void f(A<V>);
+int main() {
+ A<n> a;
+ f(a);
+}
diff --git a/gcc/testsuite/g++.target/aarch64/advsimd-intrinsics/advsimd-intrinsics.exp b/gcc/testsuite/g++.target/aarch64/advsimd-intrinsics/advsimd-intrinsics.exp
new file mode 100644
index 0000000..268e221
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/advsimd-intrinsics/advsimd-intrinsics.exp
@@ -0,0 +1,72 @@
+# Copyright (C) 2014-2021 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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 Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an ARM or AArch64 target.
+if {![istarget arm*-*-*]
+ && ![istarget aarch64*-*-*]} then {
+ return
+}
+
+# Load support procs.
+load_lib g++-dg.exp
+
+# Initialize `dg'.
+load_lib c-torture.exp
+
+dg-init
+
+# The default action for a test is 'run'. Save current default.
+global dg-do-what-default
+set save-dg-do-what-default ${dg-do-what-default}
+
+# For ARM, make sure that we have a target compatible with NEON, and do
+# not attempt to run execution tests if the hardware doesn't support it.
+if {[istarget arm*-*-*]} then {
+ if {![check_effective_target_arm_neon_ok]} then {
+ return
+ }
+ if {![is-effective-target arm_neon_hw]} then {
+ set dg-do-what-default compile
+ } else {
+ set dg-do-what-default run
+ }
+} else {
+ set dg-do-what-default run
+}
+
+torture-init
+set-torture-options $C_TORTURE_OPTIONS {{}} $LTO_TORTURE_OPTIONS
+
+# Make sure Neon flags are provided, if necessary. Use fp16 if we can.
+# Use fp16 arithmetic operations if the hardware supports it.
+if {[check_effective_target_arm_v8_2a_fp16_neon_hw]} then {
+ set additional_flags [add_options_for_arm_v8_2a_fp16_neon ""]
+} elseif {[check_effective_target_arm_neon_fp16_ok]} then {
+ set additional_flags [add_options_for_arm_neon_fp16 ""]
+} else {
+ set additional_flags [add_options_for_arm_neon ""]
+}
+
+# Main loop.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] \
+ "" ${additional_flags}
+
+# All done.
+set dg-do-what-default ${save-dg-do-what-default}
+torture-finish
+dg-finish
diff --git a/gcc/testsuite/g++.target/aarch64/advsimd-intrinsics/pr98852.C b/gcc/testsuite/g++.target/aarch64/advsimd-intrinsics/pr98852.C
new file mode 100644
index 0000000..0cb5c89
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/advsimd-intrinsics/pr98852.C
@@ -0,0 +1,110 @@
+/* { dg-do compile } */
+
+#include <arm_neon.h>
+
+using int32_elt = __typeof(((int32x4_t *) nullptr)[0][0]);
+using uint32_elt = __typeof(((uint32x4_t *) nullptr)[0][0]);
+
+typedef int32_elt gnu_int32x4_t __attribute__((vector_size(16)));
+typedef uint32_elt gnu_uint32x4_t __attribute__((vector_size(16)));
+
+template<typename T> struct id;
+template<> struct id<gnu_int32x4_t> { static const int value = 1; };
+template<> struct id<gnu_uint32x4_t> { static const int value = 2; };
+template<> struct id<int32x4_t> { static const int value = 3; };
+template<> struct id<uint32x4_t> { static const int value = 4; };
+
+#define CHECK_TYPE(EXPR, TYPE) \
+ static_assert(id<decltype(EXPR)>::value == id<TYPE>::value, "foo")
+
+void
+f (gnu_int32x4_t sg, gnu_uint32x4_t ug, int32x4_t sn, uint32x4_t un, bool c)
+{
+ CHECK_TYPE (sg, gnu_int32x4_t);
+ CHECK_TYPE (ug, gnu_uint32x4_t);
+ CHECK_TYPE (sn, int32x4_t);
+ CHECK_TYPE (un, uint32x4_t);
+
+ CHECK_TYPE (sg + 1, gnu_int32x4_t);
+ CHECK_TYPE (ug + 1, gnu_uint32x4_t);
+ CHECK_TYPE (sn + 1, int32x4_t);
+ CHECK_TYPE (un + 1, uint32x4_t);
+
+ CHECK_TYPE (1 + sg, gnu_int32x4_t);
+ CHECK_TYPE (1 + ug, gnu_uint32x4_t);
+ CHECK_TYPE (1 + sn, int32x4_t);
+ CHECK_TYPE (1 + un, uint32x4_t);
+
+ CHECK_TYPE (sg + sg, gnu_int32x4_t);
+ CHECK_TYPE (ug + ug, gnu_uint32x4_t);
+ CHECK_TYPE (sn + sn, int32x4_t);
+ CHECK_TYPE (un + un, uint32x4_t);
+
+ // In C++, unlike C, the behavior is to prefer unsigned types over
+ // signed types.
+ CHECK_TYPE (sg + ug, gnu_uint32x4_t);
+ CHECK_TYPE (ug + sg, gnu_uint32x4_t);
+ CHECK_TYPE (sn + un, uint32x4_t);
+ CHECK_TYPE (un + sn, uint32x4_t);
+
+ // That being the case, it seems more consistent to do the same thing
+ // for mixed GNU and arm_neon.h operations.
+ CHECK_TYPE (sg + un, uint32x4_t);
+ CHECK_TYPE (un + sg, uint32x4_t);
+ CHECK_TYPE (sn + ug, gnu_uint32x4_t);
+ CHECK_TYPE (ug + sn, gnu_uint32x4_t);
+
+ // If the types have the same signedness, the traditional behavior is
+ // to pick the first type if it is unsigned and the second type otherwise.
+ // This is not necessarily sensible, but dates back to at least GCC 9.1.
+ // We could probably change it.
+ CHECK_TYPE (sg + sn, int32x4_t);
+ CHECK_TYPE (sn + sg, gnu_int32x4_t);
+ CHECK_TYPE (un + ug, uint32x4_t);
+ CHECK_TYPE (ug + un, gnu_uint32x4_t);
+
+ CHECK_TYPE (c ? sg + sg : sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug + ug : ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn + sn : sn, int32x4_t);
+ CHECK_TYPE (c ? un + un : un, uint32x4_t);
+
+ CHECK_TYPE (c ? sg + 1 : sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug + 1 : ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn + 1 : sn, int32x4_t);
+ CHECK_TYPE (c ? un + 1 : un, uint32x4_t);
+
+ CHECK_TYPE (c ? 1 + sg : sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? 1 + ug : ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? 1 + sn : sn, int32x4_t);
+ CHECK_TYPE (c ? 1 + un : un, uint32x4_t);
+
+ CHECK_TYPE (c ? sg : sg + sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug : ug + ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn : sn + sn, int32x4_t);
+ CHECK_TYPE (c ? un : un + un, uint32x4_t);
+
+ CHECK_TYPE (c ? sg : sg + 1, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug : ug + 1, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn : sn + 1, int32x4_t);
+ CHECK_TYPE (c ? un : un + 1, uint32x4_t);
+
+ CHECK_TYPE (c ? sg : 1 + sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug : 1 + ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn : 1 + sn, int32x4_t);
+ CHECK_TYPE (c ? un : 1 + un, uint32x4_t);
+
+ CHECK_TYPE (c ? sg + sg : sg + sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug + ug : ug + ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn + sn : sn + sn, int32x4_t);
+ CHECK_TYPE (c ? un + un : un + un, uint32x4_t);
+
+ CHECK_TYPE (c ? sg + sg : sg + 1, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug + ug : ug + 1, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn + sn : sn + 1, int32x4_t);
+ CHECK_TYPE (c ? un + un : un + 1, uint32x4_t);
+
+ CHECK_TYPE (c ? 1 + sg : sg + sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? 1 + ug : ug + ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? 1 + sn : sn + sn, int32x4_t);
+ CHECK_TYPE (c ? 1 + un : un + un, uint32x4_t);
+}
diff --git a/gcc/testsuite/gcc.dg/pr86058.c b/gcc/testsuite/gcc.dg/pr86058.c
index 0b030b0..89628c9 100644
--- a/gcc/testsuite/gcc.dg/pr86058.c
+++ b/gcc/testsuite/gcc.dg/pr86058.c
@@ -1,8 +1,9 @@
/* PR middle-end/86058 - TARGET_MEM_REF causing incorrect message for
-Wmaybe-uninitialized warning
- { dg-do compile }
+ The test fails on a number of non-x86 targets due to pr100073.
+ { dg-do compile { target i?86-*-* x86_64-*-* } }
{ dg-options "-O2 -Wuninitialized -Wmaybe-uninitialized" } */
-
+
extern void foo (int *);
void zip (int *out, int indx)
@@ -10,9 +11,9 @@ void zip (int *out, int indx)
int arr[10];
for (int i = 0; i < indx; ++i)
- out[i] = arr[i] + 1; // { dg-warning "'arr\\\[i]' may be used uninitialized" "pr?????" { xfail *-*-* } }
+ out[i] = arr[i] + 1; // { dg-warning "'arr\\\[i]' may be used uninitialized" "pr99944" { xfail *-*-* } }
// { dg-warning "'arr' may be used uninitialized" "actual" { target *-*-* } .-1 }
-
+
foo (arr);
foo (out);
}
diff --git a/gcc/testsuite/gcc.dg/pr93210.c b/gcc/testsuite/gcc.dg/pr93210.c
index ec4194b..134d32b 100644
--- a/gcc/testsuite/gcc.dg/pr93210.c
+++ b/gcc/testsuite/gcc.dg/pr93210.c
@@ -1,7 +1,7 @@
/* PR tree-optimization/93210 */
/* { dg-do run } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
-/* { dg-final { scan-tree-dump-times "return \[0-9]\[0-9a-fA-FxX]*;" 31 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "(?:return|<retval> =) \[0-9]\[0-9a-fA-FxX]*;" 31 "optimized" } } */
#ifdef __SIZEOF_INT128__
typedef unsigned __int128 L;
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/pr98852.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/pr98852.c
new file mode 100644
index 0000000..31e51b0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/pr98852.c
@@ -0,0 +1,129 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99" } */
+
+#include <arm_neon.h>
+
+typedef __typeof(((int32x4_t *) 0)[0][0]) int32_elt;
+typedef __typeof(((uint32x4_t *) 0)[0][0]) uint32_elt;
+
+typedef int32_elt gnu_int32x4_t __attribute__((vector_size(16)));
+typedef uint32_elt gnu_uint32x4_t __attribute__((vector_size(16)));
+
+#define X_gnu_int32x4_t 1
+#define X_gnu_uint32x4_t 2
+#define X_int32x4_t 3
+#define X_uint32x4_t 4
+
+#define CHECK(T) T: X_##T
+
+#define CHECK_TYPE(EXPR, TYPE) \
+ do { \
+ int x[_Generic (EXPR, \
+ CHECK (gnu_int32x4_t), \
+ CHECK (gnu_uint32x4_t), \
+ CHECK (int32x4_t), \
+ CHECK (uint32x4_t), \
+ default : 0) == X_##TYPE ? 1 : -1]; \
+ } while (0)
+
+void
+f (gnu_int32x4_t sg, gnu_uint32x4_t ug, int32x4_t sn, uint32x4_t un, int c)
+{
+ CHECK_TYPE (sg, gnu_int32x4_t);
+ CHECK_TYPE (ug, gnu_uint32x4_t);
+ CHECK_TYPE (sn, int32x4_t);
+ CHECK_TYPE (un, uint32x4_t);
+
+ CHECK_TYPE (sg + 1, gnu_int32x4_t);
+ CHECK_TYPE (ug + 1, gnu_uint32x4_t);
+ CHECK_TYPE (sn + 1, int32x4_t);
+ CHECK_TYPE (un + 1, uint32x4_t);
+
+ CHECK_TYPE (1 + sg, gnu_int32x4_t);
+ CHECK_TYPE (1 + ug, gnu_uint32x4_t);
+ CHECK_TYPE (1 + sn, int32x4_t);
+ CHECK_TYPE (1 + un, uint32x4_t);
+
+ CHECK_TYPE (sg + sg, gnu_int32x4_t);
+ CHECK_TYPE (ug + ug, gnu_uint32x4_t);
+ CHECK_TYPE (sn + sn, int32x4_t);
+ CHECK_TYPE (un + un, uint32x4_t);
+
+ /* Traditional behavior for mixed signs is to pick the signedness of the
+ first operand. We don't have any Arm-specific reason for preferring that
+ behavior, but including the tests helps to demonstrate the points in the
+ comments below. */
+ CHECK_TYPE (sg + ug, gnu_int32x4_t);
+ CHECK_TYPE (ug + sg, gnu_uint32x4_t);
+ CHECK_TYPE (sn + un, int32x4_t);
+ CHECK_TYPE (un + sn, uint32x4_t);
+
+ /* Nothing specifies the type of mixed GNU and arm_neon.h operations, but:
+
+ - it would be surprising if sg + un had a different signedness from
+ sg + ug
+
+ - it would also be mildly surprising if sg + un had a different type from
+ both of its operands
+
+ So in cases where the operands differ in both signedness and ABI, it seems
+ more consistent to ignore the ABI difference and apply the usual rules for
+ differences in sign. */
+ CHECK_TYPE (sg + un, gnu_int32x4_t);
+ CHECK_TYPE (ug + sn, gnu_uint32x4_t);
+ CHECK_TYPE (sn + ug, int32x4_t);
+ CHECK_TYPE (un + sg, uint32x4_t);
+
+ /* And if the first vector wins when operands differ in both signedness
+ and ABI, it seems more consistent to do the same if the operands differ
+ only in ABI. */
+ CHECK_TYPE (sg + sn, gnu_int32x4_t);
+ CHECK_TYPE (ug + un, gnu_uint32x4_t);
+ CHECK_TYPE (sn + sg, int32x4_t);
+ CHECK_TYPE (un + ug, uint32x4_t);
+
+ CHECK_TYPE (c ? sg + sg : sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug + ug : ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn + sn : sn, int32x4_t);
+ CHECK_TYPE (c ? un + un : un, uint32x4_t);
+
+ CHECK_TYPE (c ? sg + 1 : sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug + 1 : ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn + 1 : sn, int32x4_t);
+ CHECK_TYPE (c ? un + 1 : un, uint32x4_t);
+
+ CHECK_TYPE (c ? 1 + sg : sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? 1 + ug : ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? 1 + sn : sn, int32x4_t);
+ CHECK_TYPE (c ? 1 + un : un, uint32x4_t);
+
+ CHECK_TYPE (c ? sg : sg + sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug : ug + ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn : sn + sn, int32x4_t);
+ CHECK_TYPE (c ? un : un + un, uint32x4_t);
+
+ CHECK_TYPE (c ? sg : sg + 1, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug : ug + 1, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn : sn + 1, int32x4_t);
+ CHECK_TYPE (c ? un : un + 1, uint32x4_t);
+
+ CHECK_TYPE (c ? sg : 1 + sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug : 1 + ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn : 1 + sn, int32x4_t);
+ CHECK_TYPE (c ? un : 1 + un, uint32x4_t);
+
+ CHECK_TYPE (c ? sg + sg : sg + sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug + ug : ug + ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn + sn : sn + sn, int32x4_t);
+ CHECK_TYPE (c ? un + un : un + un, uint32x4_t);
+
+ CHECK_TYPE (c ? sg + sg : sg + 1, gnu_int32x4_t);
+ CHECK_TYPE (c ? ug + ug : ug + 1, gnu_uint32x4_t);
+ CHECK_TYPE (c ? sn + sn : sn + 1, int32x4_t);
+ CHECK_TYPE (c ? un + un : un + 1, uint32x4_t);
+
+ CHECK_TYPE (c ? 1 + sg : sg + sg, gnu_int32x4_t);
+ CHECK_TYPE (c ? 1 + ug : ug + ug, gnu_uint32x4_t);
+ CHECK_TYPE (c ? 1 + sn : sn + sn, int32x4_t);
+ CHECK_TYPE (c ? 1 + un : un + un, uint32x4_t);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/pr100056.c b/gcc/testsuite/gcc.target/aarch64/pr100056.c
new file mode 100644
index 0000000..0b77824
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr100056.c
@@ -0,0 +1,58 @@
+/* PR target/100056 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not {\t[us]bfiz\tw[0-9]+, w[0-9]+, 11} } } */
+
+int
+or_shift_u8 (unsigned char i)
+{
+ return i | (i << 11);
+}
+
+int
+or_shift_u3a (unsigned i)
+{
+ i &= 7;
+ return i | (i << 11);
+}
+
+int
+or_shift_u3b (unsigned i)
+{
+ i = (i << 29) >> 29;
+ return i | (i << 11);
+}
+
+int
+or_shift_s16 (signed short i)
+{
+ return i | (i << 11);
+}
+
+int
+or_shift_s8 (signed char i)
+{
+ return i | (i << 11);
+}
+
+int
+or_shift_s13 (int i)
+{
+ i = (i << 19) >> 19;
+ return i | (i << 11);
+}
+
+int
+or_shift_s3 (int i)
+{
+ i = (i << 29) >> 29;
+ return i | (i << 11);
+}
+
+int
+or_shift_u8_asm (unsigned char x)
+{
+ unsigned char i = x;
+ asm volatile ("" : "+r" (i));
+ return i | (i << 11);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr99246.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr99246.c
new file mode 100644
index 0000000..7f1079c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr99246.c
@@ -0,0 +1,17 @@
+/* { dg-options "-Os" } */
+
+#include <arm_sve.h>
+extern char b[];
+int x;
+void f() {
+ while (x) {
+ x = svaddv(
+ svnot_z(svnot_z(svptrue_pat_b8(SV_VL6),
+ svmov_z(svptrue_pat_b8(SV_VL1),
+ svptrue_pat_b16(SV_VL3))),
+ svptrue_pat_b64(SV_VL2)),
+ svdup_s32(8193));
+ for (int j = x; j; j++)
+ b[j] = 0;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr99929_1.c b/gcc/testsuite/gcc.target/aarch64/sve/pr99929_1.c
new file mode 100644
index 0000000..1fe1813
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr99929_1.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <arm_sve.h>
+
+static void e(short *g, short p2) { *g ^= p2; }
+static short m[23];
+int main() {
+ for (unsigned i = 0; i < 23; ++i)
+ m[i] = 4;
+ if (svaddv(svptrue_pat_b32(SV_VL1), svdup_u32(1)) != 1)
+ __builtin_abort();
+ for (unsigned i = 0; i < 3; ++i)
+ e(m, m[i]);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr99929_2.c b/gcc/testsuite/gcc.target/aarch64/sve/pr99929_2.c
new file mode 100644
index 0000000..50d432d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr99929_2.c
@@ -0,0 +1,5 @@
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "pr99929_1.c"
+
+/* { dg-final { scan-assembler {\tptrue\tp[0-7].[bhsd], vl1\n} } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr100066.c b/gcc/testsuite/gcc.target/i386/pr100066.c
new file mode 100644
index 0000000..a795864
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100066.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { int128 } } } */
+/* { dg-options "-O1 -w" } */
+int pm;
+
+void
+w3 (int, int, int);
+
+void
+e6 (__int128 rt, long int mo)
+{
+ mo += rt / 0;
+ w3 (pm / mo, pm, 0);
+}
diff --git a/gcc/testsuite/gcc.target/s390/zvector/imm-range-error-1.c b/gcc/testsuite/gcc.target/s390/zvector/imm-range-error-1.c
new file mode 100644
index 0000000..1fe68f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/zvector/imm-range-error-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mzarch -march=z14 -mzvector" } */
+
+#include <vecintrin.h>
+
+__vector unsigned char q;
+__vector unsigned short int h;
+__vector unsigned int s;
+__vector unsigned long long d;
+
+int
+main ()
+{
+ vec_msum_u128 (d, d, q, 5); /* { dg-error "constant argument 4 for builtin '__builtin_s390_vec_msum_u128' is invalid \\(0, 4, 8, 12\\)" } */
+
+ /* Using the resolved low-level builtins here makes the errors to be
+ triggered from s390_expand_builtin. Otherwise they would come
+ from the parser already preventing other errors from showing
+ up. */
+ __builtin_s390_vrepb (q, 17); /* { dg-error "constant argument 2 for builtin '__builtin_s390_vrepb' is out of range \\(0..15\\)" } */
+ __builtin_s390_vreph (h, 8); /* { dg-error "constant argument 2 for builtin '__builtin_s390_vreph' is out of range \\(0..7\\)" } */
+ __builtin_s390_vrepf (s, 4); /* { dg-error "constant argument 2 for builtin '__builtin_s390_vrepf' is out of range \\(0..3\\)" } */
+ __builtin_s390_vrepg (d, 2); /* { dg-error "constant argument 2 for builtin '__builtin_s390_vrepg' is out of range \\(0..1\\)" } */
+
+ __builtin_s390_vpdi (d, d, 2); /* { dg-error "constant argument 3 for builtin '__builtin_s390_vpdi' is invalid \\(0, 1, 4, 5\\)" } */
+}
diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec_msum_u128-1.c b/gcc/testsuite/gcc.target/s390/zvector/vec_msum_u128-1.c
new file mode 100644
index 0000000..2f5fbca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/zvector/vec_msum_u128-1.c
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O3 -mzarch -march=z14 -mzvector --save-temps" } */
+
+#include <vecintrin.h>
+
+typedef vector unsigned char uv16qi;
+typedef vector unsigned long long uv2di;
+
+uv2di a = (uv2di){ 12, 42 };
+uv2di b = (uv2di){ 54, 120 };
+uv2di c = (uv2di){ 0, 200 };
+
+int
+main ()
+{
+ uv2di result;
+
+ result = (uv2di)vec_msum_u128 (a, b, (uv16qi)c, 0);
+
+ if (result[1] != a[0] * b[0] + a[1] * b[1] + c[1])
+ __builtin_abort();
+
+ result = (uv2di)vec_msum_u128 (a, b, (uv16qi)c, 4);
+
+ if (result[1] != a[0] * b[0] + a[1] * b[1] * 2 + c[1])
+ __builtin_abort();
+
+ result = (uv2di)vec_msum_u128 (a, b, (uv16qi)c, 8);
+
+ if (result[1] != a[0] * b[0] * 2 + a[1] * b[1] + c[1])
+ __builtin_abort();
+
+ result = (uv2di)vec_msum_u128 (a, b, (uv16qi)c, 12);
+
+ if (result[1] != a[0] * b[0] * 2 + a[1] * b[1] * 2 + c[1])
+ __builtin_abort();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "vmslg\t.*0" 1 } } */
+/* { dg-final { scan-assembler-times "vmslg\t.*4" 1 } } */
+/* { dg-final { scan-assembler-times "vmslg\t.*8" 1 } } */
+/* { dg-final { scan-assembler-times "vmslg\t.*12" 1 } } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 7e3aae5..4f63aa6 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -4246,6 +4246,8 @@ verify_gimple_assign_ternary (gassign *stmt)
debug_generic_expr (rhs1_type);
return true;
}
+ if (!is_gimple_val (rhs1))
+ return true;
/* Fallthrough. */
case COND_EXPR:
if (!is_gimple_val (rhs1)
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index def16c0..17dd1ef 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -515,7 +515,7 @@ valid_gimple_rhs_p (tree expr)
default:
if (get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS)
{
- if (((code == VEC_COND_EXPR || code == COND_EXPR)
+ if ((code == COND_EXPR
? !is_gimple_condexpr (TREE_OPERAND (expr, 0))
: !is_gimple_val (TREE_OPERAND (expr, 0)))
|| !is_gimple_val (TREE_OPERAND (expr, 1))