!100 [Init] Init GCC 10.3.0 repository

From: @eastb233
Reviewed-by: @haijianzhang
Signed-off-by: @haijianzhang
This commit is contained in:
openeuler-ci-bot 2021-07-27 12:14:28 +00:00 committed by Gitee
commit c706d9538c
125 changed files with 90 additions and 532617 deletions

View File

@ -1,67 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-AArch64-Fix-constraints-for-CPY-M.patch
3c2707f33af46ac145769872b65e25fd0b870903
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index cbf29a82e28..59bf4a69507 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -6523,7 +6523,7 @@
(define_insn "@aarch64_sel_dup<mode>"
[(set (match_operand:SVE_FULL 0 "register_operand" "=?w, w, ??w, ?&w, ??&w, ?&w")
(unspec:SVE_FULL
- [(match_operand:<VPRED> 3 "register_operand" "Upa, Upa, Upl, Upl, Upl, Upl")
+ [(match_operand:<VPRED> 3 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
(vec_duplicate:SVE_FULL
(match_operand:<VEL> 1 "register_operand" "r, w, r, w, r, w"))
(match_operand:SVE_FULL 2 "aarch64_simd_reg_or_zero" "0, 0, Dz, Dz, w, w")]
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cpy_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cpy_1.c
new file mode 100644
index 00000000000..1d8f429caeb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cpy_1.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** dup_x0_m:
+** add (x[0-9]+), x0, #?1
+** mov (p[0-7])\.b, p15\.b
+** mov z0\.d, \2/m, \1
+** ret
+*/
+svuint64_t
+dup_x0_m (svuint64_t z0, uint64_t x0)
+{
+ register svbool_t pg asm ("p15");
+ asm volatile ("" : "=Upa" (pg));
+ return svdup_u64_m (z0, pg, x0 + 1);
+}
+
+/*
+** dup_d1_z:
+** mov (p[0-7])\.b, p15\.b
+** mov z0\.d, \1/m, d1
+** ret
+*/
+svfloat64_t
+dup_d1_z (svfloat64_t z0, float64_t d1)
+{
+ register svbool_t pg asm ("p15");
+ asm volatile ("" : "=Upa" (pg));
+ return svdup_f64_m (z0, pg, d1);
+}
+
+#ifdef __cplusplus
+}
+#endif

View File

@ -1,694 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Apply-maximum-nunits-for-BB-SLP.patch
9b75f56d4b7951c60a656396dddd4a65787b95bc
diff -Nurp a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c 2020-12-20 18:46:19.539633230 +0800
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c 2020-12-20 18:48:12.799633230 +0800
@@ -38,5 +38,4 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp2" } } */
-
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/vect/bb-slp-bool-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-bool-1.c
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-bool-1.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-bool-1.c 2020-12-20 18:48:12.799633230 +0800
@@ -0,0 +1,44 @@
+#include "tree-vect.h"
+
+void __attribute__ ((noipa))
+f1 (_Bool *x, unsigned short *y)
+{
+ x[0] = (y[0] == 1);
+ x[1] = (y[1] == 1);
+}
+
+void __attribute__ ((noipa))
+f2 (_Bool *x, unsigned short *y)
+{
+ x[0] = (y[0] == 1);
+ x[1] = (y[1] == 1);
+ x[2] = (y[2] == 1);
+ x[3] = (y[3] == 1);
+ x[4] = (y[4] == 1);
+ x[5] = (y[5] == 1);
+ x[6] = (y[6] == 1);
+ x[7] = (y[7] == 1);
+}
+
+_Bool x[8];
+unsigned short y[8] = { 11, 1, 9, 5, 1, 44, 1, 1 };
+
+int
+main (void)
+{
+ check_vect ();
+
+ f1 (x, y);
+
+ if (x[0] || !x[1])
+ __builtin_abort ();
+
+ x[1] = 0;
+
+ f2 (x, y);
+
+ if (x[0] || !x[1] || x[2] | x[3] || !x[4] || x[5] || !x[6] || !x[7])
+ __builtin_abort ();
+
+ return 0;
+}
diff -Nurp a/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_14.c b/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_14.c
--- a/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_14.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.target/aarch64/vect_mixed_sizes_14.c 2020-12-20 18:48:11.811633230 +0800
@@ -0,0 +1,26 @@
+/* { dg-options "-O2 -ftree-vectorize" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** foo:
+** (
+** ldr d([0-9]+), \[x1\]
+** ldr q([0-9]+), \[x0\]
+** saddw v([0-9]+)\.4s, v\2\.4s, v\1\.4h
+** str q\3, \[x0\]
+** |
+** ldr q([0-9]+), \[x0\]
+** ldr d([0-9]+), \[x1\]
+** saddw v([0-9]+)\.4s, v\4\.4s, v\5\.4h
+** str q\6, \[x0\]
+** )
+** ret
+*/
+void
+foo (int *x, short *y)
+{
+ x[0] += y[0];
+ x[1] += y[1];
+ x[2] += y[2];
+ x[3] += y[3];
+}
diff -Nurp a/gcc/testsuite/gcc.target/i386/pr84101.c b/gcc/testsuite/gcc.target/i386/pr84101.c
--- a/gcc/testsuite/gcc.target/i386/pr84101.c 2020-12-20 18:46:18.383633230 +0800
+++ b/gcc/testsuite/gcc.target/i386/pr84101.c 2020-12-20 18:48:11.611633230 +0800
@@ -18,4 +18,5 @@ uint64_pair_t pair(int num)
return p ;
}
-/* { dg-final { scan-tree-dump-not "basic block vectorized" "slp2" } } */
+/* See PR92266 for the XFAIL. */
+/* { dg-final { scan-tree-dump-not "basic block vectorized" "slp2" { xfail ilp32 } } } */
diff -Nurp a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
--- a/gcc/tree-vect-data-refs.c 2020-12-20 18:46:19.911633230 +0800
+++ b/gcc/tree-vect-data-refs.c 2020-12-20 18:48:11.047633230 +0800
@@ -4312,9 +4312,8 @@ vect_analyze_data_refs (vec_info *vinfo,
/* Set vectype for STMT. */
scalar_type = TREE_TYPE (DR_REF (dr));
- STMT_VINFO_VECTYPE (stmt_info)
- = get_vectype_for_scalar_type (vinfo, scalar_type);
- if (!STMT_VINFO_VECTYPE (stmt_info))
+ tree vectype = get_vectype_for_scalar_type (vinfo, scalar_type);
+ if (!vectype)
{
if (dump_enabled_p ())
{
@@ -4345,14 +4344,19 @@ vect_analyze_data_refs (vec_info *vinfo,
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"got vectype for stmt: %G%T\n",
- stmt_info->stmt, STMT_VINFO_VECTYPE (stmt_info));
+ stmt_info->stmt, vectype);
}
/* Adjust the minimal vectorization factor according to the
vector type. */
- vf = TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info));
+ vf = TYPE_VECTOR_SUBPARTS (vectype);
*min_vf = upper_bound (*min_vf, vf);
+ /* Leave the BB vectorizer to pick the vector type later, based on
+ the final dataref group size and SLP node size. */
+ if (is_a <loop_vec_info> (vinfo))
+ STMT_VINFO_VECTYPE (stmt_info) = vectype;
+
if (gatherscatter != SG_NONE)
{
gather_scatter_info gs_info;
diff -Nurp a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
--- a/gcc/tree-vect-patterns.c 2020-12-20 18:46:19.979633230 +0800
+++ b/gcc/tree-vect-patterns.c 2020-12-20 18:48:11.227633230 +0800
@@ -4142,9 +4142,10 @@ vect_recog_bool_pattern (stmt_vec_info s
&& STMT_VINFO_DATA_REF (stmt_vinfo))
{
stmt_vec_info pattern_stmt_info;
- vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
- gcc_assert (vectype != NULL_TREE);
- if (!VECTOR_MODE_P (TYPE_MODE (vectype)))
+ tree nunits_vectype;
+ if (!vect_get_vector_types_for_stmt (stmt_vinfo, &vectype,
+ &nunits_vectype)
+ || !VECTOR_MODE_P (TYPE_MODE (vectype)))
return NULL;
if (check_bool_pattern (var, vinfo, bool_stmts))
diff -Nurp a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2020-12-20 18:46:17.763633230 +0800
+++ b/gcc/tree-vect-slp.c 2020-12-20 18:48:11.227633230 +0800
@@ -606,6 +606,77 @@ again:
return 0;
}
+/* Try to assign vector type VECTYPE to STMT_INFO for BB vectorization.
+ Return true if we can, meaning that this choice doesn't conflict with
+ existing SLP nodes that use STMT_INFO. */
+
+static bool
+vect_update_shared_vectype (stmt_vec_info stmt_info, tree vectype)
+{
+ tree old_vectype = STMT_VINFO_VECTYPE (stmt_info);
+ if (old_vectype && useless_type_conversion_p (vectype, old_vectype))
+ return true;
+
+ if (STMT_VINFO_GROUPED_ACCESS (stmt_info)
+ && DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
+ {
+ /* We maintain the invariant that if any statement in the group is
+ used, all other members of the group have the same vector type. */
+ stmt_vec_info first_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
+ stmt_vec_info member_info = first_info;
+ for (; member_info; member_info = DR_GROUP_NEXT_ELEMENT (member_info))
+ if (STMT_VINFO_NUM_SLP_USES (member_info) > 0
+ || is_pattern_stmt_p (member_info))
+ break;
+
+ if (!member_info)
+ {
+ for (member_info = first_info; member_info;
+ member_info = DR_GROUP_NEXT_ELEMENT (member_info))
+ STMT_VINFO_VECTYPE (member_info) = vectype;
+ return true;
+ }
+ }
+ else if (STMT_VINFO_NUM_SLP_USES (stmt_info) == 0
+ && !is_pattern_stmt_p (stmt_info))
+ {
+ STMT_VINFO_VECTYPE (stmt_info) = vectype;
+ return true;
+ }
+
+ if (dump_enabled_p ())
+ {
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: incompatible vector"
+ " types for: %G", stmt_info->stmt);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ " old vector type: %T\n", old_vectype);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ " new vector type: %T\n", vectype);
+ }
+ return false;
+}
+
+/* Try to infer and assign a vector type to all the statements in STMTS.
+ Used only for BB vectorization. */
+
+static bool
+vect_update_all_shared_vectypes (vec<stmt_vec_info> stmts)
+{
+ tree vectype, nunits_vectype;
+ if (!vect_get_vector_types_for_stmt (stmts[0], &vectype,
+ &nunits_vectype, stmts.length ()))
+ return false;
+
+ stmt_vec_info stmt_info;
+ unsigned int i;
+ FOR_EACH_VEC_ELT (stmts, i, stmt_info)
+ if (!vect_update_shared_vectype (stmt_info, vectype))
+ return false;
+
+ return true;
+}
+
/* Return true if call statements CALL1 and CALL2 are similar enough
to be combined into the same SLP group. */
@@ -751,6 +822,7 @@ vect_build_slp_tree_1 (unsigned char *sw
stmt_vec_info stmt_info;
FOR_EACH_VEC_ELT (stmts, i, stmt_info)
{
+ vec_info *vinfo = stmt_info->vinfo;
gimple *stmt = stmt_info->stmt;
swap[i] = 0;
matches[i] = false;
@@ -784,7 +856,7 @@ vect_build_slp_tree_1 (unsigned char *sw
tree nunits_vectype;
if (!vect_get_vector_types_for_stmt (stmt_info, &vectype,
- &nunits_vectype)
+ &nunits_vectype, group_size)
|| (nunits_vectype
&& !vect_record_max_nunits (stmt_info, group_size,
nunits_vectype, max_nunits)))
@@ -796,6 +868,10 @@ vect_build_slp_tree_1 (unsigned char *sw
gcc_assert (vectype);
+ if (is_a <bb_vec_info> (vinfo)
+ && !vect_update_shared_vectype (stmt_info, vectype))
+ continue;
+
if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
{
rhs_code = CALL_EXPR;
@@ -1328,7 +1404,8 @@ vect_build_slp_tree_2 (vec_info *vinfo,
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (child), j, grandchild)
if (SLP_TREE_DEF_TYPE (grandchild) != vect_external_def)
break;
- if (!grandchild)
+ if (!grandchild
+ && vect_update_all_shared_vectypes (oprnd_info->def_stmts))
{
/* Roll back. */
this_tree_size = old_tree_size;
@@ -1369,7 +1446,8 @@ vect_build_slp_tree_2 (vec_info *vinfo,
do extra work to cancel the pattern so the uses see the
scalar version. */
&& !is_pattern_stmt_p (stmt_info)
- && !oprnd_info->any_pattern)
+ && !oprnd_info->any_pattern
+ && vect_update_all_shared_vectypes (oprnd_info->def_stmts))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
@@ -1488,7 +1566,9 @@ vect_build_slp_tree_2 (vec_info *vinfo,
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (child), j, grandchild)
if (SLP_TREE_DEF_TYPE (grandchild) != vect_external_def)
break;
- if (!grandchild)
+ if (!grandchild
+ && (vect_update_all_shared_vectypes
+ (oprnd_info->def_stmts)))
{
/* Roll back. */
this_tree_size = old_tree_size;
@@ -2026,8 +2106,8 @@ vect_analyze_slp_instance (vec_info *vin
if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
{
scalar_type = TREE_TYPE (DR_REF (dr));
- vectype = get_vectype_for_scalar_type (vinfo, scalar_type);
group_size = DR_GROUP_SIZE (stmt_info);
+ vectype = get_vectype_for_scalar_type (vinfo, scalar_type, group_size);
}
else if (!dr && REDUC_GROUP_FIRST_ELEMENT (stmt_info))
{
@@ -2669,22 +2749,13 @@ vect_slp_analyze_node_operations_1 (vec_
Memory accesses already got their vector type assigned
in vect_analyze_data_refs. */
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
- if (bb_vinfo
- && ! STMT_VINFO_DATA_REF (stmt_info))
+ if (bb_vinfo && STMT_VINFO_VECTYPE (stmt_info) == boolean_type_node)
{
- tree vectype, nunits_vectype;
- if (!vect_get_vector_types_for_stmt (stmt_info, &vectype,
- &nunits_vectype))
- /* We checked this when building the node. */
- gcc_unreachable ();
- if (vectype == boolean_type_node)
- {
- vectype = vect_get_mask_type_for_stmt (stmt_info);
- if (!vectype)
- /* vect_get_mask_type_for_stmt has already explained the
- failure. */
- return false;
- }
+ tree vectype = vect_get_mask_type_for_stmt (stmt_info, node);
+ if (!vectype)
+ /* vect_get_mask_type_for_stmt has already explained the
+ failure. */
+ return false;
stmt_vec_info sstmt_info;
unsigned int i;
@@ -3585,7 +3656,7 @@ vect_get_constant_vectors (slp_tree op_n
&& vect_mask_constant_operand_p (stmt_vinfo))
vector_type = truth_type_for (stmt_vectype);
else
- vector_type = get_vectype_for_scalar_type (vinfo, TREE_TYPE (op));
+ vector_type = get_vectype_for_scalar_type (vinfo, TREE_TYPE (op), op_node);
unsigned int number_of_vectors
= vect_get_num_vectors (SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node)
diff -Nurp a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
--- a/gcc/tree-vect-stmts.c 2020-12-20 18:46:17.707633230 +0800
+++ b/gcc/tree-vect-stmts.c 2020-12-20 18:48:11.227633230 +0800
@@ -798,7 +798,7 @@ vect_prologue_cost_for_slp_op (slp_tree
/* Without looking at the actual initializer a vector of
constants can be implemented as load from the constant pool.
When all elements are the same we can use a splat. */
- tree vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (op));
+ tree vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (op), node);
unsigned group_size = SLP_TREE_SCALAR_STMTS (node).length ();
unsigned num_vects_to_check;
unsigned HOST_WIDE_INT const_nunits;
@@ -3308,7 +3308,7 @@ vectorizable_call (stmt_vec_info stmt_in
/* If all arguments are external or constant defs, infer the vector type
from the scalar type. */
if (!vectype_in)
- vectype_in = get_vectype_for_scalar_type (vinfo, rhs_type);
+ vectype_in = get_vectype_for_scalar_type (vinfo, rhs_type, slp_node);
if (vec_stmt)
gcc_assert (vectype_in);
if (!vectype_in)
@@ -4106,7 +4106,8 @@ vectorizable_simd_clone_call (stmt_vec_i
&& bestn->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_VECTOR)
{
tree arg_type = TREE_TYPE (gimple_call_arg (stmt, i));
- arginfo[i].vectype = get_vectype_for_scalar_type (vinfo, arg_type);
+ arginfo[i].vectype = get_vectype_for_scalar_type (vinfo, arg_type,
+ slp_node);
if (arginfo[i].vectype == NULL
|| (simd_clone_subparts (arginfo[i].vectype)
> bestn->simdclone->simdlen))
@@ -4805,7 +4806,7 @@ vectorizable_conversion (stmt_vec_info s
/* If op0 is an external or constant def, infer the vector type
from the scalar type. */
if (!vectype_in)
- vectype_in = get_vectype_for_scalar_type (vinfo, rhs_type);
+ vectype_in = get_vectype_for_scalar_type (vinfo, rhs_type, slp_node);
if (vec_stmt)
gcc_assert (vectype_in);
if (!vectype_in)
@@ -5558,7 +5559,7 @@ vectorizable_shift (stmt_vec_info stmt_i
/* If op0 is an external or constant def, infer the vector type
from the scalar type. */
if (!vectype)
- vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (op0));
+ vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (op0), slp_node);
if (vec_stmt)
gcc_assert (vectype);
if (!vectype)
@@ -5656,7 +5657,8 @@ vectorizable_shift (stmt_vec_info stmt_i
"vector/vector shift/rotate found.\n");
if (!op1_vectype)
- op1_vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (op1));
+ op1_vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (op1),
+ slp_node);
incompatible_op1_vectype_p
= (op1_vectype == NULL_TREE
|| maybe_ne (TYPE_VECTOR_SUBPARTS (op1_vectype),
@@ -6000,7 +6002,8 @@ vectorizable_operation (stmt_vec_info st
vectype = vectype_out;
}
else
- vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (op0));
+ vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (op0),
+ slp_node);
}
if (vec_stmt)
gcc_assert (vectype);
@@ -8903,7 +8906,7 @@ vectorizable_load (stmt_vec_info stmt_in
condition operands are supportable using vec_is_simple_use. */
static bool
-vect_is_simple_cond (tree cond, vec_info *vinfo,
+vect_is_simple_cond (tree cond, vec_info *vinfo, slp_tree slp_node,
tree *comp_vectype, enum vect_def_type *dts,
tree vectype)
{
@@ -8966,7 +8969,8 @@ vect_is_simple_cond (tree cond, vec_info
scalar_type = build_nonstandard_integer_type
(tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype))),
TYPE_UNSIGNED (scalar_type));
- *comp_vectype = get_vectype_for_scalar_type (vinfo, scalar_type);
+ *comp_vectype = get_vectype_for_scalar_type (vinfo, scalar_type,
+ slp_node);
}
return true;
@@ -9073,7 +9077,7 @@ vectorizable_condition (stmt_vec_info st
then_clause = gimple_assign_rhs2 (stmt);
else_clause = gimple_assign_rhs3 (stmt);
- if (!vect_is_simple_cond (cond_expr, stmt_info->vinfo,
+ if (!vect_is_simple_cond (cond_expr, stmt_info->vinfo, slp_node,
&comp_vectype, &dts[0], slp_node ? NULL : vectype)
|| !comp_vectype)
return false;
@@ -9564,7 +9568,8 @@ vectorizable_comparison (stmt_vec_info s
/* Invariant comparison. */
if (!vectype)
{
- vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (rhs1));
+ vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (rhs1),
+ slp_node);
if (maybe_ne (TYPE_VECTOR_SUBPARTS (vectype), nunits))
return false;
}
@@ -10322,31 +10327,93 @@ get_related_vectype_for_scalar_type (mac
/* Function get_vectype_for_scalar_type.
Returns the vector type corresponding to SCALAR_TYPE as supported
- by the target. */
+ by the target. If GROUP_SIZE is nonzero and we're performing BB
+ vectorization, make sure that the number of elements in the vector
+ is no bigger than GROUP_SIZE. */
tree
-get_vectype_for_scalar_type (vec_info *vinfo, tree scalar_type)
+get_vectype_for_scalar_type (vec_info *vinfo, tree scalar_type,
+ unsigned int group_size)
{
+ /* For BB vectorization, we should always have a group size once we've
+ constructed the SLP tree; the only valid uses of zero GROUP_SIZEs
+ are tentative requests during things like early data reference
+ analysis and pattern recognition. */
+ if (is_a <bb_vec_info> (vinfo))
+ gcc_assert (vinfo->slp_instances.is_empty () || group_size != 0);
+ else
+ group_size = 0;
+
tree vectype = get_related_vectype_for_scalar_type (vinfo->vector_mode,
scalar_type);
if (vectype && vinfo->vector_mode == VOIDmode)
vinfo->vector_mode = TYPE_MODE (vectype);
+ /* Register the natural choice of vector type, before the group size
+ has been applied. */
if (vectype)
vinfo->used_vector_modes.add (TYPE_MODE (vectype));
+ /* If the natural choice of vector type doesn't satisfy GROUP_SIZE,
+ try again with an explicit number of elements. */
+ if (vectype
+ && group_size
+ && maybe_ge (TYPE_VECTOR_SUBPARTS (vectype), group_size))
+ {
+ /* Start with the biggest number of units that fits within
+ GROUP_SIZE and halve it until we find a valid vector type.
+ Usually either the first attempt will succeed or all will
+ fail (in the latter case because GROUP_SIZE is too small
+ for the target), but it's possible that a target could have
+ a hole between supported vector types.
+
+ If GROUP_SIZE is not a power of 2, this has the effect of
+ trying the largest power of 2 that fits within the group,
+ even though the group is not a multiple of that vector size.
+ The BB vectorizer will then try to carve up the group into
+ smaller pieces. */
+ unsigned int nunits = 1 << floor_log2 (group_size);
+ do
+ {
+ vectype = get_related_vectype_for_scalar_type (vinfo->vector_mode,
+ scalar_type, nunits);
+ nunits /= 2;
+ }
+ while (nunits > 1 && !vectype);
+ }
+
return vectype;
}
+/* Return the vector type corresponding to SCALAR_TYPE as supported
+ by the target. NODE, if nonnull, is the SLP tree node that will
+ use the returned vector type. */
+
+tree
+get_vectype_for_scalar_type (vec_info *vinfo, tree scalar_type, slp_tree node)
+{
+ unsigned int group_size = 0;
+ if (node)
+ {
+ group_size = SLP_TREE_SCALAR_OPS (node).length ();
+ if (group_size == 0)
+ group_size = SLP_TREE_SCALAR_STMTS (node).length ();
+ }
+ return get_vectype_for_scalar_type (vinfo, scalar_type, group_size);
+}
+
/* Function get_mask_type_for_scalar_type.
Returns the mask type corresponding to a result of comparison
- of vectors of specified SCALAR_TYPE as supported by target. */
+ of vectors of specified SCALAR_TYPE as supported by target.
+ NODE, if nonnull, is the SLP tree node that will use the returned
+ vector type. */
tree
-get_mask_type_for_scalar_type (vec_info *vinfo, tree scalar_type)
+get_mask_type_for_scalar_type (vec_info *vinfo, tree scalar_type,
+ slp_tree node)
{
- tree vectype = get_vectype_for_scalar_type (vinfo, scalar_type);
+ tree vectype = get_vectype_for_scalar_type (vinfo, scalar_type, node);
if (!vectype)
return NULL;
@@ -11033,6 +11100,9 @@ vect_gen_while_not (gimple_seq *seq, tre
/* Try to compute the vector types required to vectorize STMT_INFO,
returning true on success and false if vectorization isn't possible.
+ If GROUP_SIZE is nonzero and we're performing BB vectorization,
+ take sure that the number of elements in the vectors is no bigger
+ than GROUP_SIZE.
On success:
@@ -11050,11 +11120,21 @@ vect_gen_while_not (gimple_seq *seq, tre
opt_result
vect_get_vector_types_for_stmt (stmt_vec_info stmt_info,
tree *stmt_vectype_out,
- tree *nunits_vectype_out)
+ tree *nunits_vectype_out,
+ unsigned int group_size)
{
vec_info *vinfo = stmt_info->vinfo;
gimple *stmt = stmt_info->stmt;
+ /* For BB vectorization, we should always have a group size once we've
+ constructed the SLP tree; the only valid uses of zero GROUP_SIZEs
+ are tentative requests during things like early data reference
+ analysis and pattern recognition. */
+ if (is_a <bb_vec_info> (vinfo))
+ gcc_assert (vinfo->slp_instances.is_empty () || group_size != 0);
+ else
+ group_size = 0;
+
*stmt_vectype_out = NULL_TREE;
*nunits_vectype_out = NULL_TREE;
@@ -11085,7 +11165,7 @@ vect_get_vector_types_for_stmt (stmt_vec
tree vectype;
tree scalar_type = NULL_TREE;
- if (STMT_VINFO_VECTYPE (stmt_info))
+ if (group_size == 0 && STMT_VINFO_VECTYPE (stmt_info))
{
*stmt_vectype_out = vectype = STMT_VINFO_VECTYPE (stmt_info);
if (dump_enabled_p ())
@@ -11094,15 +11174,17 @@ vect_get_vector_types_for_stmt (stmt_vec
}
else
{
- gcc_assert (!STMT_VINFO_DATA_REF (stmt_info));
- if (gimple_call_internal_p (stmt, IFN_MASK_STORE))
+ if (data_reference *dr = STMT_VINFO_DATA_REF (stmt_info))
+ scalar_type = TREE_TYPE (DR_REF (dr));
+ else if (gimple_call_internal_p (stmt, IFN_MASK_STORE))
scalar_type = TREE_TYPE (gimple_call_arg (stmt, 3));
else
scalar_type = TREE_TYPE (gimple_get_lhs (stmt));
/* Pure bool ops don't participate in number-of-units computation.
For comparisons use the types being compared. */
- if (VECT_SCALAR_BOOLEAN_TYPE_P (scalar_type)
+ if (!STMT_VINFO_DATA_REF (stmt_info)
+ && VECT_SCALAR_BOOLEAN_TYPE_P (scalar_type)
&& is_gimple_assign (stmt)
&& gimple_assign_rhs_code (stmt) != COND_EXPR)
{
@@ -11122,9 +11204,16 @@ vect_get_vector_types_for_stmt (stmt_vec
}
if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "get vectype for scalar type: %T\n", scalar_type);
- vectype = get_vectype_for_scalar_type (vinfo, scalar_type);
+ {
+ if (group_size)
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "get vectype for scalar type (group size %d):"
+ " %T\n", group_size, scalar_type);
+ else
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "get vectype for scalar type: %T\n", scalar_type);
+ }
+ vectype = get_vectype_for_scalar_type (vinfo, scalar_type, group_size);
if (!vectype)
return opt_result::failure_at (stmt,
"not vectorized:"
@@ -11155,7 +11244,8 @@ vect_get_vector_types_for_stmt (stmt_vec
dump_printf_loc (MSG_NOTE, vect_location,
"get vectype for smallest scalar type: %T\n",
scalar_type);
- nunits_vectype = get_vectype_for_scalar_type (vinfo, scalar_type);
+ nunits_vectype = get_vectype_for_scalar_type (vinfo, scalar_type,
+ group_size);
if (!nunits_vectype)
return opt_result::failure_at
(stmt, "not vectorized: unsupported data-type %T\n",
@@ -11183,10 +11273,11 @@ vect_get_vector_types_for_stmt (stmt_vec
/* Try to determine the correct vector type for STMT_INFO, which is a
statement that produces a scalar boolean result. Return the vector
- type on success, otherwise return NULL_TREE. */
+ type on success, otherwise return NULL_TREE. NODE, if nonnull,
+ is the SLP tree node that will use the returned vector type. */
opt_tree
-vect_get_mask_type_for_stmt (stmt_vec_info stmt_info)
+vect_get_mask_type_for_stmt (stmt_vec_info stmt_info, slp_tree node)
{
vec_info *vinfo = stmt_info->vinfo;
gimple *stmt = stmt_info->stmt;
@@ -11198,7 +11289,7 @@ vect_get_mask_type_for_stmt (stmt_vec_in
&& !VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
{
scalar_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
- mask_type = get_mask_type_for_scalar_type (vinfo, scalar_type);
+ mask_type = get_mask_type_for_scalar_type (vinfo, scalar_type, node);
if (!mask_type)
return opt_tree::failure_at (stmt,
diff -Nurp a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
--- a/gcc/tree-vectorizer.h 2020-12-20 18:46:17.851633230 +0800
+++ b/gcc/tree-vectorizer.h 2020-12-20 18:48:11.227633230 +0800
@@ -1618,8 +1618,9 @@ extern void vect_update_inits_of_drs (lo
/* In tree-vect-stmts.c. */
extern tree get_related_vectype_for_scalar_type (machine_mode, tree,
poly_uint64 = 0);
-extern tree get_vectype_for_scalar_type (vec_info *, tree);
-extern tree get_mask_type_for_scalar_type (vec_info *, tree);
+extern tree get_vectype_for_scalar_type (vec_info *, tree, unsigned int = 0);
+extern tree get_vectype_for_scalar_type (vec_info *, tree, slp_tree);
+extern tree get_mask_type_for_scalar_type (vec_info *, tree, slp_tree = 0);
extern tree get_same_sized_vectype (tree, tree);
extern bool vect_chooses_same_modes_p (vec_info *, machine_mode);
extern bool vect_get_loop_mask_type (loop_vec_info);
@@ -1671,8 +1672,8 @@ extern void optimize_mask_stores (struct
extern gcall *vect_gen_while (tree, tree, tree);
extern tree vect_gen_while_not (gimple_seq *, tree, tree, tree);
extern opt_result vect_get_vector_types_for_stmt (stmt_vec_info, tree *,
- tree *);
-extern opt_tree vect_get_mask_type_for_stmt (stmt_vec_info);
+ tree *, unsigned int = 0);
+extern opt_tree vect_get_mask_type_for_stmt (stmt_vec_info, slp_tree = 0);
/* In tree-vect-data-refs.c. */
extern bool vect_can_force_dr_alignment_p (const_tree, poly_uint64);

View File

@ -1,82 +0,0 @@
This backport contains 2 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Fix-EXTRACT_LAST_REDUCTION-handling-of-pattern-stmts.patch
9ec35478ccf0f3539988a054b7996278706a7710
0001-Fix-EXTRACT_LAST_REDUCTION-segfault.patch
dc176c3ccd6a8cd3f809f3c1549ad00674061eb5
diff -Nurp a/gcc/testsuite/gcc.dg/vect/vect-cond-reduc-6.c b/gcc/testsuite/gcc.dg/vect/vect-cond-reduc-6.c
--- a/gcc/testsuite/gcc.dg/vect/vect-cond-reduc-6.c 1969-12-31 19:00:00.000000000 -0500
+++ b/gcc/testsuite/gcc.dg/vect/vect-cond-reduc-6.c 2020-12-14 21:16:26.492000000 -0500
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+int
+f (int *y)
+{
+ int res = 0;
+ for (int i = 0; i < 100; ++i)
+ res = (y[i] & 1) == 0 && (y[i] < 10) ? res : 1;
+ return res;
+}
diff -Nurp a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
--- a/gcc/tree-vect-stmts.c 2020-12-14 21:15:27.004000000 -0500
+++ b/gcc/tree-vect-stmts.c 2020-12-14 21:16:26.492000000 -0500
@@ -1777,9 +1777,10 @@ vect_finish_stmt_generation_1 (stmt_vec_
stmt_vec_info
vect_finish_replace_stmt (stmt_vec_info stmt_info, gimple *vec_stmt)
{
- gcc_assert (gimple_get_lhs (stmt_info->stmt) == gimple_get_lhs (vec_stmt));
+ gimple *scalar_stmt = vect_orig_stmt (stmt_info)->stmt;
+ gcc_assert (gimple_get_lhs (scalar_stmt) == gimple_get_lhs (vec_stmt));
- gimple_stmt_iterator gsi = gsi_for_stmt (stmt_info->stmt);
+ gimple_stmt_iterator gsi = gsi_for_stmt (scalar_stmt);
gsi_replace (&gsi, vec_stmt, true);
return vect_finish_stmt_generation_1 (stmt_info, vec_stmt);
@@ -9118,10 +9119,12 @@ vectorizable_condition (stmt_vec_info st
if (new_code == ERROR_MARK)
must_invert_cmp_result = true;
else
- cond_code = new_code;
+ {
+ cond_code = new_code;
+ /* Make sure we don't accidentally use the old condition. */
+ cond_expr = NULL_TREE;
+ }
}
- /* Make sure we don't accidentally use the old condition. */
- cond_expr = NULL_TREE;
std::swap (then_clause, else_clause);
}
@@ -9426,20 +9429,21 @@ vectorizable_condition (stmt_vec_info st
vect_finish_stmt_generation (stmt_info, new_stmt, gsi);
vec_compare = vec_compare_name;
}
+ gimple *old_stmt = vect_orig_stmt (stmt_info)->stmt;
+ tree lhs = gimple_get_lhs (old_stmt);
gcall *new_stmt = gimple_build_call_internal
(IFN_FOLD_EXTRACT_LAST, 3, else_clause, vec_compare,
vec_then_clause);
- gimple_call_set_lhs (new_stmt, scalar_dest);
- SSA_NAME_DEF_STMT (scalar_dest) = new_stmt;
- if (stmt_info->stmt == gsi_stmt (*gsi))
+ gimple_call_set_lhs (new_stmt, lhs);
+ SSA_NAME_DEF_STMT (lhs) = new_stmt;
+ if (old_stmt == gsi_stmt (*gsi))
new_stmt_info = vect_finish_replace_stmt (stmt_info, new_stmt);
else
{
/* In this case we're moving the definition to later in the
block. That doesn't matter because the only uses of the
lhs are in phi statements. */
- gimple_stmt_iterator old_gsi
- = gsi_for_stmt (stmt_info->stmt);
+ gimple_stmt_iterator old_gsi = gsi_for_stmt (old_stmt);
gsi_remove (&old_gsi, true);
new_stmt_info
= vect_finish_stmt_generation (stmt_info, new_stmt, gsi);

View File

@ -1,66 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Fix-PR94185-Do-not-reuse-insn-alternative-after-chan.patch
bae7b38cf8a21e068ad5c0bab089dedb78af3346
diff -uprN a/gcc/lra-spills.c b/gcc/lra-spills.c
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -427,7 +427,17 @@ remove_pseudos (rtx *loc, rtx_insn *insn)
and avoid LRA cycling in case of subreg memory reload. */
res = remove_pseudos (&SUBREG_REG (*loc), insn);
if (GET_CODE (SUBREG_REG (*loc)) == MEM)
- alter_subreg (loc, false);
+ {
+ alter_subreg (loc, false);
+ if (GET_CODE (*loc) == MEM)
+ {
+ lra_get_insn_recog_data (insn)->used_insn_alternative = -1;
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file,
+ "Memory subreg was simplified in in insn #%u\n",
+ INSN_UID (insn));
+ }
+ }
return res;
}
else if (code == REG && (i = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
diff -uprN a/gcc/testsuite/g++.target/i386/pr94185.C b/gcc/testsuite/g++.target/i386/pr94185.C
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr94185.C
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIE -fstack-protector-strong" } */
+
+struct a {
+ int b;
+ int c();
+ a() : b(c()) {}
+ ~a();
+ char *e();
+};
+struct f {
+ void g(int);
+};
+struct ar {
+ int au[256];
+ f h(int);
+} bb;
+a i();
+a j(int);
+long k(int, ar);
+int d;
+void l(char *, ar m, long n) {
+ switch (m.au[d])
+ case 0:
+ n &= 4294967295;
+ bb.h(0).g(n);
+}
+void o() {
+ ar bd;
+ a bh, bi, attrname = j(0) = i();
+ int be = k(0, bd);
+ l(attrname.e(), bd, be);
+}

View File

@ -1,98 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Fix-interaction-between-aka-changes-and-DR1558.patch
ae83b9deb87787371cd94b4417e160d41dd0322c
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index adc021b2a5c..42afe1bd5cb 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5759,8 +5759,13 @@ enum auto_deduction_context
STF_USER_VISIBLE: use heuristics to try to avoid stripping user-facing
aliases of internal details. This is intended for diagnostics,
- where it should (for example) give more useful "aka" types. */
+ where it should (for example) give more useful "aka" types.
+
+ STF_STRIP_DEPENDENT: allow the stripping of aliases with dependent
+ template parameters, relying on code elsewhere to report any
+ appropriate diagnostics. */
const unsigned int STF_USER_VISIBLE = 1U;
+const unsigned int STF_STRIP_DEPENDENT = 1U << 1;
/* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
node. */
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index ba635d4ddbd..6c39c004b01 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1488,7 +1488,8 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags)
if (t == TYPE_CANONICAL (t))
return t;
- if (dependent_alias_template_spec_p (t))
+ if (!(flags & STF_STRIP_DEPENDENT)
+ && dependent_alias_template_spec_p (t))
/* DR 1558: However, if the template-id is dependent, subsequent
template argument substitution still applies to the template-id. */
return t;
@@ -1673,7 +1674,8 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags)
&& !user_facing_original_type_p (t))
return t;
result = strip_typedefs (DECL_ORIGINAL_TYPE (TYPE_NAME (t)),
- remove_attributes, flags);
+ remove_attributes,
+ flags | STF_STRIP_DEPENDENT);
}
else
result = TYPE_MAIN_VARIANT (t);
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C
new file mode 100644
index 00000000000..c3f7b1977db
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C
@@ -0,0 +1,9 @@
+// { dg-require-effective-target c++11 }
+
+template<typename> struct A {};
+template<typename T1, typename T2 = typename T1::value> using alias1 = A<T1>;
+template<typename T> class B {
+ using alias2 = alias1<A<T>>; // { dg-error {no type named 'value'} }
+ A<alias2> a; // { dg-bogus {no type named 'value'} }
+};
+B<int> b;
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C
new file mode 100644
index 00000000000..31d73d6bad3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C
@@ -0,0 +1,14 @@
+// { dg-require-effective-target c++11 }
+
+template <bool> struct A;
+class Vector {
+ template <typename> struct TypeIsGCThing {
+ template <typename T, typename A<T ::value>::Type> using Vector = Vector;
+ struct B;
+ template <typename> class ContainerIter {
+ using Action = B;
+ using ActionVector = Vector<Action, 0>;
+ ContainerIter<ActionVector> a;
+ };
+ };
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C
new file mode 100644
index 00000000000..6698a366411
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C
@@ -0,0 +1,8 @@
+// { dg-require-effective-target c++11 }
+
+template <typename> void a();
+template <typename> struct b;
+template <bool> using c = int;
+template <typename d, typename e = decltype(a<d>)> using f = e;
+template <typename e> using g = f<e>;
+template <typename h> c<b<g<h>>::i> j;

View File

@ -1,118 +0,0 @@
This backport contains 2 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Fix-type-mismatch-in-SLPed-constructors.patch
86c3a7d891f9f175d09d61f5ce163c6dc5ce681f
0001-re-PR-fortran-91003-ICE-when-compiling-LAPACK-CGEGV-.patch
d005f61e7a0dbb2c991f13b4b61b1a27ca2d8b73
diff -urpN a/gcc/testsuite/gfortran.dg/pr91003.f90 b/gcc/testsuite/gfortran.dg/pr91003.f90
--- a/gcc/testsuite/gfortran.dg/pr91003.f90 1969-12-31 19:00:00.000000000 -0500
+++ b/gcc/testsuite/gfortran.dg/pr91003.f90 2021-02-22 03:02:39.484000000 -0500
@@ -0,0 +1,33 @@
+! { dg-do compile }
+! { dg-options "-Ofast" }
+ SUBROUTINE FOO(N, A, B, C, D, E, F, G)
+ COMPLEX A(*)
+ LOGICAL H
+ INTEGER G
+ REAL I, C, J, F, F1, F2, K, E, L, M, B, D
+ DO JC = 1, N
+ K = F*REAL(A(JC))
+ Z = F*AIMAG(A(JC))
+ H = .FALSE.
+ L = G
+ IF(ABS(Z).LT.D .AND. I.GE. MAX(D, B*C, B*J)) THEN
+ H = .TRUE.
+ L = (D / F1) / MAX(D, F2*I)
+ END IF
+ IF(ABS(K).LT.D .AND. C.GE. MAX(D, B*I, B*J)) THEN
+ L = MAX(L, (D / F1) / MAX(D, F2*C))
+ END IF
+ IF(ABS(E).LT.D .AND. J.GE. MAX(D, B*C, B*I)) THEN
+ H = .TRUE.
+ L = MAX(L, (D / BNRM1) / MAX(D, BNRM2*J))
+ END IF
+ IF(H) THEN
+ M = (L*D)*MAX(ABS(K), ABS(Z), ABS(E))
+ END IF
+ IF(H) THEN
+ K = (L*REAL(A(JC)))*F
+ Z = (L*AIMAG(A(JC)))*F
+ END IF
+ A(JC) = CMPLX(K, Z)
+ END DO
+ END
diff -urpN a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2021-02-22 02:56:51.328000000 -0500
+++ b/gcc/tree-vect-slp.c 2021-02-22 03:03:22.676000000 -0500
@@ -3442,7 +3442,7 @@ vect_slp_bb (basic_block bb)
/* Return 1 if vector type STMT_VINFO is a boolean vector. */
static bool
-vect_mask_constant_operand_p (stmt_vec_info stmt_vinfo)
+vect_mask_constant_operand_p (stmt_vec_info stmt_vinfo, unsigned op_num)
{
enum tree_code code = gimple_expr_code (stmt_vinfo->stmt);
tree op, vectype;
@@ -3467,9 +3467,17 @@ vect_mask_constant_operand_p (stmt_vec_i
tree cond = gimple_assign_rhs1 (stmt);
if (TREE_CODE (cond) == SSA_NAME)
- op = cond;
+ {
+ if (op_num > 0)
+ return VECTOR_BOOLEAN_TYPE_P (STMT_VINFO_VECTYPE (stmt_vinfo));
+ op = cond;
+ }
else
- op = TREE_OPERAND (cond, 0);
+ {
+ if (op_num > 1)
+ return VECTOR_BOOLEAN_TYPE_P (STMT_VINFO_VECTYPE (stmt_vinfo));
+ op = TREE_OPERAND (cond, 0);
+ }
if (!vect_is_simple_use (op, stmt_vinfo->vinfo, &dt, &vectype))
gcc_unreachable ();
@@ -3600,9 +3608,10 @@ duplicate_and_interleave (vec_info *vinf
operands. */
static void
-vect_get_constant_vectors (slp_tree op_node, slp_tree slp_node,
+vect_get_constant_vectors (slp_tree slp_node, unsigned op_num,
vec<tree> *vec_oprnds)
{
+ slp_tree op_node = SLP_TREE_CHILDREN (slp_node)[op_num];
stmt_vec_info stmt_vinfo = SLP_TREE_SCALAR_STMTS (slp_node)[0];
vec_info *vinfo = stmt_vinfo->vinfo;
unsigned HOST_WIDE_INT nunits;
@@ -3624,7 +3633,7 @@ vect_get_constant_vectors (slp_tree op_n
/* Check if vector type is a boolean vector. */
tree stmt_vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (op))
- && vect_mask_constant_operand_p (stmt_vinfo))
+ && vect_mask_constant_operand_p (stmt_vinfo, op_num))
vector_type = truth_type_for (stmt_vectype);
else
vector_type = get_vectype_for_scalar_type (vinfo, TREE_TYPE (op), op_node);
@@ -3848,7 +3857,7 @@ vect_get_slp_defs (slp_tree slp_node, ve
vect_get_slp_vect_defs (child, &vec_defs);
}
else
- vect_get_constant_vectors (child, slp_node, &vec_defs);
+ vect_get_constant_vectors (slp_node, i, &vec_defs);
vec_oprnds->quick_push (vec_defs);
}
@@ -4269,6 +4278,10 @@ vectorize_slp_instance_root_stmt (slp_tr
{
tree vect_lhs = gimple_get_lhs (child_stmt_info->stmt);
tree root_lhs = gimple_get_lhs (instance->root_stmt->stmt);
+ if (!useless_type_conversion_p (TREE_TYPE (root_lhs),
+ TREE_TYPE (vect_lhs)))
+ vect_lhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (root_lhs),
+ vect_lhs);
rstmt = gimple_build_assign (root_lhs, vect_lhs);
break;
}

View File

@ -1,51 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
c69325a5db450dbac198f76f1162734af05a1061
0001-sccvn-Fix-up-push_partial_def-little-endian-bitfield.patch
diff -urpN a/gcc/testsuite/gcc.c-torture/execute/pr97764.c b/gcc/testsuite/gcc.c-torture/execute/pr97764.c
--- a/gcc/testsuite/gcc.c-torture/execute/pr97764.c 1969-12-31 19:00:00.000000000 -0500
+++ b/gcc/testsuite/gcc.c-torture/execute/pr97764.c 2020-12-07 03:42:13.404000000 -0500
@@ -0,0 +1,14 @@
+/* PR tree-optimization/97764 */
+/* { dg-require-effective-target int32plus } */
+
+struct S { int b : 3; int c : 28; int d : 1; };
+
+int
+main ()
+{
+ struct S e = {};
+ e.c = -1;
+ if (e.d)
+ __builtin_abort ();
+ return 0;
+}
diff -urpN a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
--- a/gcc/tree-ssa-sccvn.c 2020-12-07 03:43:37.792000000 -0500
+++ b/gcc/tree-ssa-sccvn.c 2020-12-07 03:42:13.404000000 -0500
@@ -2013,12 +2013,12 @@ vn_walk_cb_data::push_partial_def (const
}
else
{
- size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
if (pd.offset >= 0)
{
/* LSB of this_buffer[0] byte should be at pd.offset bits
in buffer. */
unsigned int msk;
+ size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
amnt = pd.offset % BITS_PER_UNIT;
if (amnt)
shift_bytes_in_array_left (this_buffer, len + 1, amnt);
@@ -2046,6 +2046,9 @@ vn_walk_cb_data::push_partial_def (const
{
amnt = (unsigned HOST_WIDE_INT) pd.offset % BITS_PER_UNIT;
if (amnt)
+ size -= BITS_PER_UNIT - amnt;
+ size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
+ if (amnt)
shift_bytes_in_array_left (this_buffer, len + 1, amnt);
}
memcpy (p, this_buffer + (amnt != 0), size / BITS_PER_UNIT);

View File

@ -1,139 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Fix-zero-masking-for-vcvtps2ph-when-dest-operand-is-.patch
43088bb4dadd3d14b6b594c5f9363fe879f3d7f7
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 87354451c58..7815d77bcbf 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -21775,19 +21775,19 @@
(set_attr "prefix" "maybe_evex")
(set_attr "mode" "V4SF")])
-(define_insn "*vcvtps2ph_store<mask_name>"
+(define_insn "*vcvtps2ph_store<merge_mask_name>"
[(set (match_operand:V4HI 0 "memory_operand" "=m")
(unspec:V4HI [(match_operand:V4SF 1 "register_operand" "v")
(match_operand:SI 2 "const_0_to_255_operand" "N")]
UNSPEC_VCVTPS2PH))]
"TARGET_F16C || TARGET_AVX512VL"
- "vcvtps2ph\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
+ "vcvtps2ph\t{%2, %1, %0<merge_mask_operand3>|%0<merge_mask_operand3>, %1, %2}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "maybe_evex")
(set_attr "mode" "V4SF")])
(define_insn "vcvtps2ph256<mask_name>"
- [(set (match_operand:V8HI 0 "nonimmediate_operand" "=vm")
+ [(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8SF 1 "register_operand" "v")
(match_operand:SI 2 "const_0_to_255_operand" "N")]
UNSPEC_VCVTPS2PH))]
@@ -21798,8 +21798,20 @@
(set_attr "btver2_decode" "vector")
(set_attr "mode" "V8SF")])
+(define_insn "*vcvtps2ph256<merge_mask_name>"
+ [(set (match_operand:V8HI 0 "memory_operand" "=m")
+ (unspec:V8HI [(match_operand:V8SF 1 "register_operand" "v")
+ (match_operand:SI 2 "const_0_to_255_operand" "N")]
+ UNSPEC_VCVTPS2PH))]
+ "TARGET_F16C || TARGET_AVX512VL"
+ "vcvtps2ph\t{%2, %1, %0<merge_mask_operand3>|%0<merge_mask_operand3>, %1, %2}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "maybe_evex")
+ (set_attr "btver2_decode" "vector")
+ (set_attr "mode" "V8SF")])
+
(define_insn "<mask_codefor>avx512f_vcvtps2ph512<mask_name>"
- [(set (match_operand:V16HI 0 "nonimmediate_operand" "=vm")
+ [(set (match_operand:V16HI 0 "register_operand" "=v")
(unspec:V16HI
[(match_operand:V16SF 1 "register_operand" "v")
(match_operand:SI 2 "const_0_to_255_operand" "N")]
@@ -21810,6 +21822,18 @@
(set_attr "prefix" "evex")
(set_attr "mode" "V16SF")])
+(define_insn "*avx512f_vcvtps2ph512<merge_mask_name>"
+ [(set (match_operand:V16HI 0 "memory_operand" "=m")
+ (unspec:V16HI
+ [(match_operand:V16SF 1 "register_operand" "v")
+ (match_operand:SI 2 "const_0_to_255_operand" "N")]
+ UNSPEC_VCVTPS2PH))]
+ "TARGET_AVX512F"
+ "vcvtps2ph\t{%2, %1, %0<merge_mask_operand3>|%0<merge_mask_operand3>, %1, %2}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "V16SF")])
+
;; For gather* insn patterns
(define_mode_iterator VEC_GATHER_MODE
[V2DI V2DF V4DI V4DF V4SI V4SF V8SI V8SF])
diff --git a/gcc/config/i386/subst.md b/gcc/config/i386/subst.md
index a5ca144c7f7..58ea9dc83e2 100644
--- a/gcc/config/i386/subst.md
+++ b/gcc/config/i386/subst.md
@@ -73,6 +73,18 @@
(match_operand:SUBST_V 2 "nonimm_or_0_operand" "0C")
(match_operand:<avx512fmaskmode> 3 "register_operand" "Yk")))])
+(define_subst_attr "merge_mask_name" "merge_mask" "" "_merge_mask")
+(define_subst_attr "merge_mask_operand3" "merge_mask" "" "%{%3%}")
+(define_subst "merge_mask"
+ [(set (match_operand:SUBST_V 0)
+ (match_operand:SUBST_V 1))]
+ "TARGET_AVX512F"
+ [(set (match_dup 0)
+ (vec_merge:SUBST_V
+ (match_dup 1)
+ (match_dup 0)
+ (match_operand:<avx512fmaskmode> 2 "register_operand" "Yk")))])
+
(define_subst_attr "mask_scalar_merge_name" "mask_scalar_merge" "" "_mask")
(define_subst_attr "mask_scalar_merge_operand3" "mask_scalar_merge" "" "%{%3%}")
(define_subst_attr "mask_scalar_merge_operand4" "mask_scalar_merge" "" "%{%4%}")
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vcvtps2ph-pr95254.c b/gcc/testsuite/gcc.target/i386/avx512f-vcvtps2ph-pr95254.c
new file mode 100644
index 00000000000..9e0da947368
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vcvtps2ph-pr95254.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512f" } */
+
+#include<immintrin.h>
+extern __m256i res;
+void
+foo (__m512 a, __mmask16 m)
+{
+ res = _mm512_maskz_cvtps_ph (m, a, 10);
+}
+
+/* { dg-final { scan-assembler-not "vcvtps2ph\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]\[^\n\]*res\[^\n\]*\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)"} } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vcvtps2ph-pr95254.c b/gcc/testsuite/gcc.target/i386/avx512vl-vcvtps2ph-pr95254.c
new file mode 100644
index 00000000000..0c685ea66fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vcvtps2ph-pr95254.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512vl -mavx512f" } */
+
+#include<immintrin.h>
+extern __m128i res;
+void
+foo (__m256 a, __mmask8 m)
+{
+ res = _mm256_maskz_cvtps_ph (m, a, 10);
+}
+
+void
+foo1 (__m128 a, __mmask8 m)
+{
+ res = _mm_maskz_cvtps_ph (m, a, 10);
+}
+
+/* { dg-final { scan-assembler-not "vcvtps2ph\[ \\t\]+\[^\{\n\]*%\[xy\]mm\[0-9\]\[^\n\]*res\[^\n\]*\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)"} } */

View File

@ -1,122 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Handle-POLY_INT_CST-in-copy_reference_ops_from_ref.patch
74266b00112a85660b1e9f6e546f0a2c007dd062
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/deref_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/deref_2.c
new file mode 100644
index 00000000000..08902983199
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/deref_2.c
@@ -0,0 +1,20 @@
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+#include <string.h>
+
+inline void
+copy (void *dst, svbool_t src)
+{
+ memcpy (dst, &src, svcntd ());
+}
+
+uint64_t
+f (int32_t *x, int32_t *y)
+{
+ union { uint64_t x; char c[8]; } u;
+ svbool_t pg = svptrue_b32 ();
+ copy (u.c, svcmpeq (pg, svld1 (pg, x), 0));
+ copy (u.c + 4, svcmpeq (pg, svld1 (pg, y), 1));
+ return u.x;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_8.c
new file mode 100644
index 00000000000..c7b6663eff2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilele_8.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+
+/* { dg-final { scan-assembler-not {\tptrue\t} } } */
+/* { dg-final { scan-assembler-not {\tpfalse\t} } } */
+
+void
+test1 (svbool_t *ptr)
+{
+ *ptr = svwhilele_b32_s32 (-4, 0);
+}
+
+void
+test2 (svbool_t *ptr)
+{
+ *ptr = svwhilele_b16_s64 (svcntb (), svcntb () + 8);
+}
+
+void
+test3 (svbool_t *ptr)
+{
+ *ptr = svwhilele_b64_s32 (0, 2);
+}
+
+void
+test4 (svbool_t *ptr)
+{
+ *ptr = svwhilele_b8_s64 (16, svcntb ());
+}
+
+/* { dg-final { scan-assembler-times {\twhilel[et]\t} 4 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilelt_4.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilelt_4.c
new file mode 100644
index 00000000000..849cd45c67e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/whilelt_4.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+
+/* { dg-final { scan-assembler-not {\tptrue\t} } } */
+/* { dg-final { scan-assembler-not {\tpfalse\t} } } */
+
+void
+test1 (svbool_t *ptr)
+{
+ *ptr = svwhilelt_b32_s32 (-4, 1);
+}
+
+void
+test2 (svbool_t *ptr)
+{
+ *ptr = svwhilelt_b16_s64 (svcntb (), svcntb () + 9);
+}
+
+void
+test3 (svbool_t *ptr)
+{
+ *ptr = svwhilelt_b64_s32 (0, 3);
+}
+
+void
+test4 (svbool_t *ptr)
+{
+ *ptr = svwhilelt_b8_s64 (16, svcntb ());
+}
+
+/* { dg-final { scan-assembler-times {\twhilel[et]\t} 4 } } */
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 7465bedb349..f58dbe15047 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -928,6 +928,7 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
break;
case STRING_CST:
case INTEGER_CST:
+ case POLY_INT_CST:
case COMPLEX_CST:
case VECTOR_CST:
case REAL_CST:

View File

@ -1,40 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Handle-POLY_INT_CSTs-in-declare_return_value.patch
be5f7eccf766a4c3a59b821f77ce320001df838f
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/inline_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/inline_1.c
new file mode 100644
index 00000000000..f736ac3f082
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/inline_1.c
@@ -0,0 +1,6 @@
+/* { dg-options "-O2" } */
+
+#pragma GCC aarch64 "arm_sve.h"
+
+static inline svint32_t foo () { return svdup_s32 (32); }
+svint32_t bar () { return svadd_x (svptrue_b8 (), foo (), 1); }
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 2b8b9ee58c1..9d0acd97f77 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -3654,7 +3654,7 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
/* ??? If we're assigning to a variable sized type, then we must
reuse the destination variable, because we've no good way to
create variable sized temporaries at this point. */
- else if (TREE_CODE (TYPE_SIZE_UNIT (caller_type)) != INTEGER_CST)
+ else if (!poly_int_tree_p (TYPE_SIZE_UNIT (caller_type)))
use_it = true;
/* If the callee cannot possibly modify MODIFY_DEST, then we can
@@ -3689,7 +3689,7 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
}
}
- gcc_assert (TREE_CODE (TYPE_SIZE_UNIT (callee_type)) == INTEGER_CST);
+ gcc_assert (poly_int_tree_p (TYPE_SIZE_UNIT (callee_type)));
var = copy_result_decl_to_var (result, id);
DECL_SEEN_IN_BIND_EXPR_P (var) = 1;

View File

@ -1,155 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-IRA-Handle-fully-tied-destinations-in-a-similar-way-.patch
9b0365879b3c4917f5a2485a1fca8bb678484bfe
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index cce73a1c3d4..098b0e73953 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -633,9 +633,28 @@ check_and_make_def_use_conflict (rtx dreg, rtx orig_dreg,
/* Check and make if necessary conflicts for definition DEF of class
DEF_CL of the current insn with input operands. Process only
- constraints of alternative ALT. */
+ constraints of alternative ALT.
+
+ One of three things is true when this function is called:
+
+ (1) DEF is an earlyclobber for alternative ALT. Input operands then
+ conflict with DEF in ALT unless they explicitly match DEF via 0-9
+ constraints.
+
+ (2) DEF matches (via 0-9 constraints) an operand that is an
+ earlyclobber for alternative ALT. Other input operands then
+ conflict with DEF in ALT.
+
+ (3) [FOR_TIE_P] Some input operand X matches DEF for alternative ALT.
+ Input operands with a different value from X then conflict with
+ DEF in ALT.
+
+ However, there's still a judgement call to make when deciding
+ whether a conflict in ALT is important enough to be reflected
+ in the pan-alternative allocno conflict set. */
static void
-check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
+check_and_make_def_conflict (int alt, int def, enum reg_class def_cl,
+ bool for_tie_p)
{
int use, use_match;
ira_allocno_t a;
@@ -669,14 +688,40 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
if (use == def || recog_data.operand_type[use] == OP_OUT)
continue;
+ /* An earlyclobber on DEF doesn't apply to an input operand X if X
+ explicitly matches DEF, but it applies to other input operands
+ even if they happen to be the same value as X.
+
+ In contrast, if an input operand X is tied to a non-earlyclobber
+ DEF, there's no conflict with other input operands that have the
+ same value as X. */
+ if (op_alt[use].matches == def
+ || (for_tie_p
+ && rtx_equal_p (recog_data.operand[use],
+ recog_data.operand[op_alt[def].matched])))
+ continue;
+
if (op_alt[use].anything_ok)
use_cl = ALL_REGS;
else
use_cl = op_alt[use].cl;
+ if (use_cl == NO_REGS)
+ continue;
+
+ /* If DEF is simply a tied operand, ignore cases in which this
+ alternative requires USE to have a likely-spilled class.
+ Adding a conflict would just constrain USE further if DEF
+ happens to be allocated first. */
+ if (for_tie_p && targetm.class_likely_spilled_p (use_cl))
+ continue;
/* If there's any alternative that allows USE to match DEF, do not
record a conflict. If that causes us to create an invalid
- instruction due to the earlyclobber, reload must fix it up. */
+ instruction due to the earlyclobber, reload must fix it up.
+
+ Likewise, if we're treating a tied DEF like a partial earlyclobber,
+ do not record a conflict if there's another alternative in which
+ DEF is neither tied nor earlyclobber. */
for (alt1 = 0; alt1 < recog_data.n_alternatives; alt1++)
{
if (!TEST_BIT (preferred_alternatives, alt1))
@@ -691,6 +736,12 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
&& recog_data.constraints[use - 1][0] == '%'
&& op_alt1[use - 1].matches == def))
break;
+ if (for_tie_p
+ && !op_alt1[def].earlyclobber
+ && op_alt1[def].matched < 0
+ && alternative_class (op_alt1, def) != NO_REGS
+ && alternative_class (op_alt1, use) != NO_REGS)
+ break;
}
if (alt1 < recog_data.n_alternatives)
@@ -701,8 +752,7 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
if ((use_match = op_alt[use].matches) >= 0)
{
- if (use_match == def)
- continue;
+ gcc_checking_assert (use_match != def);
if (op_alt[use_match].anything_ok)
use_cl = ALL_REGS;
@@ -717,7 +767,11 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
/* Make conflicts of early clobber pseudo registers of the current
insn with its inputs. Avoid introducing unnecessary conflicts by
checking classes of the constraints and pseudos because otherwise
- significant code degradation is possible for some targets. */
+ significant code degradation is possible for some targets.
+
+ For these purposes, tying an input to an output makes that output act
+ like an earlyclobber for inputs with a different value, since the output
+ register then has a predetermined purpose on input to the instruction. */
static void
make_early_clobber_and_input_conflicts (void)
{
@@ -732,15 +786,19 @@ make_early_clobber_and_input_conflicts (void)
if (TEST_BIT (preferred_alternatives, alt))
for (def = 0; def < n_operands; def++)
{
- def_cl = NO_REGS;
- if (op_alt[def].earlyclobber)
+ if (op_alt[def].anything_ok)
+ def_cl = ALL_REGS;
+ else
+ def_cl = op_alt[def].cl;
+ if (def_cl != NO_REGS)
{
- if (op_alt[def].anything_ok)
- def_cl = ALL_REGS;
- else
- def_cl = op_alt[def].cl;
- check_and_make_def_conflict (alt, def, def_cl);
+ if (op_alt[def].earlyclobber)
+ check_and_make_def_conflict (alt, def, def_cl, false);
+ else if (op_alt[def].matched >= 0
+ && !targetm.class_likely_spilled_p (def_cl))
+ check_and_make_def_conflict (alt, def, def_cl, true);
}
+
if ((def_match = op_alt[def].matches) >= 0
&& (op_alt[def_match].earlyclobber
|| op_alt[def].earlyclobber))
@@ -749,7 +807,7 @@ make_early_clobber_and_input_conflicts (void)
def_cl = ALL_REGS;
else
def_cl = op_alt[def_match].cl;
- check_and_make_def_conflict (alt, def, def_cl);
+ check_and_make_def_conflict (alt, def, def_cl, false);
}
}
}

View File

@ -1,27 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-PR92303-Try-to-simplify-memory-subreg.patch
a4504f32c056db781a2bdc104dffa1b29684c930
diff -uprN a/gcc/lra-spills.c b/gcc/lra-spills.c
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -421,7 +421,16 @@ remove_pseudos (rtx *loc, rtx_insn *insn)
if (*loc == NULL_RTX)
return res;
code = GET_CODE (*loc);
- if (code == REG && (i = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
+ if (code == SUBREG && REG_P (SUBREG_REG (*loc)))
+ {
+ /* Try to remove memory subregs to simplify LRA job
+ and avoid LRA cycling in case of subreg memory reload. */
+ res = remove_pseudos (&SUBREG_REG (*loc), insn);
+ if (GET_CODE (SUBREG_REG (*loc)) == MEM)
+ alter_subreg (loc, false);
+ return res;
+ }
+ else if (code == REG && (i = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
&& lra_get_regno_hard_regno (i) < 0
/* We do not want to assign memory for former scratches because
it might result in an address reload for some targets. In

View File

@ -1,70 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-PR-tree-optimization-92429-do-not-fold-when-updating.patch
f7dff7699fd70d3b8c3e637818e18c86f93ccfec
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 4d5e0494511..6e6df0bfdb8 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -1934,7 +1934,8 @@ number_of_iterations_cond (class loop *loop,
tree
simplify_replace_tree (tree expr, tree old, tree new_tree,
- tree (*valueize) (tree, void*), void *context)
+ tree (*valueize) (tree, void*), void *context,
+ bool do_fold)
{
unsigned i, n;
tree ret = NULL_TREE, e, se;
@@ -1966,7 +1967,7 @@ simplify_replace_tree (tree expr, tree old, tree new_tree,
for (i = 0; i < n; i++)
{
e = TREE_OPERAND (expr, i);
- se = simplify_replace_tree (e, old, new_tree, valueize, context);
+ se = simplify_replace_tree (e, old, new_tree, valueize, context, do_fold);
if (e == se)
continue;
@@ -1976,7 +1977,7 @@ simplify_replace_tree (tree expr, tree old, tree new_tree,
TREE_OPERAND (ret, i) = se;
}
- return (ret ? fold (ret) : expr);
+ return (ret ? (do_fold ? fold (ret) : ret) : expr);
}
/* Expand definitions of ssa names in EXPR as long as they are simple
diff --git a/gcc/tree-ssa-loop-niter.h b/gcc/tree-ssa-loop-niter.h
index 621e2c2e28d..eb8d1579479 100644
--- a/gcc/tree-ssa-loop-niter.h
+++ b/gcc/tree-ssa-loop-niter.h
@@ -58,7 +58,7 @@ extern void free_numbers_of_iterations_estimates (class loop *);
extern void free_numbers_of_iterations_estimates (function *);
extern tree simplify_replace_tree (tree, tree,
tree, tree (*)(tree, void *) = NULL,
- void * = NULL);
+ void * = NULL, bool do_fold = true);
extern void substitute_in_loop_info (struct loop *, tree, tree);
#endif /* GCC_TREE_SSA_LOOP_NITER_H */
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 8e318a037a7..e5fb434bd4e 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -8434,8 +8434,13 @@ update_epilogue_loop_vinfo (class loop *epilogue, tree advance)
gimple_set_op (stmt, j, *new_op);
else
{
+ /* PR92429: The last argument of simplify_replace_tree disables
+ folding when replacing arguments. This is required as
+ otherwise you might end up with different statements than the
+ ones analyzed in vect_loop_analyze, leading to different
+ vectorization. */
op = simplify_replace_tree (op, NULL_TREE, NULL_TREE,
- &find_in_mapping, &mapping);
+ &find_in_mapping, &mapping, false);
gimple_set_op (stmt, j, op);
}
}

View File

@ -1,99 +0,0 @@
This backport contains 2 patchs from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
97b798d80baf945ea28236eef3fa69f36626b579
0001-SLP-VECT-Add-check-to-fix-96837.patch
373b99dc40949efa697326f378e5022a02e0328b
0002-Add-a-testcase-for-PR-target-96827.patch
diff -uprN a/gcc/testsuite/gcc.dg/vect/bb-slp-49.c b/gcc/testsuite/gcc.dg/vect/bb-slp-49.c
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-49.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-49.c 2020-11-17 15:58:12.118126065 +0800
@@ -0,0 +1,28 @@
+/* This checks that vectorized constructors have the correct ordering. */
+/* { dg-require-effective-target vect_int } */
+
+typedef int V __attribute__((__vector_size__(16)));
+
+__attribute__((__noipa__)) void
+foo (unsigned int x, V *y)
+{
+ unsigned int a[4] = { x + 0, x + 2, x + 4, x + 6 };
+ for (unsigned int i = 0; i < 3; ++i)
+ if (a[i] == 1234)
+ a[i]--;
+ *y = (V) { a[3], a[2], a[1], a[0] };
+}
+
+int
+main ()
+{
+ V b;
+ foo (0, &b);
+ if (b[0] != 6 || b[1] != 4 || b[2] != 2 || b[3] != 0)
+ __builtin_abort ();
+ return 0;
+}
+
+/* See that we vectorize an SLP instance. */
+/* { dg-final { scan-tree-dump "Analyzing vectorizable constructor" "slp1" } } */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "slp1" } } */
diff -uprN a/gcc/testsuite/gcc.target/i386/pr96827.c b/gcc/testsuite/gcc.target/i386/pr96827.c
--- a/gcc/testsuite/gcc.target/i386/pr96827.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.target/i386/pr96827.c 2020-11-17 15:58:15.182126065 +0800
@@ -0,0 +1,41 @@
+/* { dg-do run { target sse2_runtime } } */
+/* { dg-options "-O3 -msse2 -mfpmath=sse" } */
+
+typedef unsigned short int __uint16_t;
+typedef unsigned int __uint32_t;
+typedef __uint16_t uint16_t;
+typedef __uint32_t uint32_t;
+typedef int __v4si __attribute__ ((__vector_size__ (16)));
+typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
+extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_store_si128 (__m128i *__P, __m128i __B)
+{
+ *__P = __B;
+}
+extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_set_epi32 (int __q3, int __q2, int __q1, int __q0)
+{
+ return __extension__ (__m128i)(__v4si){ __q0, __q1, __q2, __q3 };
+}
+typedef uint16_t u16;
+typedef uint32_t u32;
+extern int printf (const char *__restrict __format, ...);
+void do_the_thing(u32 idx, __m128i *dude)
+{
+ u32 dude_[4] = { idx+0, idx+2, idx+4, idx+6 };
+ for (u32 i = 0; i < 3; ++i)
+ if (dude_[i] == 1234)
+ dude_[i]--;
+ *dude = _mm_set_epi32(dude_[0], dude_[1], dude_[2], dude_[3]);
+}
+int main()
+{
+ __m128i dude;
+ u32 idx = 0;
+ do_the_thing(idx, &dude);
+ __attribute__((aligned(16))) u32 dude_[4];
+ _mm_store_si128((__m128i*)dude_, dude);
+ if (!(6 == dude_[0] && 4 == dude_[1] && 2 == dude_[2] && 0 == dude_[3]))
+ __builtin_abort ();
+ return 0;
+}
diff -uprN a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2020-11-17 15:55:57.098126065 +0800
+++ b/gcc/tree-vect-slp.c 2020-11-17 15:59:25.862126065 +0800
@@ -1842,7 +1842,8 @@ vect_supported_load_permutation_p (slp_i
/* Reduction (there are no data-refs in the root).
In reduction chain the order of the loads is not important. */
if (!STMT_VINFO_DATA_REF (stmt_info)
- && !REDUC_GROUP_FIRST_ELEMENT (stmt_info))
+ && !REDUC_GROUP_FIRST_ELEMENT (stmt_info)
+ && !SLP_INSTANCE_ROOT_STMT (slp_instn))
vect_attempt_slp_rearrange_stmts (slp_instn);
/* In basic block vectorization we allow any subchain of an interleaving

View File

@ -1,197 +0,0 @@
This backport contains 2 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Simplify-X-C1-C2-with-undefined-overflow.patch
ca2b8c082c4f16919071c9f8de8db0b33b54c405
0002-Simplify-X-C1-C2-with-wrapping-overflow.patch
287522613d661b4c5ba8403b051eb470c1674cba
diff -Nurp a/gcc/expr.c b/gcc/expr.c
--- a/gcc/expr.c 2021-03-17 16:34:24.700000000 +0800
+++ b/gcc/expr.c 2021-03-17 10:30:11.500000000 +0800
@@ -11706,38 +11706,6 @@ string_constant (tree arg, tree *ptr_off
return init;
}
-/* Compute the modular multiplicative inverse of A modulo M
- using extended Euclid's algorithm. Assumes A and M are coprime. */
-static wide_int
-mod_inv (const wide_int &a, const wide_int &b)
-{
- /* Verify the assumption. */
- gcc_checking_assert (wi::eq_p (wi::gcd (a, b), 1));
-
- unsigned int p = a.get_precision () + 1;
- gcc_checking_assert (b.get_precision () + 1 == p);
- wide_int c = wide_int::from (a, p, UNSIGNED);
- wide_int d = wide_int::from (b, p, UNSIGNED);
- wide_int x0 = wide_int::from (0, p, UNSIGNED);
- wide_int x1 = wide_int::from (1, p, UNSIGNED);
-
- if (wi::eq_p (b, 1))
- return wide_int::from (1, p, UNSIGNED);
-
- while (wi::gt_p (c, 1, UNSIGNED))
- {
- wide_int t = d;
- wide_int q = wi::divmod_trunc (c, d, UNSIGNED, &d);
- c = t;
- wide_int s = x0;
- x0 = wi::sub (x1, wi::mul (q, x0));
- x1 = s;
- }
- if (wi::lt_p (x1, 0, SIGNED))
- x1 += d;
- return x1;
-}
-
/* Optimize x % C1 == C2 for signed modulo if C1 is a power of two and C2
is non-zero and C3 ((1<<(prec-1)) | (C1 - 1)):
for C2 > 0 to x & C3 == C2
@@ -11948,7 +11916,7 @@ maybe_optimize_mod_cmp (enum tree_code c
w = wi::lrshift (w, shift);
wide_int a = wide_int::from (w, prec + 1, UNSIGNED);
wide_int b = wi::shifted_mask (prec, 1, false, prec + 1);
- wide_int m = wide_int::from (mod_inv (a, b), prec, UNSIGNED);
+ wide_int m = wide_int::from (wi::mod_inv (a, b), prec, UNSIGNED);
tree c3 = wide_int_to_tree (type, m);
tree c5 = NULL_TREE;
wide_int d, e;
diff -Nurp a/gcc/match.pd b/gcc/match.pd
--- a/gcc/match.pd 2021-03-17 16:34:19.320000000 +0800
+++ b/gcc/match.pd 2021-03-17 10:30:11.500000000 +0800
@@ -3290,6 +3290,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(scmp @0 @2)
(cmp @0 @2))))))
+/* For integral types with undefined overflow fold
+ x * C1 == C2 into x == C2 / C1 or false.
+ If overflow wraps and C1 is odd, simplify to x == C2 / C1 in the ring
+ Z / 2^n Z. */
+(for cmp (eq ne)
+ (simplify
+ (cmp (mult @0 INTEGER_CST@1) INTEGER_CST@2)
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
+ && wi::to_wide (@1) != 0)
+ (with { widest_int quot; }
+ (if (wi::multiple_of_p (wi::to_widest (@2), wi::to_widest (@1),
+ TYPE_SIGN (TREE_TYPE (@0)), &quot))
+ (cmp @0 { wide_int_to_tree (TREE_TYPE (@0), quot); })
+ { constant_boolean_node (cmp == NE_EXPR, type); }))
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))
+ && (wi::bit_and (wi::to_wide (@1), 1) == 1))
+ (cmp @0
+ {
+ tree itype = TREE_TYPE (@0);
+ int p = TYPE_PRECISION (itype);
+ wide_int m = wi::one (p + 1) << p;
+ wide_int a = wide_int::from (wi::to_wide (@1), p + 1, UNSIGNED);
+ wide_int i = wide_int::from (wi::mod_inv (a, m),
+ p, TYPE_SIGN (itype));
+ wide_int_to_tree (itype, wi::mul (i, wi::to_wide (@2)));
+ })))))
+
/* Simplify comparison of something with itself. For IEEE
floating-point, we can only do some of these simplifications. */
(for cmp (eq ge le)
diff -Nurp a/gcc/testsuite/gcc.c-torture/execute/pr23135.c b/gcc/testsuite/gcc.c-torture/execute/pr23135.c
--- a/gcc/testsuite/gcc.c-torture/execute/pr23135.c 2021-03-17 16:34:24.016000000 +0800
+++ b/gcc/testsuite/gcc.c-torture/execute/pr23135.c 2021-03-17 10:30:13.572000000 +0800
@@ -1,7 +1,7 @@
/* Based on execute/simd-1.c, modified by joern.rennecke@st.com to
trigger a reload bug. Verified for gcc mainline from 20050722 13:00 UTC
for sh-elf -m4 -O2. */
-/* { dg-options "-Wno-psabi" } */
+/* { dg-options "-Wno-psabi -fwrapv" } */
/* { dg-add-options stack_size } */
#ifndef STACK_SIZE
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr95433-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr95433-2.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr95433-2.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr95433-2.c 2021-03-17 10:30:13.276000000 +0800
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fwrapv -fdump-tree-gimple" } */
+
+typedef __INT32_TYPE__ int32_t;
+typedef unsigned __INT32_TYPE__ uint32_t;
+
+int e(int32_t x){return 3*x==5;}
+int f(int32_t x){return 3*x==-5;}
+int g(int32_t x){return -3*x==5;}
+int h(int32_t x){return 7*x==3;}
+int i(uint32_t x){return 7*x==3;}
+
+/* { dg-final { scan-tree-dump-times "== 1431655767" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "== -1431655767" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "== 613566757" 2 "gimple" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr95433.c b/gcc/testsuite/gcc.dg/tree-ssa/pr95433.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr95433.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr95433.c 2021-03-17 10:30:13.276000000 +0800
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+int f(int x){return x*7==17;}
+int g(int x){return x*3==15;}
+
+/* { dg-final { scan-tree-dump "return 0;" "optimized" } } */
+/* { dg-final { scan-tree-dump "== 5;" "optimized" } } */
diff -Nurp a/gcc/wide-int.cc b/gcc/wide-int.cc
--- a/gcc/wide-int.cc 2021-03-17 16:34:24.488000000 +0800
+++ b/gcc/wide-int.cc 2021-03-17 10:30:11.500000000 +0800
@@ -2223,6 +2223,39 @@ wi::round_up_for_mask (const wide_int &v
return (val | tmp) & -tmp;
}
+/* Compute the modular multiplicative inverse of A modulo B
+ using extended Euclid's algorithm. Assumes A and B are coprime,
+ and that A and B have the same precision. */
+wide_int
+wi::mod_inv (const wide_int &a, const wide_int &b)
+{
+ /* Verify the assumption. */
+ gcc_checking_assert (wi::eq_p (wi::gcd (a, b), 1));
+
+ unsigned int p = a.get_precision () + 1;
+ gcc_checking_assert (b.get_precision () + 1 == p);
+ wide_int c = wide_int::from (a, p, UNSIGNED);
+ wide_int d = wide_int::from (b, p, UNSIGNED);
+ wide_int x0 = wide_int::from (0, p, UNSIGNED);
+ wide_int x1 = wide_int::from (1, p, UNSIGNED);
+
+ if (wi::eq_p (b, 1))
+ return wide_int::from (1, p, UNSIGNED);
+
+ while (wi::gt_p (c, 1, UNSIGNED))
+ {
+ wide_int t = d;
+ wide_int q = wi::divmod_trunc (c, d, UNSIGNED, &d);
+ c = t;
+ wide_int s = x0;
+ x0 = wi::sub (x1, wi::mul (q, x0));
+ x1 = s;
+ }
+ if (wi::lt_p (x1, 0, SIGNED))
+ x1 += d;
+ return x1;
+}
+
/*
* Private utilities.
*/
diff -Nurp a/gcc/wide-int.h b/gcc/wide-int.h
--- a/gcc/wide-int.h 2021-03-17 16:34:14.792000000 +0800
+++ b/gcc/wide-int.h 2021-03-17 10:30:11.500000000 +0800
@@ -3368,6 +3368,8 @@ namespace wi
wide_int round_down_for_mask (const wide_int &, const wide_int &);
wide_int round_up_for_mask (const wide_int &, const wide_int &);
+ wide_int mod_inv (const wide_int &a, const wide_int &b);
+
template <typename T>
T mask (unsigned int, bool);

View File

@ -1,165 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
7a6588fe65432c0f1a8b5fdefba81700ebf88711
0001-aarch64-Fix-ash-lr-lshr-mode-3-expanders-PR94488.patch
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 24a11fb5040..9f0e2bd1e6f 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1105,31 +1105,17 @@
tmp));
DONE;
}
- else
- {
- operands[2] = force_reg (SImode, operands[2]);
- }
- }
- else if (MEM_P (operands[2]))
- {
- operands[2] = force_reg (SImode, operands[2]);
}
- if (REG_P (operands[2]))
- {
- rtx tmp = gen_reg_rtx (<MODE>mode);
- emit_insn (gen_aarch64_simd_dup<mode> (tmp,
- convert_to_mode (<VEL>mode,
- operands[2],
- 0)));
- emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1],
- tmp));
- DONE;
- }
- else
- FAIL;
-}
-)
+ operands[2] = force_reg (SImode, operands[2]);
+
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_aarch64_simd_dup<mode> (tmp, convert_to_mode (<VEL>mode,
+ operands[2],
+ 0)));
+ emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1], tmp));
+ DONE;
+})
(define_expand "lshr<mode>3"
[(match_operand:VDQ_I 0 "register_operand")
@@ -1152,31 +1138,19 @@
tmp));
DONE;
}
- else
- operands[2] = force_reg (SImode, operands[2]);
- }
- else if (MEM_P (operands[2]))
- {
- operands[2] = force_reg (SImode, operands[2]);
}
- if (REG_P (operands[2]))
- {
- rtx tmp = gen_reg_rtx (SImode);
- rtx tmp1 = gen_reg_rtx (<MODE>mode);
- emit_insn (gen_negsi2 (tmp, operands[2]));
- emit_insn (gen_aarch64_simd_dup<mode> (tmp1,
- convert_to_mode (<VEL>mode,
- tmp, 0)));
- emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0],
- operands[1],
- tmp1));
- DONE;
- }
- else
- FAIL;
-}
-)
+ operands[2] = force_reg (SImode, operands[2]);
+
+ rtx tmp = gen_reg_rtx (SImode);
+ rtx tmp1 = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_negsi2 (tmp, operands[2]));
+ emit_insn (gen_aarch64_simd_dup<mode> (tmp1,
+ convert_to_mode (<VEL>mode, tmp, 0)));
+ emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0], operands[1],
+ tmp1));
+ DONE;
+})
(define_expand "ashr<mode>3"
[(match_operand:VDQ_I 0 "register_operand")
@@ -1199,31 +1173,19 @@
tmp));
DONE;
}
- else
- operands[2] = force_reg (SImode, operands[2]);
- }
- else if (MEM_P (operands[2]))
- {
- operands[2] = force_reg (SImode, operands[2]);
}
- if (REG_P (operands[2]))
- {
- rtx tmp = gen_reg_rtx (SImode);
- rtx tmp1 = gen_reg_rtx (<MODE>mode);
- emit_insn (gen_negsi2 (tmp, operands[2]));
- emit_insn (gen_aarch64_simd_dup<mode> (tmp1,
- convert_to_mode (<VEL>mode,
- tmp, 0)));
- emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0],
- operands[1],
- tmp1));
- DONE;
- }
- else
- FAIL;
-}
-)
+ operands[2] = force_reg (SImode, operands[2]);
+
+ rtx tmp = gen_reg_rtx (SImode);
+ rtx tmp1 = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_negsi2 (tmp, operands[2]));
+ emit_insn (gen_aarch64_simd_dup<mode> (tmp1, convert_to_mode (<VEL>mode,
+ tmp, 0)));
+ emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0], operands[1],
+ tmp1));
+ DONE;
+})
(define_expand "vashl<mode>3"
[(match_operand:VDQ_I 0 "register_operand")
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr94488.c b/gcc/testsuite/gcc.c-torture/compile/pr94488.c
new file mode 100644
index 00000000000..6e20a4168de
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr94488.c
@@ -0,0 +1,22 @@
+/* PR target/94488 */
+
+typedef unsigned long V __attribute__((__vector_size__(16)));
+typedef long W __attribute__((__vector_size__(16)));
+
+void
+foo (V *x, unsigned long y)
+{
+ *x = *x >> (unsigned int) y;
+}
+
+void
+bar (V *x, unsigned long y)
+{
+ *x = *x << (unsigned int) y;
+}
+
+void
+baz (W *x, unsigned long y)
+{
+ *x = *x >> (unsigned int) y;
+}

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-aarch64-Fix-mismatched-SVE-predicate-modes.patch
26bebf576ddcdcfb596f07e8c2896f17c48516e7
diff -urpN a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
--- a/gcc/config/aarch64/aarch64.c 2020-12-14 00:57:20.128000000 -0500
+++ b/gcc/config/aarch64/aarch64.c 2020-12-14 01:00:15.080000000 -0500
@@ -4328,6 +4328,7 @@ aarch64_expand_sve_const_pred_eor (rtx t
/* EOR the result with an ELT_SIZE PTRUE. */
rtx mask = aarch64_ptrue_all (elt_size);
mask = force_reg (VNx16BImode, mask);
+ inv = gen_lowpart (VNx16BImode, inv);
target = aarch64_target_reg (target, VNx16BImode);
emit_insn (gen_aarch64_pred_z (XOR, VNx16BImode, target, mask, inv, mask));
return target;
diff -urpN a/gcc/testsuite/gcc.dg/vect/pr94606.c b/gcc/testsuite/gcc.dg/vect/pr94606.c
--- a/gcc/testsuite/gcc.dg/vect/pr94606.c 1969-12-31 19:00:00.000000000 -0500
+++ b/gcc/testsuite/gcc.dg/vect/pr94606.c 2020-12-14 01:00:15.080000000 -0500
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=armv8.2-a+sve -msve-vector-bits=256" { target aarch64*-*-* } } */
+
+const short mask[] = { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1 };
+
+int
+foo (short *restrict x, short *restrict y)
+{
+ for (int i = 0; i < 16; ++i)
+ if (mask[i])
+ x[i] += y[i];
+}

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +0,0 @@
--- a/gcc/haifa-sched.c 2021-03-08 14:46:59.204000000 +0800
+++ b/gcc/haifa-sched.c 2021-03-09 13:32:40.656000000 +0800
@@ -2036,8 +2036,10 @@ model_start_update_pressure (struct mode
/* The instruction wasn't part of the model schedule; it was moved
from a different block. Update the pressure for the end of
the model schedule. */
- MODEL_REF_PRESSURE (group, point, pci) += delta;
- MODEL_MAX_PRESSURE (group, point, pci) += delta;
+ if (MODEL_REF_PRESSURE (group, point, pci) != -1 || delta > 0)
+ MODEL_REF_PRESSURE (group, point, pci) += delta;
+ if (MODEL_MAX_PRESSURE (group, point, pci) != -1 || delta > 0)
+ MODEL_MAX_PRESSURE (group, point, pci) += delta;
}
else
{
diff -uprN a/gcc/testsuite/gcc.dg/sche1-pressure-check.c b/gcc/testsuite/gcc.dg/sche1-pressure-check.c
--- a/gcc/testsuite/gcc.dg/sche1-pressure-check.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/sche1-pressure-check.c 2021-03-09 13:40:34.036000000 +0800
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int a, g, h;
+char b, c;
+short d;
+static int e;
+int *volatile f;
+void i() {
+ int j = 0;
+ int *k = &a;
+ for (; c; c--) {
+ g && (d = 0);
+ j ^= 10;
+ {
+ int l[2];
+ l;
+ h = l[1];
+ }
+ e = 1;
+ for (; e <= 7; e++) {
+ *k = 6;
+ *f = b = 0;
+ for (; b <= 7; b++) {
+ int m = 5;
+ if (g)
+ *k &= m ^= j;
+ }
+ }
+ }
+}
+int main() {}
+

View File

@ -1,86 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-optimization-95855-Add-checks-to-avoid-spoiling.patch
33d114f570b4a3583421c700396fd5945acebc28
diff -uprN a/gcc/gimple-ssa-split-paths.c b/gcc/gimple-ssa-split-paths.c
--- a/gcc/gimple-ssa-split-paths.c
+++ b/gcc/gimple-ssa-split-paths.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
+#include "fold-const.h"
/* Given LATCH, the latch block in a loop, see if the shape of the
path reaching LATCH is suitable for being split by duplication.
@@ -254,6 +255,44 @@ is_feasible_trace (basic_block bb)
}
}
+ /* Canonicalize the form. */
+ if (single_pred_p (pred1) && single_pred (pred1) == pred2
+ && num_stmts_in_pred1 == 0)
+ std::swap (pred1, pred2);
+
+ /* This is meant to catch another kind of cases that are likely opportunities
+ for if-conversion. After canonicalizing, PRED2 must be an empty block and
+ PRED1 must be the only predecessor of PRED2. Moreover, PRED1 is supposed
+ to end with a cond_stmt which has the same args with the PHI in BB. */
+ if (single_pred_p (pred2) && single_pred (pred2) == pred1
+ && num_stmts_in_pred2 == 0)
+ {
+ gimple *cond_stmt = last_stmt (pred1);
+ if (cond_stmt && gimple_code (cond_stmt) == GIMPLE_COND)
+ {
+ tree lhs = gimple_cond_lhs (cond_stmt);
+ tree rhs = gimple_cond_rhs (cond_stmt);
+
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple *phi = gsi_stmt (gsi);
+ if ((operand_equal_p (gimple_phi_arg_def (phi, 0), lhs)
+ && operand_equal_p (gimple_phi_arg_def (phi, 1), rhs))
+ || (operand_equal_p (gimple_phi_arg_def (phi, 0), rhs)
+ && (operand_equal_p (gimple_phi_arg_def (phi, 1), lhs))))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "Block %d appears to be optimized to a join "
+ "point for if-convertable half-diamond.\n",
+ bb->index);
+ return false;
+ }
+ }
+ }
+ }
+
/* If the joiner has no PHIs with useful uses there is zero chance
of CSE/DCE/jump-threading possibilities exposed by duplicating it. */
bool found_useful_phi = false;
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/split-path-12.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-12.c
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-12.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details " } */
+
+double
+foo(double *d1, double *d2, double *d3, int num, double *ip)
+{
+ double dmax[3];
+
+ for (int i = 0; i < num; i++) {
+ dmax[0] = d1[i] < dmax[0] ? dmax[0] : d1[i];
+ dmax[1] = d2[i] < dmax[1] ? dmax[1] : d2[i];
+ dmax[2] = d3[i] < dmax[2] ? dmax[2] : d3[i];
+ ip[i] = dmax[2];
+ }
+
+ return dmax[0] + dmax[1] + dmax[2];
+}
+
+/* { dg-final { scan-tree-dump "appears to be optimized to a join point for if-convertable half-diamond" "split-paths" } } */

View File

@ -1,376 +0,0 @@
diff -Nurp a/gcc/common.opt b/gcc/common.opt
--- a/gcc/common.opt 2021-02-18 21:22:07.216000000 +0800
+++ b/gcc/common.opt 2021-02-19 16:04:17.876000000 +0800
@@ -1506,6 +1506,32 @@ ffp-int-builtin-inexact
Common Report Var(flag_fp_int_builtin_inexact) Init(1) Optimization
Allow built-in functions ceil, floor, round, trunc to raise \"inexact\" exceptions.
+fftz
+Common Report Var(flag_ftz) Optimization
+Control fpcr register for flush to zero.
+
+fp-model=
+Common Joined RejectNegative Enum(fp_model) Var(flag_fp_model) Init(FP_MODEL_NORMAL) Optimization
+-fp-model=[normal|fast|precise|except|strict] Perform floating-point precision control.
+
+Enum
+Name(fp_model) Type(enum fp_model) UnknownError(unknown floating point precision model %qs)
+
+EnumValue
+Enum(fp_model) String(normal) Value(FP_MODEL_NORMAL)
+
+EnumValue
+Enum(fp_model) String(fast) Value(FP_MODEL_FAST)
+
+EnumValue
+Enum(fp_model) String(precise) Value(FP_MODEL_PRECISE)
+
+EnumValue
+Enum(fp_model) String(except) Value(FP_MODEL_EXCEPT)
+
+EnumValue
+Enum(fp_model) String(strict) Value(FP_MODEL_STRICT)
+
; Nonzero means don't put addresses of constant functions in registers.
; Used for compiling the Unix kernel, where strange substitutions are
; done on the assembly output.
diff -Nurp a/gcc/config/aarch64/aarch64-linux.h b/gcc/config/aarch64/aarch64-linux.h
--- a/gcc/config/aarch64/aarch64-linux.h 2021-02-18 21:22:07.220000000 +0800
+++ b/gcc/config/aarch64/aarch64-linux.h 2021-02-18 21:23:55.932000000 +0800
@@ -50,7 +50,8 @@
#define LINK_SPEC LINUX_TARGET_LINK_SPEC AARCH64_ERRATA_LINK_SPEC
#define GNU_USER_TARGET_MATHFILE_SPEC \
- "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
+ "%{Ofast|ffast-math|funsafe-math-optimizations|fp-model=fast|fftz:\
+ %{!fno-ftz:crtfastmath.o%s}}"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
diff -Nurp a/gcc/flag-types.h b/gcc/flag-types.h
--- a/gcc/flag-types.h 2020-03-12 19:07:21.000000000 +0800
+++ b/gcc/flag-types.h 2021-02-18 21:23:55.932000000 +0800
@@ -207,6 +207,15 @@ enum fp_contract_mode {
FP_CONTRACT_FAST = 2
};
+/* Floating-point precision mode. */
+enum fp_model {
+ FP_MODEL_NORMAL = 0,
+ FP_MODEL_FAST = 1,
+ FP_MODEL_PRECISE = 2,
+ FP_MODEL_EXCEPT = 3,
+ FP_MODEL_STRICT = 4
+};
+
/* Scalar storage order kind. */
enum scalar_storage_order_kind {
SSO_NATIVE = 0,
diff -Nurp a/gcc/fortran/options.c b/gcc/fortran/options.c
--- a/gcc/fortran/options.c 2020-03-12 19:07:21.000000000 +0800
+++ b/gcc/fortran/options.c 2021-02-18 21:23:55.932000000 +0800
@@ -247,6 +247,7 @@ form_from_filename (const char *filename
return f_form;
}
+static void gfc_handle_fpe_option (const char *arg, bool trap);
/* Finalize commandline options. */
@@ -274,6 +275,13 @@ gfc_post_options (const char **pfilename
if (flag_protect_parens == -1)
flag_protect_parens = !optimize_fast;
+ /* If fp-model=precise/strict, turn on all ffpe-trap and ffpe-summary. */
+ if (flag_fp_model == FP_MODEL_EXCEPT || flag_fp_model == FP_MODEL_STRICT)
+ {
+ gfc_handle_fpe_option ("all", false);
+ gfc_handle_fpe_option ("invalid,zero,overflow,underflow", true);
+ }
+
/* -Ofast sets implies -fstack-arrays unless an explicit size is set for
stack arrays. */
if (flag_stack_arrays == -1 && flag_max_stack_var_size == -2)
diff -Nurp a/gcc/opts.c b/gcc/opts.c
--- a/gcc/opts.c 2021-02-18 21:22:07.424000000 +0800
+++ b/gcc/opts.c 2021-02-19 16:00:08.628000000 +0800
@@ -196,6 +196,7 @@ static void set_debug_level (enum debug_
struct gcc_options *opts_set,
location_t loc);
static void set_fast_math_flags (struct gcc_options *opts, int set);
+static void set_fp_model_flags (struct gcc_options *opts, int set);
static void decode_d_option (const char *arg, struct gcc_options *opts,
location_t loc, diagnostic_context *dc);
static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
@@ -2433,6 +2434,10 @@ common_handle_option (struct gcc_options
set_fast_math_flags (opts, value);
break;
+ case OPT_fp_model_:
+ set_fp_model_flags (opts, value);
+ break;
+
case OPT_funsafe_math_optimizations:
set_unsafe_math_optimizations_flags (opts, value);
break;
@@ -2905,6 +2910,69 @@ set_fast_math_flags (struct gcc_options
}
}
+/* Handle fp-model options. */
+static void
+set_fp_model_flags (struct gcc_options *opts, int set)
+{
+ enum fp_model model = (enum fp_model) set;
+ switch (model)
+ {
+ case FP_MODEL_FAST:
+ /* Equivalent to open ffast-math. */
+ set_fast_math_flags (opts, 1);
+ break;
+
+ case FP_MODEL_PRECISE:
+ /* Equivalent to close ffast-math. */
+ set_fast_math_flags (opts, 0);
+ /* Turn on -frounding-math -fsignaling-nans. */
+ if (!opts->frontend_set_flag_signaling_nans)
+ opts->x_flag_signaling_nans = 1;
+ if (!opts->frontend_set_flag_rounding_math)
+ opts->x_flag_rounding_math = 1;
+ opts->x_flag_expensive_optimizations = 0;
+ opts->x_flag_code_hoisting = 0;
+ opts->x_flag_predictive_commoning = 0;
+ opts->x_flag_fp_contract_mode = FP_CONTRACT_OFF;
+ break;
+
+ case FP_MODEL_EXCEPT:
+ if (!opts->frontend_set_flag_signaling_nans)
+ opts->x_flag_signaling_nans = 1;
+ if (!opts->frontend_set_flag_errno_math)
+ opts->x_flag_errno_math = 1;
+ if (!opts->frontend_set_flag_trapping_math)
+ opts->x_flag_trapping_math = 1;
+ opts->x_flag_fp_int_builtin_inexact = 1;
+ /* Also turn on ffpe-trap in fortran. */
+ break;
+
+ case FP_MODEL_STRICT:
+ /* Turn on both precise and except. */
+ if (!opts->frontend_set_flag_signaling_nans)
+ opts->x_flag_signaling_nans = 1;
+ if (!opts->frontend_set_flag_rounding_math)
+ opts->x_flag_rounding_math = 1;
+ opts->x_flag_expensive_optimizations = 0;
+ opts->x_flag_code_hoisting = 0;
+ opts->x_flag_predictive_commoning = 0;
+ if (!opts->frontend_set_flag_errno_math)
+ opts->x_flag_errno_math = 1;
+ if (!opts->frontend_set_flag_trapping_math)
+ opts->x_flag_trapping_math = 1;
+ opts->x_flag_fp_int_builtin_inexact = 1;
+ opts->x_flag_fp_contract_mode = FP_CONTRACT_OFF;
+ break;
+
+ case FP_MODEL_NORMAL:
+ /* Do nothing. */
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* When -funsafe-math-optimizations is set the following
flags are set as well. */
static void
diff -Nurp a/gcc/opts-common.c b/gcc/opts-common.c
--- a/gcc/opts-common.c 2020-03-12 19:07:21.000000000 +0800
+++ b/gcc/opts-common.c 2021-02-19 09:49:18.880000000 +0800
@@ -26,7 +26,8 @@ along with GCC; see the file COPYING3.
#include "diagnostic.h"
#include "spellcheck.h"
-static void prune_options (struct cl_decoded_option **, unsigned int *);
+static void prune_options (struct cl_decoded_option **, unsigned int *,
+ unsigned int);
/* An option that is undocumented, that takes a joined argument, and
that doesn't fit any of the classes of uses (language/common,
@@ -968,7 +969,7 @@ decode_cmdline_options_to_array (unsigne
*decoded_options = opt_array;
*decoded_options_count = num_decoded_options;
- prune_options (decoded_options, decoded_options_count);
+ prune_options (decoded_options, decoded_options_count, lang_mask);
}
/* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the
@@ -989,11 +990,108 @@ cancel_option (int opt_idx, int next_opt
return false;
}
+/* Check whether opt_idx exists in decoded_options array bewteen index
+ start and end. If found, return its index in decoded_options,
+ else return end. */
+static unsigned int
+find_opt_idx (struct cl_decoded_option *decoded_options,
+ unsigned int decoded_options_count,
+ unsigned int start, unsigned int end, unsigned int opt_idx)
+{
+ gcc_assert (end <= decoded_options_count);
+ gcc_assert (opt_idx < cl_options_count);
+ unsigned int k;
+ for (k = start; k < end; k++)
+ {
+ if (decoded_options[k].opt_index == opt_idx)
+ {
+ return k;
+ }
+ }
+ return k;
+}
+
+/* remove the opt_index element from decoded_options array. */
+static unsigned int
+remove_option (struct cl_decoded_option *decoded_options,
+ unsigned int decoded_options_count,
+ unsigned int opt_index)
+{
+ gcc_assert (opt_index < decoded_options_count);
+ unsigned int i;
+ for (i = opt_index; i < decoded_options_count - 1; i++)
+ {
+ decoded_options[i] = decoded_options[i + 1];
+ }
+ return decoded_options_count - 1;
+}
+
+/* Handle the priority between fp-model, Ofast, and
+ ffast-math. */
+static unsigned int
+handle_fp_model_driver (struct cl_decoded_option *decoded_options,
+ unsigned int decoded_options_count,
+ unsigned int fp_model_index,
+ unsigned int lang_mask)
+{
+ struct cl_decoded_option fp_model_opt = decoded_options[fp_model_index];
+ enum fp_model model = (enum fp_model) fp_model_opt.value;
+ if (model == FP_MODEL_PRECISE || model == FP_MODEL_STRICT)
+ {
+ /* If found Ofast, override Ofast with O3. */
+ unsigned int Ofast_index;
+ Ofast_index = find_opt_idx (decoded_options, decoded_options_count,
+ 0, decoded_options_count, OPT_Ofast);
+ while (Ofast_index != decoded_options_count)
+ {
+ const char *tmp_argv = "-O3";
+ decode_cmdline_option (&tmp_argv, lang_mask,
+ &decoded_options[Ofast_index]);
+ warning (0, "'-Ofast' is degraded to '-O3' due to %qs",
+ fp_model_opt.orig_option_with_args_text);
+ Ofast_index = find_opt_idx (decoded_options, decoded_options_count,
+ 0, decoded_options_count, OPT_Ofast);
+ }
+ /* If found ffast-math before fp-model=precise/strict
+ it, cancel it. */
+ unsigned int ffast_math_index;
+ ffast_math_index
+ = find_opt_idx (decoded_options, decoded_options_count, 0,
+ fp_model_index, OPT_ffast_math);
+ if (ffast_math_index != fp_model_index)
+ {
+ decoded_options_count
+ = remove_option (decoded_options, decoded_options_count,
+ ffast_math_index);
+ warning (0, "'-ffast-math' before %qs is canceled",
+ fp_model_opt.orig_option_with_args_text);
+ }
+ }
+ if (model == FP_MODEL_FAST)
+ {
+ /* If found -fno-fast-math after fp-model=fast, cancel this one. */
+ unsigned int fno_fast_math_index;
+ fno_fast_math_index
+ = find_opt_idx (decoded_options, decoded_options_count, fp_model_index,
+ decoded_options_count, OPT_ffast_math);
+ if (fno_fast_math_index != decoded_options_count
+ && decoded_options[fno_fast_math_index].value == 0)
+ {
+ decoded_options_count
+ = remove_option (decoded_options, decoded_options_count,
+ fp_model_index);
+ warning (0, "'-fp-model=fast' before '-fno-fast-math' is canceled");
+ }
+ }
+ return decoded_options_count;
+}
+
/* Filter out options canceled by the ones after them. */
static void
prune_options (struct cl_decoded_option **decoded_options,
- unsigned int *decoded_options_count)
+ unsigned int *decoded_options_count,
+ unsigned int lang_mask)
{
unsigned int old_decoded_options_count = *decoded_options_count;
struct cl_decoded_option *old_decoded_options = *decoded_options;
@@ -1005,6 +1103,8 @@ prune_options (struct cl_decoded_option
unsigned int fdiagnostics_color_idx = 0;
/* Remove arguments which are negated by others after them. */
+
+ unsigned int fp_model_index = old_decoded_options_count;
new_decoded_options_count = 0;
for (i = 0; i < old_decoded_options_count; i++)
{
@@ -1028,6 +1128,34 @@ prune_options (struct cl_decoded_option
fdiagnostics_color_idx = i;
continue;
+ case OPT_fp_model_:
+ /* Only the last fp-model option will take effect. */
+ unsigned int next_fp_model_idx;
+ next_fp_model_idx = find_opt_idx (old_decoded_options,
+ old_decoded_options_count,
+ i + 1,
+ old_decoded_options_count,
+ OPT_fp_model_);
+ if (next_fp_model_idx != old_decoded_options_count)
+ {
+ /* Found more than one fp-model, cancel this one. */
+ if (old_decoded_options[i].value
+ != old_decoded_options[next_fp_model_idx].value)
+ {
+ warning (0, "%qs is overrided by %qs",
+ old_decoded_options[i].
+ orig_option_with_args_text,
+ old_decoded_options[next_fp_model_idx].
+ orig_option_with_args_text);
+ }
+ break;
+ }
+ else
+ {
+ /* Found the last fp-model option. */
+ fp_model_index = new_decoded_options_count;
+ }
+ /* FALLTHRU. */
default:
gcc_assert (opt_idx < cl_options_count);
option = &cl_options[opt_idx];
@@ -1067,6 +1195,14 @@ keep:
break;
}
}
+ if (fp_model_index < new_decoded_options_count)
+ {
+ new_decoded_options_count
+ = handle_fp_model_driver (new_decoded_options,
+ new_decoded_options_count,
+ fp_model_index,
+ lang_mask);
+ }
if (fdiagnostics_color_idx >= 1)
{

View File

@ -1,298 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-middle-end-92046-Command-line-options-that-are.patch
e622a32db78300821fc1327637ec6413febc2c66
diff -uprN a/gcc/common.opt b/gcc/common.opt
--- a/gcc/common.opt 2020-05-28 16:12:58.815511599 +0800
+++ b/gcc/common.opt 2020-05-28 15:54:33.797511589 +0800
@@ -993,6 +993,10 @@ Align the start of loops.
falign-loops=
Common RejectNegative Joined Var(str_align_loops) Optimization
+fallow-store-data-races
+Common Report Var(flag_store_data_races) Optimization
+Allow the compiler to introduce new data races on stores.
+
fargument-alias
Common Ignore
Does nothing. Preserved for backward compatibility.
diff -uprN a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
--- a/gcc/doc/invoke.texi 2020-05-28 16:12:56.875511599 +0800
+++ b/gcc/doc/invoke.texi 2020-05-28 15:54:33.757511589 +0800
@@ -400,6 +400,7 @@ Objective-C and Objective-C++ Dialects}.
-falign-jumps[=@var{n}[:@var{m}:[@var{n2}[:@var{m2}]]]] @gol
-falign-labels[=@var{n}[:@var{m}:[@var{n2}[:@var{m2}]]]] @gol
-falign-loops[=@var{n}[:@var{m}:[@var{n2}[:@var{m2}]]]] @gol
+-fallow-store-data-races @gol
-fassociative-math -fauto-profile -fauto-profile[=@var{path}] @gol
-fauto-inc-dec -fbranch-probabilities @gol
-fbranch-target-load-optimize -fbranch-target-load-optimize2 @gol
@@ -8365,9 +8366,9 @@ designed to reduce code size.
Disregard strict standards compliance. @option{-Ofast} enables all
@option{-O3} optimizations. It also enables optimizations that are not
valid for all standard-compliant programs.
-It turns on @option{-ffast-math} and the Fortran-specific
-@option{-fstack-arrays}, unless @option{-fmax-stack-var-size} is
-specified, and @option{-fno-protect-parens}.
+It turns on @option{-ffast-math}, @option{-fallow-store-data-races}
+and the Fortran-specific @option{-fstack-arrays}, unless
+@option{-fmax-stack-var-size} is specified, and @option{-fno-protect-parens}.
@item -Og
@opindex Og
@@ -10120,6 +10121,12 @@ The maximum allowed @var{n} option value
Enabled at levels @option{-O2}, @option{-O3}.
+@item -fallow-store-data-races
+@opindex fallow-store-data-races
+Allow the compiler to introduce new data races on stores.
+
+Enabled at level @option{-Ofast}.
+
@item -funit-at-a-time
@opindex funit-at-a-time
This option is left for compatibility reasons. @option{-funit-at-a-time}
@@ -11902,10 +11909,6 @@ The maximum number of conditional store
if either vectorization (@option{-ftree-vectorize}) or if-conversion
(@option{-ftree-loop-if-convert}) is disabled.
-@item allow-store-data-races
-Allow optimizers to introduce new data races on stores.
-Set to 1 to allow, otherwise to 0.
-
@item case-values-threshold
The smallest number of different values for which it is best to use a
jump-table instead of a tree of conditional branches. If the value is
diff -uprN a/gcc/opts.c b/gcc/opts.c
--- a/gcc/opts.c 2020-05-28 16:12:58.847511599 +0800
+++ b/gcc/opts.c 2020-05-28 15:54:35.713511589 +0800
@@ -560,6 +560,7 @@ static const struct default_options defa
/* -Ofast adds optimizations to -O3. */
{ OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
+ { OPT_LEVELS_FAST, OPT_fallow_store_data_races, NULL, 1 },
{ OPT_LEVELS_NONE, 0, NULL, 0 }
};
@@ -682,13 +683,6 @@ default_options_optimization (struct gcc
: default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES) / 10,
opts->x_param_values, opts_set->x_param_values);
- /* At -Ofast, allow store motion to introduce potential race conditions. */
- maybe_set_param_value
- (PARAM_ALLOW_STORE_DATA_RACES,
- opts->x_optimize_fast ? 1
- : default_param_value (PARAM_ALLOW_STORE_DATA_RACES),
- opts->x_param_values, opts_set->x_param_values);
-
if (opts->x_optimize_size)
/* We want to crossjump as much as possible. */
maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
diff -uprN a/gcc/params.def b/gcc/params.def
--- a/gcc/params.def 2020-05-28 16:12:58.831511599 +0800
+++ b/gcc/params.def 2020-05-28 15:54:35.725511589 +0800
@@ -1199,12 +1199,6 @@ DEFPARAM (PARAM_CASE_VALUES_THRESHOLD,
"if 0, use the default for the machine.",
0, 0, 0)
-/* Data race flags for C++0x memory model compliance. */
-DEFPARAM (PARAM_ALLOW_STORE_DATA_RACES,
- "allow-store-data-races",
- "Allow new data races on stores to be introduced.",
- 0, 0, 1)
-
/* Reassociation width to be used by tree reassoc optimization. */
DEFPARAM (PARAM_TREE_REASSOC_WIDTH,
"tree-reassoc-width",
diff -uprN a/gcc/params.h b/gcc/params.h
--- a/gcc/params.h 2020-05-28 16:12:58.843511599 +0800
+++ b/gcc/params.h 2020-05-28 15:54:35.725511589 +0800
@@ -228,8 +228,6 @@ extern void init_param_values (int *para
PARAM_VALUE (PARAM_MAX_STORES_TO_SINK)
#define ALLOW_LOAD_DATA_RACES \
PARAM_VALUE (PARAM_ALLOW_LOAD_DATA_RACES)
-#define ALLOW_STORE_DATA_RACES \
- PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES)
#define ALLOW_PACKED_LOAD_DATA_RACES \
PARAM_VALUE (PARAM_ALLOW_PACKED_LOAD_DATA_RACES)
#define ALLOW_PACKED_STORE_DATA_RACES \
diff -uprN a/gcc/testsuite/c-c++-common/cxxbitfields-3.c b/gcc/testsuite/c-c++-common/cxxbitfields-3.c
--- a/gcc/testsuite/c-c++-common/cxxbitfields-3.c 2020-05-28 16:12:56.959511599 +0800
+++ b/gcc/testsuite/c-c++-common/cxxbitfields-3.c 2020-05-28 15:54:33.853511589 +0800
@@ -1,5 +1,5 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O2 --param allow-store-data-races=0" } */
+/* { dg-options "-O2 -fno-allow-store-data-races" } */
/* Make sure we don't narrow down to a QI or HI to store into VAR.J,
but instead use an SI. */
diff -uprN a/gcc/testsuite/c-c++-common/cxxbitfields-6.c b/gcc/testsuite/c-c++-common/cxxbitfields-6.c
--- a/gcc/testsuite/c-c++-common/cxxbitfields-6.c 2020-05-28 16:12:56.935511599 +0800
+++ b/gcc/testsuite/c-c++-common/cxxbitfields-6.c 2020-05-28 15:54:33.845511589 +0800
@@ -1,6 +1,6 @@
/* PR middle-end/50141 */
/* { dg-do compile } */
-/* { dg-options "-O2 --param allow-store-data-races=0" } */
+/* { dg-options "-O2 -fno-allow-store-data-races" } */
struct S
{
diff -uprN a/gcc/testsuite/c-c++-common/simulate-thread/bitfields-1.c b/gcc/testsuite/c-c++-common/simulate-thread/bitfields-1.c
--- a/gcc/testsuite/c-c++-common/simulate-thread/bitfields-1.c 2020-05-28 16:12:56.939511599 +0800
+++ b/gcc/testsuite/c-c++-common/simulate-thread/bitfields-1.c 2020-05-28 15:54:33.821511589 +0800
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "--param allow-store-data-races=0" } */
+/* { dg-options "-fno-allow-store-data-races" } */
/* { dg-final { simulate-thread } } */
#include <stdio.h>
diff -uprN a/gcc/testsuite/c-c++-common/simulate-thread/bitfields-2.c b/gcc/testsuite/c-c++-common/simulate-thread/bitfields-2.c
--- a/gcc/testsuite/c-c++-common/simulate-thread/bitfields-2.c 2020-05-28 16:12:56.939511599 +0800
+++ b/gcc/testsuite/c-c++-common/simulate-thread/bitfields-2.c 2020-05-28 15:54:33.821511589 +0800
@@ -1,5 +1,5 @@
/* { dg-do link { target { ! int16 } } } */
-/* { dg-options "--param allow-store-data-races=0" } */
+/* { dg-options "-fno-allow-store-data-races" } */
/* { dg-final { simulate-thread } } */
#include <stdio.h>
diff -uprN a/gcc/testsuite/c-c++-common/simulate-thread/bitfields-3.c b/gcc/testsuite/c-c++-common/simulate-thread/bitfields-3.c
--- a/gcc/testsuite/c-c++-common/simulate-thread/bitfields-3.c 2020-05-28 16:12:56.939511599 +0800
+++ b/gcc/testsuite/c-c++-common/simulate-thread/bitfields-3.c 2020-05-28 15:54:33.821511589 +0800
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "--param allow-store-data-races=0" } */
+/* { dg-options "-fno-allow-store-data-races" } */
/* { dg-final { simulate-thread } } */
#include <stdio.h>
diff -uprN a/gcc/testsuite/c-c++-common/simulate-thread/bitfields-4.c b/gcc/testsuite/c-c++-common/simulate-thread/bitfields-4.c
--- a/gcc/testsuite/c-c++-common/simulate-thread/bitfields-4.c 2020-05-28 16:12:56.939511599 +0800
+++ b/gcc/testsuite/c-c++-common/simulate-thread/bitfields-4.c 2020-05-28 15:54:33.821511589 +0800
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "--param allow-store-data-races=0" } */
+/* { dg-options "-fno-allow-store-data-races" } */
/* { dg-final { simulate-thread } } */
#include <stdio.h>
diff -uprN a/gcc/testsuite/gcc.dg/lto/pr52097_0.c b/gcc/testsuite/gcc.dg/lto/pr52097_0.c
--- a/gcc/testsuite/gcc.dg/lto/pr52097_0.c 2020-05-28 16:12:57.803511599 +0800
+++ b/gcc/testsuite/gcc.dg/lto/pr52097_0.c 2020-05-28 15:54:34.777511589 +0800
@@ -1,5 +1,5 @@
/* { dg-lto-do link } */
-/* { dg-lto-options { { -O -flto -fexceptions -fnon-call-exceptions --param allow-store-data-races=0 } } } */
+/* { dg-lto-options { { -O -flto -fexceptions -fnon-call-exceptions -fno-allow-store-data-races } } } */
/* { dg-require-effective-target exceptions } */
typedef struct { unsigned int e0 : 16; } s1;
diff -uprN a/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-2.c b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-2.c
--- a/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-2.c 2020-05-28 16:12:57.815511599 +0800
+++ b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-2.c 2020-05-28 15:54:34.781511589 +0800
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "--param allow-store-data-races=0 -O2" } */
+/* { dg-options "-fno-allow-store-data-races -O2" } */
/* { dg-final { simulate-thread } } */
#include <stdio.h>
diff -uprN a/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-3.c b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-3.c
--- a/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-3.c 2020-05-28 16:12:57.815511599 +0800
+++ b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-3.c 2020-05-28 15:54:34.781511589 +0800
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "--param allow-store-data-races=0 -O2" } */
+/* { dg-options "-fno-allow-store-data-races -O2" } */
/* { dg-final { simulate-thread } } */
#include <stdio.h>
diff -uprN a/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-4.c b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-4.c
--- a/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-4.c 2020-05-28 16:12:57.815511599 +0800
+++ b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-4.c 2020-05-28 15:54:34.781511589 +0800
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "--param allow-store-data-races=0" } */
+/* { dg-options "-fno-allow-store-data-races" } */
/* { dg-final { simulate-thread } } */
#include <stdio.h>
diff -uprN a/gcc/testsuite/gcc.dg/simulate-thread/speculative-store.c b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store.c
--- a/gcc/testsuite/gcc.dg/simulate-thread/speculative-store.c 2020-05-28 16:12:57.815511599 +0800
+++ b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store.c 2020-05-28 15:54:34.781511589 +0800
@@ -1,12 +1,12 @@
/* { dg-do link } */
-/* { dg-options "--param allow-store-data-races=0" } */
+/* { dg-options "-fno-allow-store-data-races" } */
/* { dg-final { simulate-thread } } */
#include <stdio.h>
#include "simulate-thread.h"
/* This file tests that speculative store movement out of a loop doesn't
- happen. This is disallowed when --param allow-store-data-races is 0. */
+ happen. This is disallowed when -fno-allow-store-data-races. */
int global = 100;
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c 2020-05-28 16:12:58.027511599 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c 2020-05-28 15:54:34.997511589 +0800
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-lim2-details --param allow-store-data-races=1" } */
+/* { dg-options "-O1 -fdump-tree-lim2-details -fallow-store-data-races" } */
float a[100];
diff -uprN a/gcc/testsuite/g++.dg/simulate-thread/bitfields-2.C b/gcc/testsuite/g++.dg/simulate-thread/bitfields-2.C
--- a/gcc/testsuite/g++.dg/simulate-thread/bitfields-2.C 2020-05-28 16:12:57.015511599 +0800
+++ b/gcc/testsuite/g++.dg/simulate-thread/bitfields-2.C 2020-05-28 15:54:33.885511589 +0800
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "--param allow-store-data-races=0" } */
+/* { dg-options "-fno-allow-store-data-races" } */
/* { dg-final { simulate-thread } } */
/* Test that setting <var.a> does not touch either <var.b> or <var.c>.
diff -uprN a/gcc/testsuite/g++.dg/simulate-thread/bitfields.C b/gcc/testsuite/g++.dg/simulate-thread/bitfields.C
--- a/gcc/testsuite/g++.dg/simulate-thread/bitfields.C 2020-05-28 16:12:57.015511599 +0800
+++ b/gcc/testsuite/g++.dg/simulate-thread/bitfields.C 2020-05-28 15:54:33.885511589 +0800
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "--param allow-store-data-races=0" } */
+/* { dg-options "-fno-allow-store-data-races" } */
/* { dg-final { simulate-thread } } */
/* Test that setting <var.a> does not touch either <var.b> or <var.c>.
diff -uprN a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
--- a/gcc/tree-if-conv.c 2020-05-28 16:12:58.831511599 +0800
+++ b/gcc/tree-if-conv.c 2020-05-28 15:54:35.641511589 +0800
@@ -913,10 +913,10 @@ ifcvt_memrefs_wont_trap (gimple *stmt, v
to unconditionally. */
if (base_master_dr
&& DR_BASE_W_UNCONDITIONALLY (*base_master_dr))
- return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES);
+ return flag_store_data_races;
/* or the base is known to be not readonly. */
else if (base_object_writable (DR_REF (a)))
- return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES);
+ return flag_store_data_races;
}
return false;
diff -uprN a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
--- a/gcc/tree-ssa-loop-im.c 2020-05-28 16:12:58.779511599 +0800
+++ b/gcc/tree-ssa-loop-im.c 2020-05-28 15:54:35.729511589 +0800
@@ -2088,7 +2088,7 @@ execute_sm (struct loop *loop, vec<edge>
for_each_index (&ref->mem.ref, force_move_till, &fmt_data);
if (bb_in_transaction (loop_preheader_edge (loop)->src)
- || (! PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES)
+ || (! flag_store_data_races
&& ! ref_always_accessed_p (loop, ref, true)))
multi_threaded_model_p = true;

View File

@ -1,74 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-widening_mul-restrict-ops-to-be-defined-in-the-same-.patch:
d21dff5b4fee51ae432143065bededfc763dc344
diff -Nurp a/gcc/testsuite/gcc.dg/pr94269.c b/gcc/testsuite/gcc.dg/pr94269.c
--- a/gcc/testsuite/gcc.dg/pr94269.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/pr94269.c 2020-04-17 17:04:50.608000000 +0800
@@ -0,0 +1,26 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-O2 -ftree-loop-vectorize -funsafe-math-optimizations -march=armv8.2-a+sve -msve-vector-bits=256" } */
+
+float
+foo(long n, float *x, int inc_x,
+ float *y, int inc_y)
+{
+ float dot = 0.0;
+ int ix = 0, iy = 0;
+
+ if (n < 0) {
+ return dot;
+ }
+
+ int i = 0;
+ while (i < n) {
+ dot += y[iy] * x[ix];
+ ix += inc_x;
+ iy += inc_y;
+ i++;
+ }
+
+ return dot;
+}
+
+/* { dg-final { scan-assembler-not "smaddl" { target aarch64*-*-* } } } */
diff -Nurp a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
--- a/gcc/tree-ssa-math-opts.c 2020-04-17 16:43:59.540000000 +0800
+++ b/gcc/tree-ssa-math-opts.c 2020-04-17 16:48:34.072036000 +0800
@@ -2721,11 +2721,14 @@ convert_plusminus_to_widen (gimple_stmt_
multiply-and-accumulate instructions.
If the widened-multiplication result has more than one uses, it is
- probably wiser not to do the conversion. */
+ probably wiser not to do the conversion. Also restrict this operation
+ to single basic block to avoid moving the multiply to a different block
+ with a higher execution frequency. */
if (code == PLUS_EXPR
&& (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR))
{
if (!has_single_use (rhs1)
+ || gimple_bb (rhs1_stmt) != gimple_bb (stmt)
|| !is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1,
&type2, &mult_rhs2))
return false;
@@ -2735,6 +2738,7 @@ convert_plusminus_to_widen (gimple_stmt_
else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR)
{
if (!has_single_use (rhs2)
+ || gimple_bb (rhs2_stmt) != gimple_bb (stmt)
|| !is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1,
&type2, &mult_rhs2))
return false;
diff -Nurp a/gcc/testsuite/gcc.target/aarch64/sve/var_stride_1.c b/gcc/testsuite/gcc.target/aarch64/sve/var_stride_1.c
--- a/gcc/testsuite/gcc.target/aarch64/sve/var_stride_1.c 2020-03-31 09:51:36.000000000 +0800
+++ b/gcc/testsuite/gcc.target/aarch64/sve/var_stride_1.c 2020-04-29 10:55:44.937471475 +0800
@@ -17,7 +17,6 @@ f (TYPE *x, TYPE *y, unsigned short n, l
/* { dg-final { scan-assembler {\tstr\tw[0-9]+} } } */
/* Should multiply by (VF-1)*4 rather than (257-1)*4. */
/* { dg-final { scan-assembler-not {, 1024} } } */
-/* { dg-final { scan-assembler-not {\t.bfiz\t} } } */
/* { dg-final { scan-assembler-not {lsl[^\n]*[, ]10} } } */
/* { dg-final { scan-assembler-not {\tcmp\tx[0-9]+, 0} } } */
/* { dg-final { scan-assembler-not {\tcmp\tw[0-9]+, 0} } } */

View File

@ -1,88 +0,0 @@
This backport contains 2 patchs from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
4bf29d15f2e01348a45a1f4e1a135962f123fdd6
0001-AArch64-PR79262-Adjust-vector-cost.patch
27071013521b015d17a2666448f27a6ff0c55aca
0001-Move-EXTRACT_LAST_REDUCTION-costing-to-vectorizable_.patch
diff -Nurp a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
--- a/gcc/config/aarch64/aarch64.c 2020-11-20 04:36:33.988000000 +0800
+++ b/gcc/config/aarch64/aarch64.c 2020-11-20 04:32:20.984000000 +0800
@@ -448,7 +448,7 @@ static const struct cpu_vector_cost gene
1, /* vec_int_stmt_cost */
1, /* vec_fp_stmt_cost */
2, /* vec_permute_cost */
- 1, /* vec_to_scalar_cost */
+ 2, /* vec_to_scalar_cost */
1, /* scalar_to_vec_cost */
1, /* vec_align_load_cost */
1, /* vec_unalign_load_cost */
diff -Nurp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c 2020-11-20 04:36:34.016000000 +0800
+++ b/gcc/tree-vect-loop.c 2020-11-20 04:32:20.984000000 +0800
@@ -3926,8 +3926,11 @@ vect_model_reduction_cost (stmt_vec_info
code = gimple_assign_rhs_code (orig_stmt_info->stmt);
- if (reduction_type == EXTRACT_LAST_REDUCTION
- || reduction_type == FOLD_LEFT_REDUCTION)
+ if (reduction_type == EXTRACT_LAST_REDUCTION)
+ /* No extra instructions are needed in the prologue. The loop body
+ operations are costed in vectorizable_condition. */
+ inside_cost = 0;
+ else if (reduction_type == FOLD_LEFT_REDUCTION)
{
/* No extra instructions needed in the prologue. */
prologue_cost = 0;
diff -Nurp a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
--- a/gcc/tree-vect-stmts.c 2020-11-20 04:36:33.996000000 +0800
+++ b/gcc/tree-vect-stmts.c 2020-11-20 04:32:20.984000000 +0800
@@ -859,7 +859,8 @@ vect_model_simple_cost (stmt_vec_info st
enum vect_def_type *dt,
int ndts,
slp_tree node,
- stmt_vector_for_cost *cost_vec)
+ stmt_vector_for_cost *cost_vec,
+ vect_cost_for_stmt kind = vector_stmt)
{
int inside_cost = 0, prologue_cost = 0;
@@ -906,7 +907,7 @@ vect_model_simple_cost (stmt_vec_info st
}
/* Pass the inside-of-loop statements to the target-specific cost model. */
- inside_cost += record_stmt_cost (cost_vec, ncopies, vector_stmt,
+ inside_cost += record_stmt_cost (cost_vec, ncopies, kind,
stmt_info, 0, vect_body);
if (dump_enabled_p ())
@@ -9194,15 +9195,18 @@ vectorizable_condition (stmt_vec_info st
" EXTRACT_LAST_REDUCTION.\n");
LOOP_VINFO_CAN_FULLY_MASK_P (loop_vinfo) = false;
}
- if (expand_vec_cond_expr_p (vectype, comp_vectype,
- cond_code))
- {
- STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
- vect_model_simple_cost (stmt_info, ncopies, dts, ndts, slp_node,
- cost_vec);
- return true;
- }
- return false;
+
+ vect_cost_for_stmt kind = vector_stmt;
+ if (reduction_type == EXTRACT_LAST_REDUCTION)
+ /* Count one reduction-like operation per vector. */
+ kind = vec_to_scalar;
+ else if (!expand_vec_cond_expr_p (vectype, comp_vectype, cond_code))
+ return false;
+
+ STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
+ vect_model_simple_cost (stmt_info, ncopies, dts, ndts, slp_node,
+ cost_vec, kind);
+ return true;
}
/* Transform. */

View File

@ -1,154 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-lra-Avoid-cycling-on-certain-subreg-reloads-PR96796.patch
6001db79c477b03eacc7e7049560921fb54b7845
diff -uprN a/gcc/lra-constraints.c b/gcc/lra-constraints.c
--- a/gcc/lra-constraints.c 2020-03-12 19:07:21.000000000 +0800
+++ b/gcc/lra-constraints.c 2020-09-08 10:02:52.308147305 +0800
@@ -235,12 +235,17 @@ get_reg_class (int regno)
CL. Use elimination first if REG is a hard register. If REG is a
reload pseudo created by this constraints pass, assume that it will
be allocated a hard register from its allocno class, but allow that
- class to be narrowed to CL if it is currently a superset of CL.
+ class to be narrowed to CL if it is currently a superset of CL and
+ if either:
+
+ - ALLOW_ALL_RELOAD_CLASS_CHANGES_P is true or
+ - the instruction we're processing is not a reload move.
If NEW_CLASS is nonnull, set *NEW_CLASS to the new allocno class of
REGNO (reg), or NO_REGS if no change in its class was needed. */
static bool
-in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class)
+in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class,
+ bool allow_all_reload_class_changes_p = false)
{
enum reg_class rclass, common_class;
machine_mode reg_mode;
@@ -265,7 +270,8 @@ in_class_p (rtx reg, enum reg_class cl,
typically moves that have many alternatives, and restricting
reload pseudos for one alternative may lead to situations
where other reload pseudos are no longer allocatable. */
- || (INSN_UID (curr_insn) >= new_insn_uid_start
+ || (!allow_all_reload_class_changes_p
+ && INSN_UID (curr_insn) >= new_insn_uid_start
&& curr_insn_set != NULL
&& ((OBJECT_P (SET_SRC (curr_insn_set))
&& ! CONSTANT_P (SET_SRC (curr_insn_set)))
@@ -557,13 +563,12 @@ init_curr_insn_input_reloads (void)
curr_insn_input_reloads_num = 0;
}
-/* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse already
- created input reload pseudo (only if TYPE is not OP_OUT). Don't
- reuse pseudo if IN_SUBREG_P is true and the reused pseudo should be
- wrapped up in SUBREG. The result pseudo is returned through
- RESULT_REG. Return TRUE if we created a new pseudo, FALSE if we
- reused the already created input reload pseudo. Use TITLE to
- describe new registers for debug purposes. */
+/* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse an existing
+ reload pseudo. Don't reuse an existing reload pseudo if IN_SUBREG_P
+ is true and the reused pseudo should be wrapped up in a SUBREG.
+ The result pseudo is returned through RESULT_REG. Return TRUE if we
+ created a new pseudo, FALSE if we reused an existing reload pseudo.
+ Use TITLE to describe new registers for debug purposes. */
static bool
get_reload_reg (enum op_type type, machine_mode mode, rtx original,
enum reg_class rclass, bool in_subreg_p,
@@ -575,6 +580,35 @@ get_reload_reg (enum op_type type, machi
if (type == OP_OUT)
{
+ /* Output reload registers tend to start out with a conservative
+ choice of register class. Usually this is ALL_REGS, although
+ a target might narrow it (for performance reasons) through
+ targetm.preferred_reload_class. It's therefore quite common
+ for a reload instruction to require a more restrictive class
+ than the class that was originally assigned to the reload register.
+
+ In these situations, it's more efficient to refine the choice
+ of register class rather than create a second reload register.
+ This also helps to avoid cycling for registers that are only
+ used by reload instructions. */
+ if (REG_P (original)
+ && (int) REGNO (original) >= new_regno_start
+ && INSN_UID (curr_insn) >= new_insn_uid_start
+ && in_class_p (original, rclass, &new_class, true))
+ {
+ unsigned int regno = REGNO (original);
+ if (lra_dump_file != NULL)
+ {
+ fprintf (lra_dump_file, " Reuse r%d for output ", regno);
+ dump_value_slim (lra_dump_file, original, 1);
+ }
+ if (new_class != lra_get_allocno_class (regno))
+ lra_change_class (regno, new_class, ", change to", false);
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file, "\n");
+ *result_reg = original;
+ return false;
+ }
*result_reg
= lra_create_new_reg_with_unique_value (mode, original, rclass, title);
return true;
diff -uprN a/gcc/testsuite/gcc.c-torture/compile/pr96796.c b/gcc/testsuite/gcc.c-torture/compile/pr96796.c
--- a/gcc/testsuite/gcc.c-torture/compile/pr96796.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.c-torture/compile/pr96796.c 2020-09-08 09:59:40.077774393 +0800
@@ -0,0 +1,55 @@
+/* { dg-additional-options "-fcommon" } */
+
+struct S0 {
+ signed f0 : 8;
+ unsigned f1;
+ unsigned f4;
+};
+struct S1 {
+ long f3;
+ char f4;
+} g_3_4;
+
+int g_5, func_1_l_32, func_50___trans_tmp_31;
+static struct S0 g_144, g_834, g_1255, g_1261;
+
+int g_273[120] = {};
+int *g_555;
+char **g_979;
+static int g_1092_0;
+static int g_1193;
+int safe_mul_func_int16_t_s_s(int si1, int si2) { return si1 * si2; }
+static struct S0 *func_50();
+int func_1() { func_50(g_3_4, g_5, func_1_l_32, 8, 3); }
+void safe_div_func_int64_t_s_s(int *);
+void safe_mod_func_uint32_t_u_u(struct S0);
+struct S0 *func_50(int p_51, struct S0 p_52, struct S1 p_53, int p_54,
+ int p_55) {
+ int __trans_tmp_30;
+ char __trans_tmp_22;
+ short __trans_tmp_19;
+ long l_985_1;
+ long l_1191[8];
+ safe_div_func_int64_t_s_s(g_273);
+ __builtin_printf((char*)g_1261.f4);
+ safe_mod_func_uint32_t_u_u(g_834);
+ g_144.f0 += 1;
+ for (;;) {
+ struct S1 l_1350 = {&l_1350};
+ for (; p_53.f3; p_53.f3 -= 1)
+ for (; g_1193 <= 2; g_1193 += 1) {
+ __trans_tmp_19 = safe_mul_func_int16_t_s_s(l_1191[l_985_1 + p_53.f3],
+ p_55 % (**g_979 = 10));
+ __trans_tmp_22 = g_1255.f1 * p_53.f4;
+ __trans_tmp_30 = __trans_tmp_19 + __trans_tmp_22;
+ if (__trans_tmp_30)
+ g_1261.f0 = p_51;
+ else {
+ g_1255.f0 = p_53.f3;
+ int *l_1422 = g_834.f0 = g_144.f4 != (*l_1422)++ > 0 < 0 ^ 51;
+ g_555 = ~0;
+ g_1092_0 |= func_50___trans_tmp_31;
+ }
+ }
+ }
+}

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Bump-BASE-VER-to-9.3.1.patch
9f26e5863a75744bbee1479792ecae084a3ceb20
diff -Nurp a/gcc/BASE-VER b/gcc/BASE-VER
--- a/gcc/BASE-VER 2020-08-19 10:47:14.100000000 +0800
+++ b/gcc/BASE-VER 2020-08-19 10:32:30.380000000 +0800
@@ -1 +1 @@
-9.3.0
+9.3.1
diff -Nurp a/gcc/Makefile.in b/gcc/Makefile.in
--- a/gcc/Makefile.in 2020-08-19 10:32:45.528000000 +0800
+++ b/gcc/Makefile.in 2020-08-19 10:34:24.968000000 +0800
@@ -885,8 +885,7 @@ PATCHLEVEL_c := \
# significant - do not remove it.
BASEVER_s := "\"$(BASEVER_c)\""
DEVPHASE_s := "\"$(if $(DEVPHASE_c), ($(DEVPHASE_c)))\""
-DATESTAMP_s := \
- "\"$(if $(DEVPHASE_c)$(filter-out 0,$(PATCHLEVEL_c)), $(DATESTAMP_c))\""
+DATESTAMP_s := "\"\""
PKGVERSION_s:= "\"@PKGVERSION@\""
BUGURL_s := "\"@REPORT_BUGS_TO@\""

File diff suppressed because it is too large Load Diff

View File

@ -1,68 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-vect-CSE-for-bump-and-offset-in-strided-load-store-o.patch
4a31a8add56d49867c187d90b3a89e97634543c2
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr95199.c b/gcc/testsuite/gcc.target/aarch64/sve/pr95199.c
new file mode 100644
index 00000000000..adcd5124a7c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr95199.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=armv8.2-a+sve -fdump-tree-vect" } */
+
+void
+foo (double *a, double *b, double m, int inc_x, int inc_y)
+{
+ int ix = 0, iy = 0;
+ for (int i = 0; i < 1000; ++i)
+ {
+ a[ix] += m * b[iy];
+ ix += inc_x;
+ iy += inc_y;
+ }
+ return ;
+}
+
+/* { dg-final { scan-tree-dump-times "VEC_SERIES_EXPR" 2 "vect" } } */
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 4a0a907fcb4..c9174395fca 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -2846,16 +2846,12 @@ vect_get_strided_load_store_ops (stmt_vec_info stmt_info,
tree *dataref_bump, tree *vec_offset)
{
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
- gimple_seq stmts;
tree bump = size_binop (MULT_EXPR,
fold_convert (sizetype, DR_STEP (dr)),
size_int (TYPE_VECTOR_SUBPARTS (vectype)));
- *dataref_bump = force_gimple_operand (bump, &stmts, true, NULL_TREE);
- if (stmts)
- gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
+ *dataref_bump = cse_and_gimplify_to_preheader (loop_vinfo, bump);
/* The offset given in GS_INFO can have pointer type, so use the element
type of the vector instead. */
@@ -2866,13 +2862,11 @@ vect_get_strided_load_store_ops (stmt_vec_info stmt_info,
tree step = size_binop (EXACT_DIV_EXPR, DR_STEP (dr),
ssize_int (gs_info->scale));
step = fold_convert (offset_type, step);
- step = force_gimple_operand (step, &stmts, true, NULL_TREE);
/* Create {0, X, X*2, X*3, ...}. */
- *vec_offset = gimple_build (&stmts, VEC_SERIES_EXPR, offset_vectype,
- build_zero_cst (offset_type), step);
- if (stmts)
- gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
+ tree offset = fold_build2 (VEC_SERIES_EXPR, offset_vectype,
+ build_zero_cst (offset_type), step);
+ *vec_offset = cse_and_gimplify_to_preheader (loop_vinfo, offset);
}
/* Return the amount that should be added to a vector pointer to move

View File

@ -1,58 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-middle-end-91195-incorrect-may-be-used-uniniti.patch
06e8db10cd80d88fb3a6afedf2c35da6c1fa6d85
diff -uprN a/gcc/testsuite/gcc.dg/pr91195.c b/gcc/testsuite/gcc.dg/pr91195.c
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr91195.c
@@ -0,0 +1,25 @@
+/* PR middle-end/91195 */
+/* { dg-do compile } */
+/* { dg-options "-Wmaybe-uninitialized -O2" } */
+
+int bar (char*);
+
+void
+foo (char *x, char *y)
+{
+ char *a[2];
+ int b = 0;
+
+ if (x)
+ a[b++] = x; /* { dg-bogus "may be used uninitialized in this function" } */
+ if (y)
+ a[b++] = y;
+
+ for (int j = 0; j < 4; j++)
+ switch (j)
+ {
+ case 0:
+ if (b == 0 || bar (a[0]))
+ break;
+ }
+}
diff -uprN a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -2269,6 +2269,10 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
new_stmt = gimple_build_assign (name, lhs);
gimple_set_location (new_stmt, locus);
+ lhs = unshare_expr (lhs);
+ /* Set TREE_NO_WARNING on the rhs of the load to avoid uninit
+ warnings. */
+ TREE_NO_WARNING (gimple_assign_rhs1 (new_stmt)) = 1;
gsi_insert_on_edge (e1, new_stmt);
/* 3) Create a PHI node at the join block, with one argument
@@ -2279,7 +2283,6 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
add_phi_arg (newphi, rhs, e0, locus);
add_phi_arg (newphi, name, e1, locus);
- lhs = unshare_expr (lhs);
new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));
/* 4) Insert that PHI node. */

View File

@ -1,69 +0,0 @@
From dbf3dc75888623e9d4bb7cc5e9c30caa9b24ffe7 Mon Sep 17 00:00:00 2001
From: Bu Le <bule1@huawei.com>
Date: Thu, 12 Mar 2020 22:39:12 +0000
Subject: [PATCH] aarch64: Add --params to control the number of recip steps
[PR94154]
-mlow-precision-div hard-coded the number of iterations to 2 for double
and 1 for float. This patch adds a --param to control the number.
2020-03-13 Bu Le <bule1@huawei.com>
gcc/
PR target/94154
* config/aarch64/aarch64.opt (-param=aarch64-float-recp-precision=)
(-param=aarch64-double-recp-precision=): New options.
* doc/invoke.texi: Document them.
* config/aarch64/aarch64.c (aarch64_emit_approx_div): Use them
instead of hard-coding the choice of 1 for float and 2 for double.
---
gcc/ChangeLog | 9 +++++++++
gcc/config/aarch64/aarch64.c | 8 +++++---
gcc/config/aarch64/aarch64.opt | 9 +++++++++
gcc/doc/invoke.texi | 11 +++++++++++
4 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index c320d5ba51d..2c81f86dd2a 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -12911,10 +12911,12 @@ aarch64_emit_approx_div (rtx quo, rtx num, rtx den)
/* Iterate over the series twice for SF and thrice for DF. */
int iterations = (GET_MODE_INNER (mode) == DFmode) ? 3 : 2;
- /* Optionally iterate over the series once less for faster performance,
- while sacrificing the accuracy. */
+ /* Optionally iterate over the series less for faster performance,
+ while sacrificing the accuracy. The default is 2 for DF and 1 for SF. */
if (flag_mlow_precision_div)
- iterations--;
+ iterations = (GET_MODE_INNER (mode) == DFmode
+ ? PARAM_VALUE (PARAM_AARCH64_DOUBLE_RECP_PRECISION)
+ : PARAM_VALUE (PARAM_AARCH64_FLOAT_RECP_PRECISION));
/* Iterate over the series to calculate the approximate reciprocal. */
rtx xtmp = gen_reg_rtx (mode);
--- a/gcc/params.def 2020-04-15 17:24:31.984000000 +0800
+++ b/gcc/params.def 2020-04-15 16:59:21.752000000 +0800
@@ -1420,6 +1414,17 @@ DEFPARAM(PARAM_SSA_NAME_DEF_CHAIN_LIMIT,
"a value.",
512, 0, 0)
+DEFPARAM(PARAM_AARCH64_FLOAT_RECP_PRECISION,
+ "aarch64-float-recp-precision",
+ "The number of Newton iterations for calculating the reciprocal "
+ "for float type. ",
+ 1, 1, 5)
+
+DEFPARAM(PARAM_AARCH64_DOUBLE_RECP_PRECISION,
+ "aarch64-double-recp-precision",
+ "The number of Newton iterations for calculating the reciprocal "
+ "for double type.",
+ 2, 1, 5)
/*
Local variables:
--
2.18.2

View File

@ -1,25 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-combine-Don-t-generate-IF_THEN_ELSE.patch
ddbb5da5199fb421dc398911c37fa7f896efc13f
diff --git a/gcc/combine.c b/gcc/combine.c
index 4de759a8e6b..ce7aeecb5c2 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -5909,14 +5909,6 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int in_dest,
mode, VOIDmode,
cond, cop1),
mode);
- else
- return gen_rtx_IF_THEN_ELSE (mode,
- simplify_gen_relational (cond_code,
- mode,
- VOIDmode,
- cond,
- cop1),
- true_rtx, false_rtx);
code = GET_CODE (x);
op0_mode = VOIDmode;

View File

@ -1,460 +0,0 @@
diff -urpN a/libquadmath/Makefile.in b/libquadmath/Makefile.in
--- a/libquadmath/Makefile.in 2020-03-31 09:51:59.000000000 +0800
+++ b/libquadmath/Makefile.in 2020-04-06 11:52:45.650793256 +0800
@@ -90,7 +90,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-@BUILD_LIBQUADMATH_FALSE@libquadmath_la_DEPENDENCIES =
+#libquadmath_la_DEPENDENCIES =
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
@@ -146,68 +146,68 @@ am__installdirs = "$(DESTDIR)$(toolexecl
"$(DESTDIR)$(libsubincludedir)"
LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
am__dirstamp = $(am__leading_dot)dirstamp
-@BUILD_LIBQUADMATH_TRUE@am_libquadmath_la_OBJECTS = math/x2y2m1q.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/acoshq.lo math/fmodq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/acosq.lo math/frexpq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/rem_pio2q.lo math/asinhq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/hypotq.lo math/remainderq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/asinq.lo math/rintq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/atan2q.lo math/isinfq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/roundq.lo math/atanhq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/isnanq.lo math/scalblnq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/atanq.lo math/j0q.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/scalbnq.lo math/cbrtq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/j1q.lo math/signbitq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/ceilq.lo math/jnq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/sincos_table.lo math/complex.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/ldexpq.lo math/sincosq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/copysignq.lo math/lgammaq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/sincosq_kernel.lo math/coshq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/llroundq.lo math/sinhq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/cosq.lo math/log10q.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/sinq.lo math/cosq_kernel.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/log1pq.lo math/sinq_kernel.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/erfq.lo math/logq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/sqrtq.lo math/expm1q.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/lroundq.lo math/tanhq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/expq.lo math/modfq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/tanq.lo math/fabsq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/nanq.lo math/tgammaq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/finiteq.lo math/nextafterq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/truncq.lo math/floorq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/powq.lo math/fmaq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/logbq.lo math/exp2q.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/issignalingq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/lgammaq_neg.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/lgammaq_product.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/tanq_kernel.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/tgammaq_product.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/casinhq_kernel.lo math/cacoshq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/cacosq.lo math/casinhq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/casinq.lo math/catanhq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/catanq.lo math/cimagq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/conjq.lo math/cprojq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/crealq.lo math/fdimq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/fmaxq.lo math/fminq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/ilogbq.lo math/llrintq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/log2q.lo math/lrintq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/nearbyintq.lo math/remquoq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/ccoshq.lo math/cexpq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/clog10q.lo math/clogq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/csinq.lo math/csinhq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/csqrtq.lo math/ctanq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/ctanhq.lo printf/addmul_1.lo \
-@BUILD_LIBQUADMATH_TRUE@ printf/add_n.lo printf/cmp.lo \
-@BUILD_LIBQUADMATH_TRUE@ printf/divrem.lo printf/flt1282mpn.lo \
-@BUILD_LIBQUADMATH_TRUE@ printf/fpioconst.lo printf/lshift.lo \
-@BUILD_LIBQUADMATH_TRUE@ printf/mul_1.lo printf/mul_n.lo \
-@BUILD_LIBQUADMATH_TRUE@ printf/mul.lo printf/printf_fphex.lo \
-@BUILD_LIBQUADMATH_TRUE@ printf/printf_fp.lo \
-@BUILD_LIBQUADMATH_TRUE@ printf/quadmath-printf.lo \
-@BUILD_LIBQUADMATH_TRUE@ printf/rshift.lo printf/submul_1.lo \
-@BUILD_LIBQUADMATH_TRUE@ printf/sub_n.lo strtod/strtoflt128.lo \
-@BUILD_LIBQUADMATH_TRUE@ strtod/mpn2flt128.lo \
-@BUILD_LIBQUADMATH_TRUE@ strtod/tens_in_limb.lo
+am_libquadmath_la_OBJECTS = math/x2y2m1q.lo \
+ math/acoshq.lo math/fmodq.lo \
+ math/acosq.lo math/frexpq.lo \
+ math/rem_pio2q.lo math/asinhq.lo \
+ math/hypotq.lo math/remainderq.lo \
+ math/asinq.lo math/rintq.lo \
+ math/atan2q.lo math/isinfq.lo \
+ math/roundq.lo math/atanhq.lo \
+ math/isnanq.lo math/scalblnq.lo \
+ math/atanq.lo math/j0q.lo \
+ math/scalbnq.lo math/cbrtq.lo \
+ math/j1q.lo math/signbitq.lo \
+ math/ceilq.lo math/jnq.lo \
+ math/sincos_table.lo math/complex.lo \
+ math/ldexpq.lo math/sincosq.lo \
+ math/copysignq.lo math/lgammaq.lo \
+ math/sincosq_kernel.lo math/coshq.lo \
+ math/llroundq.lo math/sinhq.lo \
+ math/cosq.lo math/log10q.lo \
+ math/sinq.lo math/cosq_kernel.lo \
+ math/log1pq.lo math/sinq_kernel.lo \
+ math/erfq.lo math/logq.lo \
+ math/sqrtq.lo math/expm1q.lo \
+ math/lroundq.lo math/tanhq.lo \
+ math/expq.lo math/modfq.lo \
+ math/tanq.lo math/fabsq.lo \
+ math/nanq.lo math/tgammaq.lo \
+ math/finiteq.lo math/nextafterq.lo \
+ math/truncq.lo math/floorq.lo \
+ math/powq.lo math/fmaq.lo \
+ math/logbq.lo math/exp2q.lo \
+ math/issignalingq.lo \
+ math/lgammaq_neg.lo \
+ math/lgammaq_product.lo \
+ math/tanq_kernel.lo \
+ math/tgammaq_product.lo \
+ math/casinhq_kernel.lo math/cacoshq.lo \
+ math/cacosq.lo math/casinhq.lo \
+ math/casinq.lo math/catanhq.lo \
+ math/catanq.lo math/cimagq.lo \
+ math/conjq.lo math/cprojq.lo \
+ math/crealq.lo math/fdimq.lo \
+ math/fmaxq.lo math/fminq.lo \
+ math/ilogbq.lo math/llrintq.lo \
+ math/log2q.lo math/lrintq.lo \
+ math/nearbyintq.lo math/remquoq.lo \
+ math/ccoshq.lo math/cexpq.lo \
+ math/clog10q.lo math/clogq.lo \
+ math/csinq.lo math/csinhq.lo \
+ math/csqrtq.lo math/ctanq.lo \
+ math/ctanhq.lo printf/addmul_1.lo \
+ printf/add_n.lo printf/cmp.lo \
+ printf/divrem.lo printf/flt1282mpn.lo \
+ printf/fpioconst.lo printf/lshift.lo \
+ printf/mul_1.lo printf/mul_n.lo \
+ printf/mul.lo printf/printf_fphex.lo \
+ printf/printf_fp.lo \
+ printf/quadmath-printf.lo \
+ printf/rshift.lo printf/submul_1.lo \
+ printf/sub_n.lo strtod/strtoflt128.lo \
+ strtod/mpn2flt128.lo \
+ strtod/tens_in_limb.lo
libquadmath_la_OBJECTS = $(am_libquadmath_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -217,8 +217,8 @@ libquadmath_la_LINK = $(LIBTOOL) $(AM_V_
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(libquadmath_la_LDFLAGS) $(LDFLAGS) -o \
$@
-@BUILD_LIBQUADMATH_TRUE@am_libquadmath_la_rpath = -rpath \
-@BUILD_LIBQUADMATH_TRUE@ $(toolexeclibdir)
+am_libquadmath_la_rpath = -rpath \
+ $(toolexeclibdir)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@@ -336,7 +336,7 @@ CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
+DEFS = @DEFS@ -D__float128="long double"
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
@@ -408,7 +408,7 @@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
-enable_shared = @enable_shared@
+enable_shared = yes
enable_static = @enable_static@
exec_prefix = @exec_prefix@
get_gcc_base_ver = @get_gcc_base_ver@
@@ -450,109 +450,109 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign info-in-builddir
-@BUILD_LIBQUADMATH_TRUE@ACLOCAL_AMFLAGS = -I .. -I ../config
-@BUILD_LIBQUADMATH_TRUE@AM_CPPFLAGS = -I $(top_srcdir)/../include
-@BUILD_LIBQUADMATH_TRUE@AM_CFLAGS = $(XCFLAGS)
-@BUILD_LIBQUADMATH_TRUE@gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_FALSE@version_arg =
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_GNU_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_arg = -Wl,--version-script=$(srcdir)/quadmath.map
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_arg = -Wl,-M,quadmath.map-sun
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_FALSE@version_dep =
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_GNU_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_dep = $(srcdir)/quadmath.map
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_dep = quadmath.map-sun
-@BUILD_LIBQUADMATH_TRUE@toolexeclib_LTLIBRARIES = libquadmath.la
-@BUILD_LIBQUADMATH_TRUE@libquadmath_la_LIBADD =
-@BUILD_LIBQUADMATH_TRUE@libquadmath_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
-@BUILD_LIBQUADMATH_TRUE@ $(version_arg) $(lt_host_flags) -lm
-
-@BUILD_LIBQUADMATH_TRUE@libquadmath_la_DEPENDENCIES = $(version_dep) $(libquadmath_la_LIBADD)
-@BUILD_LIBQUADMATH_TRUE@nodist_libsubinclude_HEADERS = quadmath.h quadmath_weak.h
-@BUILD_LIBQUADMATH_TRUE@libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
-@BUILD_LIBQUADMATH_TRUE@libquadmath_la_SOURCES = \
-@BUILD_LIBQUADMATH_TRUE@ math/x2y2m1q.c math/acoshq.c math/fmodq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/acosq.c math/frexpq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/rem_pio2q.c math/asinhq.c math/hypotq.c math/remainderq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/asinq.c math/rintq.c math/atan2q.c math/isinfq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/roundq.c math/atanhq.c math/isnanq.c math/scalblnq.c math/atanq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/j0q.c math/scalbnq.c math/cbrtq.c math/j1q.c math/signbitq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/ceilq.c math/jnq.c math/sincos_table.c math/complex.c math/ldexpq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/sincosq.c math/copysignq.c math/lgammaq.c math/sincosq_kernel.c \
-@BUILD_LIBQUADMATH_TRUE@ math/coshq.c math/llroundq.c math/sinhq.c math/cosq.c math/log10q.c \
-@BUILD_LIBQUADMATH_TRUE@ math/sinq.c math/cosq_kernel.c math/log1pq.c math/sinq_kernel.c \
-@BUILD_LIBQUADMATH_TRUE@ math/erfq.c math/logq.c math/sqrtq.c math/expm1q.c math/lroundq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/tanhq.c math/expq.c math/modfq.c math/tanq.c math/fabsq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/nanq.c math/tgammaq.c math/finiteq.c math/nextafterq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/truncq.c math/floorq.c math/powq.c math/fmaq.c math/logbq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/exp2q.c math/issignalingq.c math/lgammaq_neg.c math/lgammaq_product.c \
-@BUILD_LIBQUADMATH_TRUE@ math/tanq_kernel.c math/tgammaq_product.c math/casinhq_kernel.c \
-@BUILD_LIBQUADMATH_TRUE@ math/cacoshq.c math/cacosq.c math/casinhq.c math/casinq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/catanhq.c math/catanq.c math/cimagq.c math/conjq.c math/cprojq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/crealq.c math/fdimq.c math/fmaxq.c math/fminq.c math/ilogbq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/llrintq.c math/log2q.c math/lrintq.c math/nearbyintq.c math/remquoq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/ccoshq.c math/cexpq.c math/clog10q.c math/clogq.c math/csinq.c \
-@BUILD_LIBQUADMATH_TRUE@ math/csinhq.c math/csqrtq.c math/ctanq.c math/ctanhq.c \
-@BUILD_LIBQUADMATH_TRUE@ printf/addmul_1.c printf/add_n.c printf/cmp.c printf/divrem.c \
-@BUILD_LIBQUADMATH_TRUE@ printf/flt1282mpn.c printf/fpioconst.c printf/lshift.c printf/mul_1.c \
-@BUILD_LIBQUADMATH_TRUE@ printf/mul_n.c printf/mul.c printf/printf_fphex.c printf/printf_fp.c \
-@BUILD_LIBQUADMATH_TRUE@ printf/quadmath-printf.c printf/rshift.c printf/submul_1.c printf/sub_n.c \
-@BUILD_LIBQUADMATH_TRUE@ strtod/strtoflt128.c strtod/mpn2flt128.c strtod/tens_in_limb.c
+ACLOCAL_AMFLAGS = -I .. -I ../config
+AM_CPPFLAGS = -I $(top_srcdir)/../include
+AM_CFLAGS = $(XCFLAGS)
+gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
+@LIBQUAD_USE_SYMVER_FALSE@version_arg =
+@LIBQUAD_USE_SYMVER_GNU_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_arg = -Wl,--version-script=$(srcdir)/quadmath.map
+@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_arg = -Wl,-M,quadmath.map-sun
+@LIBQUAD_USE_SYMVER_FALSE@version_dep =
+@LIBQUAD_USE_SYMVER_GNU_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_dep = $(srcdir)/quadmath.map
+@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_dep = quadmath.map-sun
+toolexeclib_LTLIBRARIES = libquadmath.la
+libquadmath_la_LIBADD =
+libquadmath_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
+ $(version_arg) $(lt_host_flags) -lm
+
+libquadmath_la_DEPENDENCIES = $(version_dep) $(libquadmath_la_LIBADD)
+nodist_libsubinclude_HEADERS = quadmath.h quadmath_weak.h
+libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
+libquadmath_la_SOURCES = \
+ math/x2y2m1q.c math/acoshq.c math/fmodq.c \
+ math/acosq.c math/frexpq.c \
+ math/rem_pio2q.c math/asinhq.c math/hypotq.c math/remainderq.c \
+ math/asinq.c math/rintq.c math/atan2q.c math/isinfq.c \
+ math/roundq.c math/atanhq.c math/isnanq.c math/scalblnq.c math/atanq.c \
+ math/j0q.c math/scalbnq.c math/cbrtq.c math/j1q.c math/signbitq.c \
+ math/ceilq.c math/jnq.c math/sincos_table.c math/complex.c math/ldexpq.c \
+ math/sincosq.c math/copysignq.c math/lgammaq.c math/sincosq_kernel.c \
+ math/coshq.c math/llroundq.c math/sinhq.c math/cosq.c math/log10q.c \
+ math/sinq.c math/cosq_kernel.c math/log1pq.c math/sinq_kernel.c \
+ math/erfq.c math/logq.c math/sqrtq.c math/expm1q.c math/lroundq.c \
+ math/tanhq.c math/expq.c math/modfq.c math/tanq.c math/fabsq.c \
+ math/nanq.c math/tgammaq.c math/finiteq.c math/nextafterq.c \
+ math/truncq.c math/floorq.c math/powq.c math/fmaq.c math/logbq.c \
+ math/exp2q.c math/issignalingq.c math/lgammaq_neg.c math/lgammaq_product.c \
+ math/tanq_kernel.c math/tgammaq_product.c math/casinhq_kernel.c \
+ math/cacoshq.c math/cacosq.c math/casinhq.c math/casinq.c \
+ math/catanhq.c math/catanq.c math/cimagq.c math/conjq.c math/cprojq.c \
+ math/crealq.c math/fdimq.c math/fmaxq.c math/fminq.c math/ilogbq.c \
+ math/llrintq.c math/log2q.c math/lrintq.c math/nearbyintq.c math/remquoq.c \
+ math/ccoshq.c math/cexpq.c math/clog10q.c math/clogq.c math/csinq.c \
+ math/csinhq.c math/csqrtq.c math/ctanq.c math/ctanhq.c \
+ printf/addmul_1.c printf/add_n.c printf/cmp.c printf/divrem.c \
+ printf/flt1282mpn.c printf/fpioconst.c printf/lshift.c printf/mul_1.c \
+ printf/mul_n.c printf/mul.c printf/printf_fphex.c printf/printf_fp.c \
+ printf/quadmath-printf.c printf/rshift.c printf/submul_1.c printf/sub_n.c \
+ strtod/strtoflt128.c strtod/mpn2flt128.c strtod/tens_in_limb.c
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
-@BUILD_LIBQUADMATH_TRUE@AM_MAKEFLAGS = \
-@BUILD_LIBQUADMATH_TRUE@ "AR_FLAGS=$(AR_FLAGS)" \
-@BUILD_LIBQUADMATH_TRUE@ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
-@BUILD_LIBQUADMATH_TRUE@ "CFLAGS=$(CFLAGS)" \
-@BUILD_LIBQUADMATH_TRUE@ "CXXFLAGS=$(CXXFLAGS)" \
-@BUILD_LIBQUADMATH_TRUE@ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
-@BUILD_LIBQUADMATH_TRUE@ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
-@BUILD_LIBQUADMATH_TRUE@ "INSTALL=$(INSTALL)" \
-@BUILD_LIBQUADMATH_TRUE@ "INSTALL_DATA=$(INSTALL_DATA)" \
-@BUILD_LIBQUADMATH_TRUE@ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
-@BUILD_LIBQUADMATH_TRUE@ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
-@BUILD_LIBQUADMATH_TRUE@ "JC1FLAGS=$(JC1FLAGS)" \
-@BUILD_LIBQUADMATH_TRUE@ "LDFLAGS=$(LDFLAGS)" \
-@BUILD_LIBQUADMATH_TRUE@ "LIBCFLAGS=$(LIBCFLAGS)" \
-@BUILD_LIBQUADMATH_TRUE@ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
-@BUILD_LIBQUADMATH_TRUE@ "MAKE=$(MAKE)" \
-@BUILD_LIBQUADMATH_TRUE@ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
-@BUILD_LIBQUADMATH_TRUE@ "PICFLAG=$(PICFLAG)" \
-@BUILD_LIBQUADMATH_TRUE@ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
-@BUILD_LIBQUADMATH_TRUE@ "SHELL=$(SHELL)" \
-@BUILD_LIBQUADMATH_TRUE@ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
-@BUILD_LIBQUADMATH_TRUE@ "exec_prefix=$(exec_prefix)" \
-@BUILD_LIBQUADMATH_TRUE@ "infodir=$(infodir)" \
-@BUILD_LIBQUADMATH_TRUE@ "libdir=$(libdir)" \
-@BUILD_LIBQUADMATH_TRUE@ "prefix=$(prefix)" \
-@BUILD_LIBQUADMATH_TRUE@ "includedir=$(includedir)" \
-@BUILD_LIBQUADMATH_TRUE@ "AR=$(AR)" \
-@BUILD_LIBQUADMATH_TRUE@ "AS=$(AS)" \
-@BUILD_LIBQUADMATH_TRUE@ "CC=$(CC)" \
-@BUILD_LIBQUADMATH_TRUE@ "CXX=$(CXX)" \
-@BUILD_LIBQUADMATH_TRUE@ "LD=$(LD)" \
-@BUILD_LIBQUADMATH_TRUE@ "LIBCFLAGS=$(LIBCFLAGS)" \
-@BUILD_LIBQUADMATH_TRUE@ "NM=$(NM)" \
-@BUILD_LIBQUADMATH_TRUE@ "PICFLAG=$(PICFLAG)" \
-@BUILD_LIBQUADMATH_TRUE@ "RANLIB=$(RANLIB)" \
-@BUILD_LIBQUADMATH_TRUE@ "DESTDIR=$(DESTDIR)"
+AM_MAKEFLAGS = \
+ "AR_FLAGS=$(AR_FLAGS)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CFLAGS=$(CFLAGS)" \
+ "CXXFLAGS=$(CXXFLAGS)" \
+ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+ "JC1FLAGS=$(JC1FLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+ "MAKE=$(MAKE)" \
+ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+ "PICFLAG=$(PICFLAG)" \
+ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+ "SHELL=$(SHELL)" \
+ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+ "exec_prefix=$(exec_prefix)" \
+ "infodir=$(infodir)" \
+ "libdir=$(libdir)" \
+ "prefix=$(prefix)" \
+ "includedir=$(includedir)" \
+ "AR=$(AR)" \
+ "AS=$(AS)" \
+ "CC=$(CC)" \
+ "CXX=$(CXX)" \
+ "LD=$(LD)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "NM=$(NM)" \
+ "PICFLAG=$(PICFLAG)" \
+ "RANLIB=$(RANLIB)" \
+ "DESTDIR=$(DESTDIR)"
# Subdir rules rely on $(FLAGS_TO_PASS)
-@BUILD_LIBQUADMATH_TRUE@FLAGS_TO_PASS = $(AM_MAKEFLAGS)
-@BUILD_LIBQUADMATH_TRUE@MAKEOVERRIDES =
-@BUILD_LIBQUADMATH_TRUE@@GENINSRC_FALSE@STAMP_GENINSRC =
+FLAGS_TO_PASS = $(AM_MAKEFLAGS)
+MAKEOVERRIDES =
+@GENINSRC_FALSE@STAMP_GENINSRC =
# AM_CONDITIONAL on configure option --generated-files-in-srcdir
-@BUILD_LIBQUADMATH_TRUE@@GENINSRC_TRUE@STAMP_GENINSRC = stamp-geninsrc
-@BUILD_LIBQUADMATH_TRUE@ALL_LOCAL_DEPS = $(STAMP_GENINSRC)
-@BUILD_INFO_FALSE@@BUILD_LIBQUADMATH_TRUE@STAMP_BUILD_INFO =
+@GENINSRC_TRUE@STAMP_GENINSRC = stamp-geninsrc
+ALL_LOCAL_DEPS = $(STAMP_GENINSRC)
+@BUILD_INFO_FALSE@STAMP_BUILD_INFO =
# AM_CONDITIONAL on configure check ACX_CHECK_PROG_VER([MAKEINFO])
-@BUILD_INFO_TRUE@@BUILD_LIBQUADMATH_TRUE@STAMP_BUILD_INFO = stamp-build-info
-@BUILD_LIBQUADMATH_TRUE@CLEANFILES = $(STAMP_GENINSRC) $(STAMP_BUILD_INFO)
-@BUILD_LIBQUADMATH_TRUE@MAINTAINERCLEANFILES = $(srcdir)/libquadmath.info
+@BUILD_INFO_TRUE@STAMP_BUILD_INFO = stamp-build-info
+CLEANFILES = $(STAMP_GENINSRC) $(STAMP_BUILD_INFO)
+MAINTAINERCLEANFILES = $(srcdir)/libquadmath.info
# Automake Documentation:
# If your package has Texinfo files in many directories, you can use the
@@ -563,8 +563,8 @@ TEXINFO_TEX = ../gcc/doc/include/texinfo
# Defines info, dvi, pdf and html targets
MAKEINFOFLAGS = -I $(srcdir)/../gcc/doc/include
-@BUILD_LIBQUADMATH_FALSE@info_TEXINFOS =
-@BUILD_LIBQUADMATH_TRUE@info_TEXINFOS = libquadmath.texi
+info_TEXINFOS =
+info_TEXINFOS = libquadmath.texi
libquadmath_TEXINFOS = libquadmath-vers.texi
MULTISRCTOP =
MULTIBUILDTOP =
@@ -1186,6 +1186,7 @@ distclean-tags:
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
check-am: all-am
check: check-am
+#all-local
all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) $(HEADERS) config.h \
all-local
installdirs:
@@ -1424,22 +1425,22 @@ uninstall-am: uninstall-dvi-am uninstall
.PRECIOUS: Makefile
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@quadmath.map-sun : $(srcdir)/quadmath.map \
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(top_srcdir)/../contrib/make_sunver.pl \
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(libquadmath_la_OBJECTS) $(libquadmath_la_LIBADD)
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ perl $(top_srcdir)/../contrib/make_sunver.pl \
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(srcdir)/quadmath.map \
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ `echo $(libquadmath_la_OBJECTS) $(libquadmath_la_LIBADD) | \
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ sed 's,\([^/ ]*\)\.l\([ao]\),.libs/\1.\2,g'` \
-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ > $@ || (rm -f $@ ; exit 1)
-
-@BUILD_LIBQUADMATH_TRUE@stamp-geninsrc: libquadmath.info
-@BUILD_LIBQUADMATH_TRUE@ cp -p $(top_builddir)/libquadmath.info $(srcdir)/libquadmath.info
-@BUILD_LIBQUADMATH_TRUE@ @touch $@
-
-@BUILD_LIBQUADMATH_TRUE@stamp-build-info: libquadmath.texi $(libquadmath_TEXINFOS)
-@BUILD_LIBQUADMATH_TRUE@ $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -o libquadmath.info $(srcdir)/libquadmath.texi
-@BUILD_LIBQUADMATH_TRUE@ @touch $@
+@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@quadmath.map-sun : $(srcdir)/quadmath.map \
+@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(top_srcdir)/../contrib/make_sunver.pl \
+@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(libquadmath_la_OBJECTS) $(libquadmath_la_LIBADD)
+@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ perl $(top_srcdir)/../contrib/make_sunver.pl \
+@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(srcdir)/quadmath.map \
+@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ `echo $(libquadmath_la_OBJECTS) $(libquadmath_la_LIBADD) | \
+@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ sed 's,\([^/ ]*\)\.l\([ao]\),.libs/\1.\2,g'` \
+@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ > $@ || (rm -f $@ ; exit 1)
+
+stamp-geninsrc: libquadmath.info
+ cp -p $(top_builddir)/libquadmath.info $(srcdir)/libquadmath.info
+ @touch $@
+
+stamp-build-info: libquadmath.texi $(libquadmath_TEXINFOS)
+ $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -o libquadmath.info $(srcdir)/libquadmath.texi
+ @touch $@
all-local: $(ALL_LOCAL_DEPS)
diff -Nurp a/libquadmath/quadmath.h b/libquadmath/quadmath.h
--- a/libquadmath/quadmath.h 2020-03-31 09:51:59.000000000 +0800
+++ b/libquadmath/quadmath.h 2020-04-06 11:52:45.650793256 +0800
@@ -27,6 +27,9 @@ Boston, MA 02110-1301, USA. */
extern "C" {
#endif
+#ifdef AARCH64_QUADMATH
+typedef long double __float128;
+#endif
/* Define the complex type corresponding to __float128
("_Complex __float128" is not allowed) */
#if (!defined(_ARCH_PPC)) || defined(__LONG_DOUBLE_IEEE128__)
diff -Nurp a/libquadmath/quadmath.h b/libquadmath/quadmath.h
--- a/libquadmath/quadmath.h 2015-08-09 16:46:52.541904000 +0800
+++ b/libquadmath/quadmath.h 2019-08-17 18:25:51.923399149 +0800
@@ -154,10 +154,9 @@ extern int quadmath_snprintf (char *str,
#define FLT128_MAX_10_EXP 4932
-#define HUGE_VALQ __builtin_huge_valq()
/* The following alternative is valid, but brings the warning:
(floating constant exceeds range of __float128) */
-/* #define HUGE_VALQ (__extension__ 0x1.0p32767Q) */
+ #define HUGE_VALQ (__extension__ 0x1.0p32767Q)
#define M_Eq 2.718281828459045235360287471352662498Q /* e */
#define M_LOG2Eq 1.442695040888963407359924681001892137Q /* log_2 e */

View File

@ -1,258 +0,0 @@
diff -Nurp a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
--- a/gcc/c-family/c-opts.c 2021-01-07 17:32:31.856000000 +0800
+++ b/gcc/c-family/c-opts.c 2021-01-07 17:05:02.524000000 +0800
@@ -783,6 +783,10 @@ c_common_post_options (const char **pfil
if (cpp_opts->deps.style == DEPS_NONE)
check_deps_environment_vars ();
+ if (flag_simdmath)
+ {
+ defer_opt (OPT_include, "simdmath.h");
+ }
handle_deferred_opts ();
sanitize_cpp_opts ();
diff -Nurp a/gcc/common.opt b/gcc/common.opt
--- a/gcc/common.opt 2021-01-07 17:30:43.912000000 +0800
+++ b/gcc/common.opt 2021-01-07 17:38:38.612000000 +0800
@@ -1935,6 +1935,10 @@ fmath-errno
Common Report Var(flag_errno_math) Init(1) Optimization SetByCombined
Set errno after built-in math functions.
+fsimdmath
+Common Report Var(flag_simdmath) Init(0) Optimization
+Enable auto-vectorize math functions for mathlib. This option will turn on -fno-math-errno and -fopenmp-simd.
+
fmax-errors=
Common Joined RejectNegative UInteger Var(flag_max_errors)
-fmax-errors=<number> Maximum number of errors to report.
diff -Nurp a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
--- a/gcc/config/aarch64/aarch64.c 2021-01-07 17:30:43.912000000 +0800
+++ b/gcc/config/aarch64/aarch64.c 2021-01-05 15:17:21.580000000 +0800
@@ -21588,8 +21588,12 @@ aarch64_simd_clone_compute_vecsize_and_s
elt_bits = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type));
if (clonei->simdlen == 0)
{
- count = 2;
- vec_bits = (num == 0 ? 64 : 128);
+ /* Currently mathlib or sleef hasn't provide function for V2SF mode
+ simdclone of single precision functions. (e.g._ZCVnN2v_expf)
+ Therefore this mode is disabled by default to avoid link error.
+ Use -msimdmath-64 option to enable this mode. */
+ count = flag_simdmath_64 ? 2 : 1;
+ vec_bits = ((num == 0 && flag_simdmath_64) ? 64 : 128);
clonei->simdlen = vec_bits / elt_bits;
}
else
diff -Nurp a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
--- a/gcc/config/aarch64/aarch64.opt 2021-01-07 17:30:43.912000000 +0800
+++ b/gcc/config/aarch64/aarch64.opt 2021-01-05 15:17:21.448000000 +0800
@@ -197,6 +197,12 @@ precision of square root results to abou
single precision and to 32 bits for double precision.
If enabled, it implies -mlow-precision-recip-sqrt.
+msimdmath-64
+Target Var(flag_simdmath_64) Optimization
+Allow compiler to generate V2SF 64 bits simdclone of math functions,
+which is not currently supported in mathlib or sleef.
+Therefore this option is disabled by default.
+
mlow-precision-div
Target Var(flag_mlow_precision_div) Optimization
Enable the division approximation. Enabling this reduces
diff -Nurp a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
--- a/gcc/fortran/scanner.c 2021-01-07 17:31:59.264000000 +0800
+++ b/gcc/fortran/scanner.c 2021-01-07 17:05:28.776000000 +0800
@@ -2702,6 +2702,10 @@ gfc_new_file (void)
&& !load_file (flag_pre_include, NULL, false))
exit (FATAL_EXIT_CODE);
+ if (flag_simdmath
+ && !load_file ("simdmath_f.h", NULL, false))
+ exit (FATAL_EXIT_CODE);
+
if (gfc_cpp_enabled ())
{
result = gfc_cpp_preprocess (gfc_source_file);
diff -Nurp a/gcc/opts.c b/gcc/opts.c
--- a/gcc/opts.c 2021-01-07 17:30:57.740000000 +0800
+++ b/gcc/opts.c 2021-01-05 15:17:21.068000000 +0800
@@ -190,6 +190,7 @@ typedef char *char_p; /* For DEF_VEC_P.
static void handle_param (struct gcc_options *opts,
struct gcc_options *opts_set, location_t loc,
const char *carg);
+static void set_simdmath_flags (struct gcc_options *opts, int set);
static void set_debug_level (enum debug_info_type type, int extended,
const char *arg, struct gcc_options *opts,
struct gcc_options *opts_set,
@@ -2420,6 +2421,10 @@ common_handle_option (struct gcc_options
dc->min_margin_width = value;
break;
+ case OPT_fsimdmath:
+ set_simdmath_flags (opts, value);
+ break;
+
case OPT_fdump_:
/* Deferred. */
break;
@@ -2843,6 +2848,18 @@ handle_param (struct gcc_options *opts,
free (arg);
}
+/* The following routines are used to set -fno-math-errno and -fopenmp-simd
+ to enable vector mathlib. */
+static void
+set_simdmath_flags (struct gcc_options *opts, int set)
+{
+ if (set)
+ {
+ opts->x_flag_errno_math = 0;
+ opts->x_flag_openmp_simd = 1;
+ }
+}
+
/* Used to set the level of strict aliasing warnings in OPTS,
when no level is specified (i.e., when -Wstrict-aliasing, and not
-Wstrict-aliasing=level was given).
diff -Nurp a/libgomp/configure b/libgomp/configure
--- a/libgomp/configure 2021-01-07 17:40:08.216000000 +0800
+++ b/libgomp/configure 2021-01-07 16:29:45.628000000 +0800
@@ -17258,7 +17258,7 @@ fi
-ac_config_files="$ac_config_files omp.h omp_lib.h omp_lib.f90 libgomp_f.h"
+ac_config_files="$ac_config_files omp.h omp_lib.h simdmath.h simdmath_f.h omp_lib.f90 libgomp_f.h"
ac_config_files="$ac_config_files Makefile testsuite/Makefile libgomp.spec"
@@ -18426,6 +18426,8 @@ do
"gstdint.h") CONFIG_COMMANDS="$CONFIG_COMMANDS gstdint.h" ;;
"omp.h") CONFIG_FILES="$CONFIG_FILES omp.h" ;;
"omp_lib.h") CONFIG_FILES="$CONFIG_FILES omp_lib.h" ;;
+ "simdmath.h") CONFIG_FILES="$CONFIG_FILES simdmath.h" ;;
+ "simdmath_f.h") CONFIG_FILES="$CONFIG_FILES simdmath_f.h" ;;
"omp_lib.f90") CONFIG_FILES="$CONFIG_FILES omp_lib.f90" ;;
"libgomp_f.h") CONFIG_FILES="$CONFIG_FILES libgomp_f.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
diff -Nurp a/libgomp/configure.ac b/libgomp/configure.ac
--- a/libgomp/configure.ac 2021-01-07 17:40:08.216000000 +0800
+++ b/libgomp/configure.ac 2021-01-07 16:26:26.560000000 +0800
@@ -422,7 +422,7 @@ CFLAGS="$save_CFLAGS"
# Determine what GCC version number to use in filesystem paths.
GCC_BASE_VER
-AC_CONFIG_FILES(omp.h omp_lib.h omp_lib.f90 libgomp_f.h)
+AC_CONFIG_FILES(omp.h omp_lib.h simdmath.h simdmath_f.h omp_lib.f90 libgomp_f.h)
AC_CONFIG_FILES(Makefile testsuite/Makefile libgomp.spec)
AC_CONFIG_FILES([testsuite/libgomp-test-support.pt.exp:testsuite/libgomp-test-support.exp.in])
AC_OUTPUT
diff -Nurp a/libgomp/Makefile.am b/libgomp/Makefile.am
--- a/libgomp/Makefile.am 2021-01-07 17:40:08.168000000 +0800
+++ b/libgomp/Makefile.am 2021-01-07 16:27:39.776000000 +0800
@@ -74,9 +74,9 @@ libgomp_la_SOURCES += openacc.f90
endif
nodist_noinst_HEADERS = libgomp_f.h
-nodist_libsubinclude_HEADERS = omp.h openacc.h
+nodist_libsubinclude_HEADERS = omp.h openacc.h simdmath.h
if USE_FORTRAN
-nodist_finclude_HEADERS = omp_lib.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod \
+nodist_finclude_HEADERS = omp_lib.h simdmath_f.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod \
openacc_lib.h openacc.f90 openacc.mod openacc_kinds.mod
endif
diff -Nurp a/libgomp/Makefile.in b/libgomp/Makefile.in
--- a/libgomp/Makefile.in 2021-01-07 17:40:08.208000000 +0800
+++ b/libgomp/Makefile.in 2021-01-07 16:50:28.820000000 +0800
@@ -145,7 +145,7 @@ am__CONFIG_DISTCLEAN_FILES = config.stat
configure.lineno config.status.lineno
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = config.h
-CONFIG_CLEAN_FILES = omp.h omp_lib.h omp_lib.f90 libgomp_f.h \
+CONFIG_CLEAN_FILES = omp.h omp_lib.h simdmath.h simdmath_f.h omp_lib.f90 libgomp_f.h \
libgomp.spec
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -575,8 +575,8 @@ libgomp_la_SOURCES = alloc.c atomic.c ba
@PLUGIN_HSA_TRUE@libgomp_plugin_hsa_la_LIBADD = libgomp.la $(PLUGIN_HSA_LIBS)
@PLUGIN_HSA_TRUE@libgomp_plugin_hsa_la_LIBTOOLFLAGS = --tag=disable-static
nodist_noinst_HEADERS = libgomp_f.h
-nodist_libsubinclude_HEADERS = omp.h openacc.h
-@USE_FORTRAN_TRUE@nodist_finclude_HEADERS = omp_lib.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod \
+nodist_libsubinclude_HEADERS = omp.h openacc.h simdmath.h
+@USE_FORTRAN_TRUE@nodist_finclude_HEADERS = omp_lib.h simdmath_f.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod \
@USE_FORTRAN_TRUE@ openacc_lib.h openacc.f90 openacc.mod openacc_kinds.mod
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -668,6 +668,10 @@ omp.h: $(top_builddir)/config.status $(s
cd $(top_builddir) && $(SHELL) ./config.status $@
omp_lib.h: $(top_builddir)/config.status $(srcdir)/omp_lib.h.in
cd $(top_builddir) && $(SHELL) ./config.status $@
+simdmath_f.h: $(top_builddir)/config.status $(srcdir)/simdmath_f.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+simdmath.h: $(top_builddir)/config.status $(srcdir)/simdmath.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
omp_lib.f90: $(top_builddir)/config.status $(srcdir)/omp_lib.f90.in
cd $(top_builddir) && $(SHELL) ./config.status $@
libgomp_f.h: $(top_builddir)/config.status $(srcdir)/libgomp_f.h.in
diff -Nurp a/libgomp/simdmath_f.h.in b/libgomp/simdmath_f.h.in
--- a/libgomp/simdmath_f.h.in 1970-01-01 08:00:00.000000000 +0800
+++ b/libgomp/simdmath_f.h.in 2021-01-07 16:13:23.196000000 +0800
@@ -0,0 +1,11 @@
+!GCC$ builtin (cos) attributes simd (notinbranch)
+!GCC$ builtin (cosf) attributes simd (notinbranch)
+!GCC$ builtin (sin) attributes simd (notinbranch)
+!GCC$ builtin (sinf) attributes simd (notinbranch)
+!GCC$ builtin (exp) attributes simd (notinbranch)
+!GCC$ builtin (expf) attributes simd (notinbranch)
+!GCC$ builtin (exp2f) attributes simd (notinbranch)
+!GCC$ builtin (log) attributes simd (notinbranch)
+!GCC$ builtin (logf) attributes simd (notinbranch)
+!GCC$ builtin (pow) attributes simd (notinbranch)
+!GCC$ builtin (powf) attributes simd (notinbranch)
diff -Nurp a/libgomp/simdmath.h.in b/libgomp/simdmath.h.in
--- a/libgomp/simdmath.h.in 1970-01-01 08:00:00.000000000 +0800
+++ b/libgomp/simdmath.h.in 2021-01-07 16:13:56.144000000 +0800
@@ -0,0 +1,40 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma omp declare simd simdlen(2) notinbranch
+double cos (double x);
+
+#pragma omp declare simd simdlen(4) notinbranch
+float cosf (float x);
+
+#pragma omp declare simd simdlen(2) notinbranch
+double sin (double x);
+
+#pragma omp declare simd simdlen(4) notinbranch
+float sinf (float x);
+
+#pragma omp declare simd simdlen(2) notinbranch
+double exp (double x);
+
+#pragma omp declare simd simdlen(4) notinbranch
+float expf (float x);
+
+#pragma omp declare simd simdlen(2) notinbranch
+double log (double x);
+
+#pragma omp declare simd simdlen(4) notinbranch
+float logf (float x);
+
+#pragma omp declare simd simdlen(2) notinbranch
+double pow (double x, double y);
+
+#pragma omp declare simd simdlen(4) notinbranch
+float powf (float x, float y);
+
+#pragma omp declare simd simdlen(4) notinbranch
+float exp2f (float x);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif

View File

@ -1,18 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-fix-CTOR-vectorization.patch
3d42842c07f4143042f3dcc39a050b262bcf1b55
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 9d17e3386fa..fb13af7965e 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2257,6 +2257,7 @@ vect_analyze_slp_instance (vec_info *vinfo,
/* Value is defined in another basic block. */
if (!def_info)
return false;
+ def_info = vect_stmt_to_vectorize (def_info);
scalar_stmts.safe_push (def_info);
}
else

View File

@ -1,51 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-IPA-compare-VRP-types.patch
a86623902767122c71c7229150a8b8a79cbb3673
diff -Nurp a/gcc/ipa-prop.c b/gcc/ipa-prop.c
--- a/gcc/ipa-prop.c 2020-11-28 00:19:34.340000000 +0800
+++ b/gcc/ipa-prop.c 2020-11-28 00:21:24.680000000 +0800
@@ -122,7 +122,8 @@ struct ipa_vr_ggc_hash_traits : public g
static bool
equal (const value_range_base *a, const value_range_base *b)
{
- return a->equal_p (*b);
+ return (a->equal_p (*b)
+ && types_compatible_p (a->type (), b->type ()));
}
static void
mark_empty (value_range_base *&p)
diff -Nurp a/gcc/testsuite/gcc.c-torture/execute/pr97404.c b/gcc/testsuite/gcc.c-torture/execute/pr97404.c
--- a/gcc/testsuite/gcc.c-torture/execute/pr97404.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.c-torture/execute/pr97404.c 2020-11-28 00:21:24.680000000 +0800
@@ -0,0 +1,28 @@
+/* PR ipa/97404 */
+/* { dg-additional-options "-fno-inline" } */
+
+char a, b;
+long c;
+short d, e;
+long *f = &c;
+int g;
+char h(signed char i) { return 0; }
+static short j(short i, int k) { return i < 0 ? 0 : i >> k; }
+void l(void);
+void m(void)
+{
+ e = j(d | 9766, 11);
+ *f = e;
+}
+void l(void)
+{
+ a = 5 | g;
+ b = h(a);
+}
+int main()
+{
+ m();
+ if (c != 4)
+ __builtin_abort();
+ return 0;
+}

View File

@ -1,123 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-optimization-39612-avoid-issueing-loads-in-SM-w.patch
f9e1ea10e657af9fb02fafecf1a600740fd34409
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr39612.c b/gcc/testsuite/gcc.dg/tree-ssa/pr39612.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr39612.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr39612.c 2020-08-17 11:14:08.000000000 +0800
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-lim2-details -Wuninitialized" } */
+
+void foo(int *);
+void f2(int dst[3], int R)
+{
+ int i, inter[2];
+
+ for (i = 1; i < R; i++) {
+ if (i & 8)
+ {
+ inter[0] = 1;
+ inter[1] = 1;
+ }
+ }
+
+ foo(inter);
+}
+
+/* { dg-final { scan-tree-dump-times "Executing store motion" 2 "lim2" } } */
+/* { dg-final { scan-tree-dump-not " = inter\\\[\[0-1\]\\\];" "lim2" } } */
diff -Nurp a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
--- a/gcc/tree-ssa-loop-im.c 2020-08-17 11:13:58.436000000 +0800
+++ b/gcc/tree-ssa-loop-im.c 2020-08-17 11:14:08.000000000 +0800
@@ -127,6 +127,8 @@ struct im_mem_ref
bitmap stored; /* The set of loops in that this memory location
is stored to. */
+ bitmap loaded; /* The set of loops in that this memory location
+ is loaded from. */
vec<mem_ref_loc> accesses_in_loop;
/* The locations of the accesses. Vector
indexed by the loop number. */
@@ -1394,6 +1396,7 @@ mem_ref_alloc (ao_ref *mem, unsigned has
ref->ref_decomposed = false;
ref->hash = hash;
ref->stored = NULL;
+ ref->loaded = NULL;
bitmap_initialize (&ref->indep_loop, &lim_bitmap_obstack);
bitmap_initialize (&ref->dep_loop, &lim_bitmap_obstack);
ref->accesses_in_loop.create (1);
@@ -1434,6 +1437,27 @@ mark_ref_stored (im_mem_ref *ref, struct
loop = loop_outer (loop);
}
+/* Set the LOOP bit in REF loaded bitmap and allocate that if
+ necessary. Return whether a bit was changed. */
+
+static bool
+set_ref_loaded_in_loop (im_mem_ref *ref, class loop *loop)
+{
+ if (!ref->loaded)
+ ref->loaded = BITMAP_ALLOC (&lim_bitmap_obstack);
+ return bitmap_set_bit (ref->loaded, loop->num);
+}
+
+/* Marks reference REF as loaded in LOOP. */
+
+static void
+mark_ref_loaded (im_mem_ref *ref, class loop *loop)
+{
+ while (loop != current_loops->tree_root
+ && set_ref_loaded_in_loop (ref, loop))
+ loop = loop_outer (loop);
+}
+
/* Gathers memory references in statement STMT in LOOP, storing the
information about them in the memory_accesses structure. Marks
the vops accessed through unrecognized statements there as
@@ -1569,6 +1593,8 @@ gather_mem_refs_stmt (struct loop *loop,
bitmap_set_bit (&memory_accesses.refs_stored_in_loop[loop->num], ref->id);
mark_ref_stored (ref, loop);
}
+ else
+ mark_ref_loaded (ref, loop);
init_lim_data (stmt)->ref = ref->id;
return;
}
@@ -1956,6 +1982,8 @@ execute_sm_if_changed (edge ex, tree mem
gsi = gsi_start_bb (then_bb);
/* Insert actual store. */
stmt = gimple_build_assign (unshare_expr (mem), tmp_var);
+ /* Make sure to not warn about maybe-uninit uses of tmp_var here. */
+ gimple_set_no_warning (stmt, true);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
edge e1 = single_succ_edge (new_bb);
@@ -2102,14 +2130,17 @@ execute_sm (struct loop *loop, vec<edge>
by move_computations after all dependencies. */
gsi = gsi_for_stmt (first_mem_ref_loc (loop, ref)->stmt);
- /* FIXME/TODO: For the multi-threaded variant, we could avoid this
- load altogether, since the store is predicated by a flag. We
- could, do the load only if it was originally in the loop. */
- load = gimple_build_assign (tmp_var, unshare_expr (ref->mem.ref));
- lim_data = init_lim_data (load);
- lim_data->max_loop = loop;
- lim_data->tgt_loop = loop;
- gsi_insert_before (&gsi, load, GSI_SAME_STMT);
+ /* Avoid doing a load if there was no load of the ref in the loop.
+ Esp. when the ref is not always stored we cannot optimize it
+ away later. */
+ if (ref->loaded && bitmap_bit_p (ref->loaded, loop->num))
+ {
+ load = gimple_build_assign (tmp_var, unshare_expr (ref->mem.ref));
+ lim_data = init_lim_data (load);
+ lim_data->max_loop = loop;
+ lim_data->tgt_loop = loop;
+ gsi_insert_before (&gsi, load, GSI_SAME_STMT);
+ }
if (multi_threaded_model_p)
{

View File

@ -1,35 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Fix-ICE-when-__builtin_calloc-has-no-LHS-PR-tree-opt.patch
4c4be718fb65f9b8dd06d83c6fa3f697a5369d52
diff -Nurp a/gcc/testsuite/gcc.target/s390/pr91014.c b/gcc/testsuite/gcc.target/s390/pr91014.c
--- a/gcc/testsuite/gcc.target/s390/pr91014.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.target/s390/pr91014.c 2020-09-09 15:47:34.740000000 +0800
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+/* { dg-require-effective-target alloca } */
+
+void foo(void)
+{
+ __builtin_calloc (1, 1); /* { dg-warning "ignoring return value of '__builtin_calloc' declared with attribute 'warn_unused_result'" } */
+}
diff -Nurp a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
--- a/gcc/tree-ssa-dse.c 2020-09-09 15:47:21.084000000 +0800
+++ b/gcc/tree-ssa-dse.c 2020-09-09 15:47:34.740000000 +0800
@@ -119,10 +119,11 @@ initialize_ao_ref_for_dse (gimple *stmt,
{
tree nelem = gimple_call_arg (stmt, 0);
tree selem = gimple_call_arg (stmt, 1);
+ tree lhs;
if (TREE_CODE (nelem) == INTEGER_CST
- && TREE_CODE (selem) == INTEGER_CST)
+ && TREE_CODE (selem) == INTEGER_CST
+ && (lhs = gimple_call_lhs (stmt)) != NULL_TREE)
{
- tree lhs = gimple_call_lhs (stmt);
tree size = fold_build2 (MULT_EXPR, TREE_TYPE (nelem),
nelem, selem);
ao_ref_init_from_ptr_and_size (write, lhs, size);

View File

@ -1,38 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-PR-tree-optimization-94574-aarch64-ICE-during-GIMPLE.patch
f65cecabc32fe12b024253502af953e657e1a878
diff -uprN a/gcc/testsuite/gcc.dg/pr94574.c b/gcc/testsuite/gcc.dg/pr94574.c
--- a/gcc/testsuite/gcc.dg/pr94574.c 1970-01-01 00:00:00.000000000 +0000
+++ b/gcc/testsuite/gcc.dg/pr94574.c 2020-04-15 21:08:48.972000000 +0000
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned int v4si __attribute__((vector_size(16)));
+typedef unsigned int v2si __attribute__((vector_size(8)));
+
+/* The aliasing is somewhat dubious here, but it must compile. */
+
+v2si
+foo (v4si v)
+{
+ v2si res;
+ *(v4si *) &res = v;
+ return res;
+}
diff -uprN a/gcc/tree-ssa.c b/gcc/tree-ssa.c
--- a/gcc/tree-ssa.c 2020-03-31 01:51:30.000000000 +0000
+++ b/gcc/tree-ssa.c 2020-04-15 21:26:09.828000000 +0000
@@ -1528,7 +1528,9 @@ non_rewritable_lvalue_p (tree lhs)
&& known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))),
mem_ref_offset (lhs))
&& multiple_of_p (sizetype, TREE_OPERAND (lhs, 1),
- TYPE_SIZE_UNIT (TREE_TYPE (lhs))))
+ TYPE_SIZE_UNIT (TREE_TYPE (lhs)))
+ && known_ge (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (decl))),
+ wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (lhs)))))
return false;
}

View File

@ -1,396 +0,0 @@
This backport contains 2 patchs from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-affine.c-expr_to_aff_combination-New-function-s.patch
5120e0d8d48f4590a275e60565de6c5a4e772fc1
0001-PR-tree-optimization-94574-aarch64-ICE-during-GIMPLE.patch
0447929f11e6a3e1b076841712b90a8b6bc7d33a
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c 2020-12-08 14:54:11.467633230 +0800
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -funroll-loops -fdump-tree-lim2-details" } */
+
+#define TYPE unsigned int
+
+#include "pr83403.h"
+
+/* { dg-final { scan-tree-dump-times "Executing store motion of" 10 "lim2" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c 2020-12-08 14:54:11.467633230 +0800
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -funroll-loops -fdump-tree-lim2-details" } */
+
+#define TYPE int
+
+#include "pr83403.h"
+
+/* { dg-final { scan-tree-dump-times "Executing store motion of" 10 "lim2" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr83403.h b/gcc/testsuite/gcc.dg/tree-ssa/pr83403.h
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr83403.h 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83403.h 2020-12-08 14:54:11.467633230 +0800
@@ -0,0 +1,30 @@
+__attribute__ ((noinline)) void
+calculate (const double *__restrict__ A, const double *__restrict__ B,
+ double *__restrict__ C)
+{
+ TYPE m = 0;
+ TYPE n = 0;
+ TYPE k = 0;
+
+ A = (const double *) __builtin_assume_aligned (A, 16);
+ B = (const double *) __builtin_assume_aligned (B, 16);
+ C = (double *) __builtin_assume_aligned (C, 16);
+
+ for (n = 0; n < 9; n++)
+ {
+ for (m = 0; m < 10; m++)
+ {
+ C[(n * 10) + m] = 0.0;
+ }
+
+ for (k = 0; k < 17; k++)
+ {
+#pragma simd
+ for (m = 0; m < 10; m++)
+ {
+ C[(n * 10) + m] += A[(k * 20) + m] * B[(n * 20) + k];
+ }
+ }
+ }
+}
+
diff -Nurp a/gcc/tree-affine.c b/gcc/tree-affine.c
--- a/gcc/tree-affine.c 2020-12-09 09:01:13.179633230 +0800
+++ b/gcc/tree-affine.c 2020-12-08 14:54:11.467633230 +0800
@@ -259,104 +259,66 @@ aff_combination_convert (aff_tree *comb,
}
}
-/* Splits EXPR into an affine combination of parts. */
+/* Tries to handle OP0 CODE OP1 as affine combination of parts. Returns
+ true when that was successful and returns the combination in COMB. */
-void
-tree_to_aff_combination (tree expr, tree type, aff_tree *comb)
+static bool
+expr_to_aff_combination (aff_tree *comb, tree_code code, tree type,
+ tree op0, tree op1 = NULL_TREE)
{
aff_tree tmp;
- enum tree_code code;
- tree cst, core, toffset;
poly_int64 bitpos, bitsize, bytepos;
- machine_mode mode;
- int unsignedp, reversep, volatilep;
-
- STRIP_NOPS (expr);
- code = TREE_CODE (expr);
switch (code)
{
case POINTER_PLUS_EXPR:
- tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
- tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp);
+ tree_to_aff_combination (op0, type, comb);
+ tree_to_aff_combination (op1, sizetype, &tmp);
aff_combination_add (comb, &tmp);
- return;
+ return true;
case PLUS_EXPR:
case MINUS_EXPR:
- tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
- tree_to_aff_combination (TREE_OPERAND (expr, 1), type, &tmp);
+ tree_to_aff_combination (op0, type, comb);
+ tree_to_aff_combination (op1, type, &tmp);
if (code == MINUS_EXPR)
aff_combination_scale (&tmp, -1);
aff_combination_add (comb, &tmp);
- return;
+ return true;
case MULT_EXPR:
- cst = TREE_OPERAND (expr, 1);
- if (TREE_CODE (cst) != INTEGER_CST)
+ if (TREE_CODE (op1) != INTEGER_CST)
break;
- tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
- aff_combination_scale (comb, wi::to_widest (cst));
- return;
+ tree_to_aff_combination (op0, type, comb);
+ aff_combination_scale (comb, wi::to_widest (op1));
+ return true;
case NEGATE_EXPR:
- tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
+ tree_to_aff_combination (op0, type, comb);
aff_combination_scale (comb, -1);
- return;
+ return true;
case BIT_NOT_EXPR:
/* ~x = -x - 1 */
- tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
+ tree_to_aff_combination (op0, type, comb);
aff_combination_scale (comb, -1);
aff_combination_add_cst (comb, -1);
- return;
-
- case ADDR_EXPR:
- /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR. */
- if (TREE_CODE (TREE_OPERAND (expr, 0)) == MEM_REF)
- {
- expr = TREE_OPERAND (expr, 0);
- tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
- tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp);
- aff_combination_add (comb, &tmp);
- return;
- }
- core = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize, &bitpos,
- &toffset, &mode, &unsignedp, &reversep,
- &volatilep);
- if (!multiple_p (bitpos, BITS_PER_UNIT, &bytepos))
- break;
- aff_combination_const (comb, type, bytepos);
- if (TREE_CODE (core) == MEM_REF)
- {
- tree mem_offset = TREE_OPERAND (core, 1);
- aff_combination_add_cst (comb, wi::to_poly_widest (mem_offset));
- core = TREE_OPERAND (core, 0);
- }
- else
- core = build_fold_addr_expr (core);
-
- if (TREE_CODE (core) == ADDR_EXPR)
- aff_combination_add_elt (comb, core, 1);
- else
- {
- tree_to_aff_combination (core, type, &tmp);
- aff_combination_add (comb, &tmp);
- }
- if (toffset)
- {
- tree_to_aff_combination (toffset, type, &tmp);
- aff_combination_add (comb, &tmp);
- }
- return;
+ return true;
CASE_CONVERT:
{
- tree otype = TREE_TYPE (expr);
- tree inner = TREE_OPERAND (expr, 0);
+ tree otype = type;
+ tree inner = op0;
tree itype = TREE_TYPE (inner);
enum tree_code icode = TREE_CODE (inner);
+ /* STRIP_NOPS */
+ if (tree_nop_conversion_p (otype, itype))
+ {
+ tree_to_aff_combination (op0, type, comb);
+ return true;
+ }
+
/* In principle this is a valid folding, but it isn't necessarily
an optimization, so do it here and not in fold_unary. */
if ((icode == PLUS_EXPR || icode == MINUS_EXPR || icode == MULT_EXPR)
@@ -376,38 +338,127 @@ tree_to_aff_combination (tree expr, tree
{
op0 = fold_convert (otype, op0);
op1 = fold_convert (otype, op1);
- expr = fold_build2 (icode, otype, op0, op1);
- tree_to_aff_combination (expr, type, comb);
- return;
+ return expr_to_aff_combination (comb, icode, otype, op0, op1);
}
wide_int minv, maxv;
/* If inner type has wrapping overflow behavior, fold conversion
for below case:
- (T1)(X - CST) -> (T1)X - (T1)CST
- if X - CST doesn't overflow by range information. Also handle
- (T1)(X + CST) as (T1)(X - (-CST)). */
+ (T1)(X *+- CST) -> (T1)X *+- (T1)CST
+ if X *+- CST doesn't overflow by range information. */
if (TYPE_UNSIGNED (itype)
&& TYPE_OVERFLOW_WRAPS (itype)
- && TREE_CODE (op0) == SSA_NAME
&& TREE_CODE (op1) == INTEGER_CST
- && icode != MULT_EXPR
- && get_range_info (op0, &minv, &maxv) == VR_RANGE)
+ && determine_value_range (op0, &minv, &maxv) == VR_RANGE)
{
+ wi::overflow_type overflow = wi::OVF_NONE;
+ signop sign = UNSIGNED;
if (icode == PLUS_EXPR)
- op1 = wide_int_to_tree (itype, -wi::to_wide (op1));
- if (wi::geu_p (minv, wi::to_wide (op1)))
+ wi::add (maxv, wi::to_wide (op1), sign, &overflow);
+ else if (icode == MULT_EXPR)
+ wi::mul (maxv, wi::to_wide (op1), sign, &overflow);
+ else
+ wi::sub (minv, wi::to_wide (op1), sign, &overflow);
+
+ if (overflow == wi::OVF_NONE)
{
op0 = fold_convert (otype, op0);
op1 = fold_convert (otype, op1);
- expr = fold_build2 (MINUS_EXPR, otype, op0, op1);
- tree_to_aff_combination (expr, type, comb);
- return;
+ return expr_to_aff_combination (comb, icode, otype, op0,
+ op1);
}
}
}
}
break;
+ default:;
+ }
+
+ return false;
+}
+
+/* Splits EXPR into an affine combination of parts. */
+
+void
+tree_to_aff_combination (tree expr, tree type, aff_tree *comb)
+{
+ aff_tree tmp;
+ enum tree_code code;
+ tree core, toffset;
+ poly_int64 bitpos, bitsize, bytepos;
+ machine_mode mode;
+ int unsignedp, reversep, volatilep;
+
+ STRIP_NOPS (expr);
+
+ code = TREE_CODE (expr);
+ switch (code)
+ {
+ case POINTER_PLUS_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ if (expr_to_aff_combination (comb, code, type, TREE_OPERAND (expr, 0),
+ TREE_OPERAND (expr, 1)))
+ return;
+ break;
+
+ case NEGATE_EXPR:
+ case BIT_NOT_EXPR:
+ if (expr_to_aff_combination (comb, code, type, TREE_OPERAND (expr, 0)))
+ return;
+ break;
+
+ CASE_CONVERT:
+ /* ??? TREE_TYPE (expr) should be equal to type here, but IVOPTS
+ calls this with not showing an outer widening cast. */
+ if (expr_to_aff_combination (comb, code,
+ TREE_TYPE (expr), TREE_OPERAND (expr, 0)))
+ {
+ aff_combination_convert (comb, type);
+ return;
+ }
+ break;
+
+ case ADDR_EXPR:
+ /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR. */
+ if (TREE_CODE (TREE_OPERAND (expr, 0)) == MEM_REF)
+ {
+ expr = TREE_OPERAND (expr, 0);
+ tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
+ tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp);
+ aff_combination_add (comb, &tmp);
+ return;
+ }
+ core = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize, &bitpos,
+ &toffset, &mode, &unsignedp, &reversep,
+ &volatilep);
+ if (!multiple_p (bitpos, BITS_PER_UNIT, &bytepos))
+ break;
+ aff_combination_const (comb, type, bytepos);
+ if (TREE_CODE (core) == MEM_REF)
+ {
+ tree mem_offset = TREE_OPERAND (core, 1);
+ aff_combination_add_cst (comb, wi::to_poly_widest (mem_offset));
+ core = TREE_OPERAND (core, 0);
+ }
+ else
+ core = build_fold_addr_expr (core);
+
+ if (TREE_CODE (core) == ADDR_EXPR)
+ aff_combination_add_elt (comb, core, 1);
+ else
+ {
+ tree_to_aff_combination (core, type, &tmp);
+ aff_combination_add (comb, &tmp);
+ }
+ if (toffset)
+ {
+ tree_to_aff_combination (toffset, type, &tmp);
+ aff_combination_add (comb, &tmp);
+ }
+ return;
+
default:
{
if (poly_int_tree_p (expr))
@@ -665,7 +716,7 @@ aff_combination_expand (aff_tree *comb A
{
unsigned i;
aff_tree to_add, current, curre;
- tree e, rhs;
+ tree e;
gimple *def;
widest_int scale;
struct name_expansion *exp;
@@ -715,20 +766,38 @@ aff_combination_expand (aff_tree *comb A
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
+ if (!expr_to_aff_combination (&current, code, TREE_TYPE (name),
+ gimple_assign_rhs1 (def),
+ gimple_assign_rhs2 (def)))
+ continue;
+ break;
case NEGATE_EXPR:
case BIT_NOT_EXPR:
+ if (!expr_to_aff_combination (&current, code, TREE_TYPE (name),
+ gimple_assign_rhs1 (def)))
+ continue;
+ break;
CASE_CONVERT:
- rhs = gimple_assign_rhs_to_tree (def);
+ if (!expr_to_aff_combination (&current, code, TREE_TYPE (name),
+ gimple_assign_rhs1 (def)))
+ /* This makes us always expand conversions which we did
+ in the past and makes gcc.dg/tree-ssa/ivopts-lt-2.c
+ PASS, eliminating one induction variable in IVOPTs.
+ ??? But it is really excessive and we should try
+ harder to do without it. */
+ aff_combination_elt (&current, TREE_TYPE (name),
+ fold_convert (TREE_TYPE (name),
+ gimple_assign_rhs1 (def)));
break;
case ADDR_EXPR:
case INTEGER_CST:
case POLY_INT_CST:
- rhs = gimple_assign_rhs1 (def);
+ tree_to_aff_combination (gimple_assign_rhs1 (def),
+ TREE_TYPE (name), &current);
break;
default:
continue;
}
- tree_to_aff_combination (rhs, TREE_TYPE (name), &current);
exp = XNEW (struct name_expansion);
exp->in_progress = 1;
if (!*cache)

View File

@ -1,82 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-92085-ICE-tree-check-expecte.patch
3c8e341b996546607fa1f39a0fd9a9d7c2c38214
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr92085-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr92085-1.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr92085-1.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr92085-1.c 2020-07-09 11:05:23.136000000 +0800
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fexceptions -fnon-call-exceptions -ftree-loop-vectorize -fno-tree-sink --param dse-max-alias-queries-per-store=2 -w" } */
+
+void
+di (int y9, int qw)
+{
+ if ((int) &y9 != 0)
+ {
+ int py;
+ int **fq = &py;
+
+ while (qw < 1)
+ {
+ if ((0 < (**fq ? **fq : (**fq = 1))) / (**fq = y9))
+ ;
+
+ ++qw;
+ }
+ }
+}
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr92085-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr92085-2.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr92085-2.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr92085-2.c 2020-07-09 11:05:23.136000000 +0800
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -ftree-loop-vectorize -fno-tree-dce -fno-tree-sink -w" } */
+
+int a8;
+
+void
+c1 (int oz, int dk, int ub)
+{
+ int *hd = 0;
+ long int *th = &dk;
+
+ while (ub < 1)
+ {
+ oz || dk;
+ ++ub;
+ }
+
+ while (oz < 2)
+ {
+ long int *lq = &oz;
+
+ (*hd < (*lq = *th)) < oz;
+
+ if (oz == 0)
+ *th = a8 = oz;
+
+ *lq = 0;
+ }
+}
diff -Nurp a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
--- a/gcc/tree-if-conv.c 2020-07-09 11:04:58.832000000 +0800
+++ b/gcc/tree-if-conv.c 2020-07-09 11:05:23.136000000 +0800
@@ -2984,10 +2984,11 @@ ifcvt_local_dce (class loop *loop)
ao_ref write;
ao_ref_init (&write, lhs);
- if (dse_classify_store (&write, stmt, false, NULL, NULL, latch_vdef)
- == DSE_STORE_DEAD)
- delete_dead_or_redundant_assignment (&gsi, "dead");
- gsi_next (&gsi);
+ if (dse_classify_store (&write, stmt, false, NULL, NULL, latch_vdef)
+ == DSE_STORE_DEAD)
+ delete_dead_or_redundant_assignment (&gsi, "dead");
+ else
+ gsi_next (&gsi);
continue;
}

View File

@ -1,70 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-ssa-sccvn.c-copy_reference_ops_from_ref-Adjust-.patch
2f215d2176608467aeee73b245beedfc60836b71
diff -Nurp gcc-9.3.0_org/gcc/tree-ssa-sccvn.c gcc-9.3.0/gcc/tree-ssa-sccvn.c
--- gcc-9.3.0_org/gcc/tree-ssa-sccvn.c 2020-08-18 15:31:39.308000000 +0800
+++ gcc-9.3.0/gcc/tree-ssa-sccvn.c 2020-08-18 15:32:03.456000000 +0800
@@ -797,39 +797,6 @@ vn_reference_eq (const_vn_reference_t co
static void
copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
{
- if (TREE_CODE (ref) == TARGET_MEM_REF)
- {
- vn_reference_op_s temp;
-
- result->reserve (3);
-
- memset (&temp, 0, sizeof (temp));
- temp.type = TREE_TYPE (ref);
- temp.opcode = TREE_CODE (ref);
- temp.op0 = TMR_INDEX (ref);
- temp.op1 = TMR_STEP (ref);
- temp.op2 = TMR_OFFSET (ref);
- temp.off = -1;
- temp.clique = MR_DEPENDENCE_CLIQUE (ref);
- temp.base = MR_DEPENDENCE_BASE (ref);
- result->quick_push (temp);
-
- memset (&temp, 0, sizeof (temp));
- temp.type = NULL_TREE;
- temp.opcode = ERROR_MARK;
- temp.op0 = TMR_INDEX2 (ref);
- temp.off = -1;
- result->quick_push (temp);
-
- memset (&temp, 0, sizeof (temp));
- temp.type = NULL_TREE;
- temp.opcode = TREE_CODE (TMR_BASE (ref));
- temp.op0 = TMR_BASE (ref);
- temp.off = -1;
- result->quick_push (temp);
- return;
- }
-
/* For non-calls, store the information that makes up the address. */
tree orig = ref;
while (ref)
@@ -859,6 +826,20 @@ copy_reference_ops_from_ref (tree ref, v
temp.base = MR_DEPENDENCE_BASE (ref);
temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
break;
+ case TARGET_MEM_REF:
+ /* The base address gets its own vn_reference_op_s structure. */
+ temp.op0 = TMR_INDEX (ref);
+ temp.op1 = TMR_STEP (ref);
+ temp.op2 = TMR_OFFSET (ref);
+ temp.clique = MR_DEPENDENCE_CLIQUE (ref);
+ temp.base = MR_DEPENDENCE_BASE (ref);
+ result->safe_push (temp);
+ memset (&temp, 0, sizeof (temp));
+ temp.type = NULL_TREE;
+ temp.opcode = ERROR_MARK;
+ temp.op0 = TMR_INDEX2 (ref);
+ temp.off = -1;
+ break;
case BIT_FIELD_REF:
/* Record bits, position and storage order. */
temp.op0 = TREE_OPERAND (ref, 1);

View File

@ -1,31 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-ipa-92409-r277920-causes-ICE-in-gcc.dg-cast-fu.patch
e7399b548c866ee2e408e0855b3be794c056fb1d
diff -uprN a/gcc/tree-inline.c b/gcc/tree-inline.c
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -3593,7 +3593,9 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
vs. the call expression. */
if (modify_dest)
caller_type = TREE_TYPE (modify_dest);
- else
+ else if (return_slot)
+ caller_type = TREE_TYPE (return_slot);
+ else /* No LHS on the call. */
caller_type = TREE_TYPE (TREE_TYPE (callee));
/* We don't need to do anything for functions that don't return anything. */
@@ -3634,6 +3636,10 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
&& !DECL_GIMPLE_REG_P (result)
&& DECL_P (var))
DECL_GIMPLE_REG_P (var) = 0;
+
+ if (!useless_type_conversion_p (callee_type, caller_type))
+ var = build1 (VIEW_CONVERT_EXPR, callee_type, var);
+
use = NULL;
goto done;
}

View File

@ -1,79 +0,0 @@
commit ee80f0c6ba50ebf0300fb0cfe1079a1321295749
Author: Richard Biener <rguenther@suse.de>
Date: Thu Oct 24 11:23:54 2019 +0000
re PR tree-optimization/92203 (ICE in eliminate_stmt, at tree-ssa-sccvn.c:5492)
2019-10-24 Richard Biener <rguenther@suse.de>
PR tree-optimization/92203
* treee-ssa-sccvn.c (eliminate_dom_walker::eliminate_stmt):
Skip eliminating conversion stmts inserted by insertion.
* gcc.dg/torture/pr92203.c: New testcase.
From-SVN: r277374
diff --git a/gcc/testsuite/gcc.dg/torture/pr92203.c b/gcc/testsuite/gcc.dg/torture/pr92203.c
new file mode 100644
index 00000000000..c752969d5e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr92203.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-div-by-zero" } */
+
+unsigned long int rr;
+
+void
+cw (int z9)
+{
+ int m5;
+ unsigned long int vz = 0;
+ long int *na;
+
+ if (z9 == 0)
+ rr = 0;
+ else
+ {
+ na = (long int *) &m5;
+ for (*na = 0; *na < 1; ++*na)
+ {
+ na = (long int *) &vz;
+ rr /= 0;
+ }
+ }
+
+ m5 = rr / 5;
+ ++vz;
+ if (vz != 0)
+ while (z9 < 1)
+ {
+ if (m5 >= 0)
+ rr += m5;
+
+ na = (long int *) &rr;
+ if (*na >= 0)
+ rr = 0;
+ }
+}
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 57331ab44dc..3872168a4ed 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -5459,8 +5459,13 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi)
/* If this is an assignment from our leader (which
happens in the case the value-number is a constant)
- then there is nothing to do. */
- if (gimple_assign_single_p (stmt)
+ then there is nothing to do. Likewise if we run into
+ inserted code that needed a conversion because of
+ our type-agnostic value-numbering of loads. */
+ if ((gimple_assign_single_p (stmt)
+ || (is_gimple_assign (stmt)
+ && (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
+ || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)))
&& sprime == gimple_assign_rhs1 (stmt))
return;

View File

@ -1,162 +0,0 @@
This backport contains 2 patchs from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Tweak-gcc.dg-vect-bb-slp-4-01-.c-PR92366.patch
3771033244b3ee1b53a8a00d734580b16384fdd3
0001-tree-vect-slp.c-vect_analyze_slp_instance-Dump-const.patch
140ee00a961fda084c1b4b3f0e7e489a917858f7
diff -Nurp a/gcc/testsuite/gcc.dg/vect/bb-slp-40.c b/gcc/testsuite/gcc.dg/vect/bb-slp-40.c
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-40.c 2020-09-14 21:24:20.899694710 +0800
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-40.c 2020-09-15 20:54:05.456027442 +0800
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -fdump-tree-slp-all" } */
+/* { dg-additional-options "-fvect-cost-model=dynamic" } */
/* { dg-require-effective-target vect_int } */
char g_d[1024], g_s1[1024], g_s2[1024];
@@ -30,5 +30,5 @@ void foo(void)
}
/* See that we vectorize an SLP instance. */
-/* { dg-final { scan-tree-dump-times "Found vectorizable constructor" 1 "slp1" } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp1" } } */
+/* { dg-final { scan-tree-dump "Analyzing vectorizable constructor" "slp1" } } */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "slp1" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/vect/bb-slp-41.c b/gcc/testsuite/gcc.dg/vect/bb-slp-41.c
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-41.c 2020-09-14 21:24:20.899694710 +0800
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-41.c 2020-09-15 20:54:10.424087539 +0800
@@ -1,10 +1,9 @@
-/* { dg-do run } */
-/* { dg-options "-O3 -fdump-tree-slp-all -fno-vect-cost-model" } */
/* { dg-require-effective-target vect_int } */
#define ARR_SIZE 1000
-void foo (int *a, int *b)
+void __attribute__((optimize (0)))
+foo (int *a, int *b)
{
int i;
for (i = 0; i < (ARR_SIZE - 2); ++i)
@@ -56,6 +55,4 @@ int main ()
return 0;
}
-/* See that we vectorize an SLP instance. */
-/* { dg-final { scan-tree-dump-times "Found vectorizable constructor" 12 "slp1" } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "slp1" } } */
+/* { dg-final { scan-tree-dump-not "vectorizing stmts using SLP" "slp1" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/vect/bb-slp-42.c b/gcc/testsuite/gcc.dg/vect/bb-slp-42.c
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-42.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-42.c 2020-09-15 20:54:14.724139555 +0800
@@ -0,0 +1,48 @@
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_perm } */
+
+#include "tree-vect.h"
+
+#define ARR_SIZE 1024
+
+void __attribute__((noipa))
+foo (int a[][ARR_SIZE], int *b)
+{
+ int i;
+ for (i = 0; i < ARR_SIZE; ++i)
+ {
+ a[0][i] += b[0];
+ a[1][i] += b[1];
+ a[2][i] += b[2];
+ a[3][i] += b[3];
+ }
+}
+
+int
+main ()
+{
+ int a[4][ARR_SIZE];
+ int b[4];
+
+ check_vect ();
+
+ for (int i = 0; i < 4; ++i)
+ {
+ b[i] = 20 * i;
+ for (int j = 0; j < ARR_SIZE; ++j)
+ a[i][j] = (i + 1) * ARR_SIZE - j;
+ }
+
+ foo (a, b);
+
+ for (int i = 0; i < 4; ++i)
+ for (int j = 0; j < ARR_SIZE; ++j)
+ if (a[i][j] != (i + 1) * ARR_SIZE - j + 20 * i)
+ __builtin_abort ();
+
+ return 0;
+
+}
+
+/* See that we do not try to vectorize the uniform CTORs. */
+/* { dg-final { scan-tree-dump-not "Analyzing vectorizable constructor" "slp1" } } */
diff -Nurp a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2020-09-14 21:24:20.983695752 +0800
+++ b/gcc/tree-vect-slp.c 2020-09-14 16:13:11.077779069 +0800
@@ -2106,6 +2106,10 @@ vect_analyze_slp_instance (vec_info *vin
else
return false;
}
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Analyzing vectorizable constructor: %G\n",
+ stmt_info->stmt);
}
else
{
@@ -3049,31 +3053,22 @@ vect_slp_check_for_constructors (bb_vec_
gimple_stmt_iterator gsi;
for (gsi = bb_vinfo->region_begin;
- gsi_stmt (gsi) != gsi_stmt (bb_vinfo->region_end); gsi_next (&gsi))
+ gsi_stmt (gsi) != gsi_stmt (bb_vinfo->region_end); gsi_next (&gsi))
{
- gimple *stmt = gsi_stmt (gsi);
-
- if (is_gimple_assign (stmt)
- && gimple_assign_rhs_code (stmt) == CONSTRUCTOR
- && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
- && TREE_CODE (TREE_TYPE (gimple_assign_lhs (stmt))) == VECTOR_TYPE)
- {
- tree rhs = gimple_assign_rhs1 (stmt);
-
- if (CONSTRUCTOR_NELTS (rhs) == 0)
- continue;
-
- poly_uint64 subparts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs));
+ gassign *stmt = dyn_cast <gassign *> (gsi_stmt (gsi));
+ if (!stmt || gimple_assign_rhs_code (stmt) != CONSTRUCTOR)
+ continue;
- if (maybe_ne (subparts, CONSTRUCTOR_NELTS (rhs)))
- continue;
+ tree rhs = gimple_assign_rhs1 (stmt);
+ if (!VECTOR_TYPE_P (TREE_TYPE (rhs))
+ || maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)),
+ CONSTRUCTOR_NELTS (rhs))
+ || VECTOR_TYPE_P (TREE_TYPE (CONSTRUCTOR_ELT (rhs, 0)->value))
+ || uniform_vector_p (rhs))
+ continue;
- if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "Found vectorizable constructor: %G\n", stmt);
- stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (stmt);
- BB_VINFO_GROUPED_STORES (bb_vinfo).safe_push (stmt_info);
- }
+ stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (stmt);
+ BB_VINFO_GROUPED_STORES (bb_vinfo).safe_push (stmt_info);
}
}

View File

@ -1,54 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-92555-ICE-in-exact_div-at-po.patch
f1e0c7e0eb3eafb122fc3d00242828c82a9286a2
diff -Nurp a/gcc/testsuite/gcc.dg/vect/pr92555.c b/gcc/testsuite/gcc.dg/vect/pr92555.c
--- a/gcc/testsuite/gcc.dg/vect/pr92555.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/pr92555.c 2020-08-11 09:36:18.060000000 +0800
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fwrapv" } */
+
+signed char rq;
+
+signed char
+pu (int tr, int al)
+{
+ signed char x8;
+
+ while (tr != 0)
+ {
+ for (x8 = 0; x8 >= 0; x8 += 2)
+ ;
+
+ rq ^= al ^ 1;
+ ++x8;
+ ++tr;
+ }
+
+ return x8;
+}
diff -Nurp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c 2020-08-11 09:35:10.952000000 +0800
+++ b/gcc/tree-vect-loop.c 2020-08-11 09:36:18.064000000 +0800
@@ -1415,6 +1415,18 @@ vect_update_vf_for_slp (loop_vec_info lo
for (i = 0; i < nbbs; i++)
{
basic_block bb = bbs[i];
+ for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
+ gsi_next (&si))
+ {
+ stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (si.phi ());
+ if (!stmt_info)
+ continue;
+ if ((STMT_VINFO_RELEVANT_P (stmt_info)
+ || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info)))
+ && !PURE_SLP_STMT (stmt_info))
+ /* STMT needs both SLP and loop-based vectorization. */
+ only_slp_in_loop = false;
+ }
for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si);
gsi_next (&si))
{

View File

@ -1,207 +0,0 @@
This backport contains 2 patchs from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-AArch64-Improve-SVE-constant-moves.patch
4aeb1ba7f62c1d680c819ae3e137c3bad6f520ca
0002-aarch64-Add-vector-vector-vec_extract-patterns-PR928.patch
c15893df6eafc32efd6184379dd7f02c36da7d12
diff -Nurp a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
--- a/gcc/config/aarch64/aarch64.c 2020-09-03 19:50:00.484000000 +0800
+++ b/gcc/config/aarch64/aarch64.c 2020-09-03 19:50:19.336943210 +0800
@@ -3632,7 +3632,7 @@ aarch64_maybe_expand_sve_subreg_move (rt
attributes. Unlike gen_lowpart, this doesn't care whether the
mode change is valid. */
-static rtx
+rtx
aarch64_replace_reg_mode (rtx x, machine_mode mode)
{
if (GET_MODE (x) == mode)
@@ -15016,6 +15016,36 @@ aarch64_simd_check_vect_par_cnst_half (r
return true;
}
+/* Return a PARALLEL containing NELTS elements, with element I equal
+ to BASE + I * STEP. */
+
+rtx
+aarch64_gen_stepped_int_parallel (unsigned int nelts, int base, int step)
+{
+ rtvec vec = rtvec_alloc (nelts);
+ for (unsigned int i = 0; i < nelts; ++i)
+ RTVEC_ELT (vec, i) = gen_int_mode (base + i * step, DImode);
+ return gen_rtx_PARALLEL (VOIDmode, vec);
+}
+
+/* Return true if OP is a PARALLEL of CONST_INTs that form a linear
+ series with step STEP. */
+
+bool
+aarch64_stepped_int_parallel_p (rtx op, int step)
+{
+ if (GET_CODE (op) != PARALLEL || !CONST_INT_P (XVECEXP (op, 0, 0)))
+ return false;
+
+ unsigned HOST_WIDE_INT base = UINTVAL (XVECEXP (op, 0, 0));
+ for (int i = 1; i < XVECLEN (op, 0); ++i)
+ if (!CONST_INT_P (XVECEXP (op, 0, i))
+ || UINTVAL (XVECEXP (op, 0, i)) != base + i * step)
+ return false;
+
+ return true;
+}
+
/* Bounds-check lanes. Ensure OPERAND lies between LOW (inclusive) and
HIGH (exclusive). */
void
diff -Nurp a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
--- a/gcc/config/aarch64/aarch64-protos.h 2020-09-03 19:50:00.484000000 +0800
+++ b/gcc/config/aarch64/aarch64-protos.h 2020-09-03 19:50:29.137683100 +0800
@@ -501,6 +501,8 @@ bool aarch64_sve_ld1r_operand_p (rtx);
bool aarch64_sve_ldr_operand_p (rtx);
bool aarch64_sve_struct_memory_operand_p (rtx);
rtx aarch64_simd_vect_par_cnst_half (machine_mode, int, bool);
+rtx aarch64_gen_stepped_int_parallel (unsigned int, int, int);
+bool aarch64_stepped_int_parallel_p (rtx, int);
rtx aarch64_tls_get_addr (void);
tree aarch64_fold_builtin (tree, int, tree *, bool);
unsigned aarch64_dbx_register_number (unsigned);
@@ -516,6 +518,7 @@ void aarch64_expand_mov_immediate (rtx,
void aarch64_emit_sve_pred_move (rtx, rtx, rtx);
void aarch64_expand_sve_mem_move (rtx, rtx, machine_mode);
bool aarch64_maybe_expand_sve_subreg_move (rtx, rtx);
+rtx aarch64_replace_reg_mode (rtx, machine_mode);
void aarch64_split_sve_subreg_move (rtx, rtx, rtx);
void aarch64_expand_prologue (void);
void aarch64_expand_vector_init (rtx, rtx);
diff -Nurp a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
--- a/gcc/config/aarch64/aarch64-simd.md 2020-09-03 19:50:00.484000000 +0800
+++ b/gcc/config/aarch64/aarch64-simd.md 2020-09-03 19:50:44.100673150 +0800
@@ -282,37 +282,51 @@
rtx dst_high_part = gen_highpart (<VHALF>mode, dst);
rtx lo = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
rtx hi = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
-
- emit_insn
- (gen_aarch64_simd_mov_from_<mode>low (dst_low_part, src, lo));
- emit_insn
- (gen_aarch64_simd_mov_from_<mode>high (dst_high_part, src, hi));
+ emit_insn (gen_aarch64_get_half<mode> (dst_low_part, src, lo));
+ emit_insn (gen_aarch64_get_half<mode> (dst_high_part, src, hi));
}
DONE;
}
)
-(define_insn "aarch64_simd_mov_from_<mode>low"
- [(set (match_operand:<VHALF> 0 "register_operand" "=r")
+(define_expand "aarch64_get_half<mode>"
+ [(set (match_operand:<VHALF> 0 "register_operand")
(vec_select:<VHALF>
- (match_operand:VQ 1 "register_operand" "w")
- (match_operand:VQ 2 "vect_par_cnst_lo_half" "")))]
- "TARGET_SIMD && reload_completed"
- "umov\t%0, %1.d[0]"
- [(set_attr "type" "neon_to_gp<q>")
- (set_attr "length" "4")
- ])
+ (match_operand:VQ 1 "register_operand")
+ (match_operand 2 "ascending_int_parallel")))]
+ "TARGET_SIMD"
+)
+
+(define_insn_and_split "aarch64_simd_mov_from_<mode>low"
+ [(set (match_operand:<VHALF> 0 "register_operand" "=w,?r")
+ (vec_select:<VHALF>
+ (match_operand:VQ_NO2E 1 "register_operand" "w,w")
+ (match_operand:VQ_NO2E 2 "vect_par_cnst_lo_half" "")))]
+ "TARGET_SIMD"
+ "@
+ #
+ umov\t%0, %1.d[0]"
+ "&& reload_completed && aarch64_simd_register (operands[0], <VHALF>mode)"
+ [(set (match_dup 0) (match_dup 1))]
+ {
+ operands[1] = aarch64_replace_reg_mode (operands[1], <VHALF>mode);
+ }
+ [(set_attr "type" "mov_reg,neon_to_gp<q>")
+ (set_attr "length" "4")]
+)
(define_insn "aarch64_simd_mov_from_<mode>high"
- [(set (match_operand:<VHALF> 0 "register_operand" "=r")
+ [(set (match_operand:<VHALF> 0 "register_operand" "=w,?r")
(vec_select:<VHALF>
- (match_operand:VQ 1 "register_operand" "w")
- (match_operand:VQ 2 "vect_par_cnst_hi_half" "")))]
- "TARGET_SIMD && reload_completed"
- "umov\t%0, %1.d[1]"
- [(set_attr "type" "neon_to_gp<q>")
- (set_attr "length" "4")
- ])
+ (match_operand:VQ_NO2E 1 "register_operand" "w,w")
+ (match_operand:VQ_NO2E 2 "vect_par_cnst_hi_half" "")))]
+ "TARGET_SIMD"
+ "@
+ dup\\t%d0, %1.d[1]
+ umov\t%0, %1.d[1]"
+ [(set_attr "type" "neon_dup<q>,neon_to_gp<q>")
+ (set_attr "length" "4")]
+)
(define_insn "orn<mode>3"
[(set (match_operand:VDQ_I 0 "register_operand" "=w")
@@ -6016,6 +6030,35 @@
DONE;
})
+;; Extract a 64-bit vector from one half of a 128-bit vector.
+(define_expand "vec_extract<mode><Vhalf>"
+ [(match_operand:<VHALF> 0 "register_operand")
+ (match_operand:VQ_NO2E 1 "register_operand")
+ (match_operand 2 "immediate_operand")]
+ "TARGET_SIMD"
+{
+ int start = INTVAL (operands[2]);
+ if (start != 0 && start != <nunits> / 2)
+ FAIL;
+ rtx sel = aarch64_gen_stepped_int_parallel (<nunits> / 2, start, 1);
+ emit_insn (gen_aarch64_get_half<mode> (operands[0], operands[1], sel));
+ DONE;
+})
+
+;; Extract a single-element 64-bit vector from one half of a 128-bit vector.
+(define_expand "vec_extractv2dfv1df"
+ [(match_operand:V1DF 0 "register_operand")
+ (match_operand:V2DF 1 "register_operand")
+ (match_operand 2 "immediate_operand")]
+ "TARGET_SIMD"
+{
+ /* V1DF is rarely used by other patterns, so it should be better to hide
+ it in a subreg destination of a normal DF op. */
+ rtx scalar0 = gen_lowpart (DFmode, operands[0]);
+ emit_insn (gen_vec_extractv2dfdf (scalar0, operands[1], operands[2]));
+ DONE;
+})
+
;; aes
(define_insn "aarch64_crypto_aes<aes_op>v16qi"
diff -Nurp a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
--- a/gcc/config/aarch64/predicates.md 2020-09-03 19:50:00.484000000 +0800
+++ b/gcc/config/aarch64/predicates.md 2020-09-03 19:50:49.315344350 +0800
@@ -438,6 +438,12 @@
return aarch64_simd_check_vect_par_cnst_half (op, mode, false);
})
+(define_predicate "ascending_int_parallel"
+ (match_code "parallel")
+{
+ return aarch64_stepped_int_parallel_p (op, 1);
+})
+
(define_special_predicate "aarch64_simd_lshift_imm"
(match_code "const,const_vector")
{

View File

@ -1,65 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-92512-ICE-in-gimple_op-at-gi.patch
b9f71c51cd578c6ab6ad2986edb80ba48aa477bc
diff -Nurp a/gcc/testsuite/gcc.dg/torture/pr92512.c b/gcc/testsuite/gcc.dg/torture/pr92512.c
--- a/gcc/testsuite/gcc.dg/torture/pr92512.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/torture/pr92512.c 2020-08-10 20:53:50.404000000 +0800
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ftree-vectorize" } */
+
+long int
+nl (long int fy, int k3, int zr)
+{
+ while (k3 < 1)
+ {
+ if (zr == 0)
+ fy = 0;
+
+ fy *= fy < zr;
+ ++k3;
+ }
+
+ return fy;
+}
diff -Nurp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c 2020-08-10 20:53:42.636000000 +0800
+++ b/gcc/tree-vect-loop.c 2020-08-10 20:53:50.404000000 +0800
@@ -2931,9 +2931,11 @@ pop:
/* The following make sure we can compute the operand index
easily plus it mostly disallows chaining via COND_EXPR condition
operands. */
- || (gimple_assign_rhs1 (use_stmt) != op
- && gimple_assign_rhs2 (use_stmt) != op
- && gimple_assign_rhs3 (use_stmt) != op))
+ || (gimple_assign_rhs1_ptr (use_stmt) != path[i].second->use
+ && (gimple_num_ops (use_stmt) <= 2
+ || gimple_assign_rhs2_ptr (use_stmt) != path[i].second->use)
+ && (gimple_num_ops (use_stmt) <= 3
+ || gimple_assign_rhs3_ptr (use_stmt) != path[i].second->use)))
{
fail = true;
break;
@@ -2946,7 +2948,18 @@ pop:
FOR_EACH_IMM_USE_STMT (op_use_stmt, imm_iter, op)
if (!is_gimple_debug (op_use_stmt)
&& flow_bb_inside_loop_p (loop, gimple_bb (op_use_stmt)))
- cnt++;
+ {
+ /* We want to allow x + x but not x < 1 ? x : 2. */
+ if (is_gimple_assign (op_use_stmt)
+ && gimple_assign_rhs_code (op_use_stmt) == COND_EXPR)
+ {
+ use_operand_p use_p;
+ FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
+ cnt++;
+ }
+ else
+ cnt++;
+ }
if (cnt != 1)
{
fail = true;

View File

@ -1,248 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-88828-Inefficient-update-of-.patch
3bc104bdb4b5aa99ff6dceb246beaa65b012c5ac
diff -Nurp a/gcc/testsuite/gcc.target/i386/pr88828-0.c b/gcc/testsuite/gcc.target/i386/pr88828-0.c
--- a/gcc/testsuite/gcc.target/i386/pr88828-0.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.target/i386/pr88828-0.c 2020-08-24 21:08:23.028000000 +0800
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4.2" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+typedef float v4sf __attribute__((vector_size(16)));
+
+v4si foo (v4si x)
+{
+ return (v4si){ x[0], 1, x[2], 3 };
+}
+
+/* { dg-final { scan-assembler "pblendw" } } */
+
+v4si bar (v4sf x)
+{
+ return (v4si){ 1, x[1], x[2], 3 };
+}
+
+/* { dg-final { scan-assembler "cvttps2dq" } } */
+/* { dg-final { scan-assembler "pblendw" } } */
+
+v4si baz (v4si x)
+{
+ return (v4si) { x[1], x[2], x[3], 0 };
+}
+
+/* { dg-final { scan-assembler "psrldq" } } */
diff -Nurp a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
--- a/gcc/tree-ssa-forwprop.c 2020-08-24 21:07:59.800000000 +0800
+++ b/gcc/tree-ssa-forwprop.c 2020-08-24 21:08:23.028000000 +0800
@@ -1997,17 +1997,54 @@ simplify_permutation (gimple_stmt_iterat
return 0;
}
+/* Get the BIT_FIELD_REF definition of VAL, if any, looking through
+ conversions with code CONV_CODE or update it if still ERROR_MARK.
+ Return NULL_TREE if no such matching def was found. */
+
+static tree
+get_bit_field_ref_def (tree val, enum tree_code &conv_code)
+{
+ if (TREE_CODE (val) != SSA_NAME)
+ return NULL_TREE ;
+ gimple *def_stmt = get_prop_source_stmt (val, false, NULL);
+ if (!def_stmt)
+ return NULL_TREE;
+ enum tree_code code = gimple_assign_rhs_code (def_stmt);
+ if (code == FLOAT_EXPR
+ || code == FIX_TRUNC_EXPR)
+ {
+ tree op1 = gimple_assign_rhs1 (def_stmt);
+ if (conv_code == ERROR_MARK)
+ {
+ if (maybe_ne (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (val))),
+ GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op1)))))
+ return NULL_TREE;
+ conv_code = code;
+ }
+ else if (conv_code != code)
+ return NULL_TREE;
+ if (TREE_CODE (op1) != SSA_NAME)
+ return NULL_TREE;
+ def_stmt = SSA_NAME_DEF_STMT (op1);
+ if (! is_gimple_assign (def_stmt))
+ return NULL_TREE;
+ code = gimple_assign_rhs_code (def_stmt);
+ }
+ if (code != BIT_FIELD_REF)
+ return NULL_TREE;
+ return gimple_assign_rhs1 (def_stmt);
+}
+
/* Recognize a VEC_PERM_EXPR. Returns true if there were any changes. */
static bool
simplify_vector_constructor (gimple_stmt_iterator *gsi)
{
gimple *stmt = gsi_stmt (*gsi);
- gimple *def_stmt;
tree op, op2, orig[2], type, elem_type;
unsigned elem_size, i;
unsigned HOST_WIDE_INT nelts;
- enum tree_code code, conv_code;
+ enum tree_code conv_code;
constructor_elt *elt;
bool maybe_ident;
@@ -2027,6 +2064,9 @@ simplify_vector_constructor (gimple_stmt
orig[1] = NULL;
conv_code = ERROR_MARK;
maybe_ident = true;
+ tree one_constant = NULL_TREE;
+ auto_vec<tree> constants;
+ constants.safe_grow_cleared (nelts);
FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt)
{
tree ref, op1;
@@ -2034,68 +2074,57 @@ simplify_vector_constructor (gimple_stmt
if (i >= nelts)
return false;
- if (TREE_CODE (elt->value) != SSA_NAME)
- return false;
- def_stmt = get_prop_source_stmt (elt->value, false, NULL);
- if (!def_stmt)
- return false;
- code = gimple_assign_rhs_code (def_stmt);
- if (code == FLOAT_EXPR
- || code == FIX_TRUNC_EXPR)
+ op1 = get_bit_field_ref_def (elt->value, conv_code);
+ if (op1)
{
- op1 = gimple_assign_rhs1 (def_stmt);
- if (conv_code == ERROR_MARK)
+ ref = TREE_OPERAND (op1, 0);
+ unsigned int j;
+ for (j = 0; j < 2; ++j)
{
- if (maybe_ne (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (elt->value))),
- GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op1)))))
- return false;
- conv_code = code;
+ if (!orig[j])
+ {
+ if (TREE_CODE (ref) != SSA_NAME)
+ return false;
+ if (! VECTOR_TYPE_P (TREE_TYPE (ref))
+ || ! useless_type_conversion_p (TREE_TYPE (op1),
+ TREE_TYPE (TREE_TYPE (ref))))
+ return false;
+ if (j && !useless_type_conversion_p (TREE_TYPE (orig[0]),
+ TREE_TYPE (ref)))
+ return false;
+ orig[j] = ref;
+ break;
+ }
+ else if (ref == orig[j])
+ break;
}
- else if (conv_code != code)
+ if (j == 2)
return false;
- if (TREE_CODE (op1) != SSA_NAME)
- return false;
- def_stmt = SSA_NAME_DEF_STMT (op1);
- if (! is_gimple_assign (def_stmt))
+
+ unsigned int elt;
+ if (maybe_ne (bit_field_size (op1), elem_size)
+ || !constant_multiple_p (bit_field_offset (op1), elem_size, &elt))
return false;
- code = gimple_assign_rhs_code (def_stmt);
+ if (j)
+ elt += nelts;
+ if (elt != i)
+ maybe_ident = false;
+ sel.quick_push (elt);
}
- if (code != BIT_FIELD_REF)
- return false;
- op1 = gimple_assign_rhs1 (def_stmt);
- ref = TREE_OPERAND (op1, 0);
- unsigned int j;
- for (j = 0; j < 2; ++j)
+ else if (CONSTANT_CLASS_P (elt->value))
{
- if (!orig[j])
- {
- if (TREE_CODE (ref) != SSA_NAME)
- return false;
- if (! VECTOR_TYPE_P (TREE_TYPE (ref))
- || ! useless_type_conversion_p (TREE_TYPE (op1),
- TREE_TYPE (TREE_TYPE (ref))))
- return false;
- if (j && !useless_type_conversion_p (TREE_TYPE (orig[0]),
- TREE_TYPE (ref)))
- return false;
- orig[j] = ref;
- break;
- }
- else if (ref == orig[j])
- break;
+ if (orig[1]
+ && orig[1] != error_mark_node)
+ return false;
+ orig[1] = error_mark_node;
+ if (!one_constant)
+ one_constant = elt->value;
+ constants[i] = elt->value;
+ sel.quick_push (i + nelts);
+ maybe_ident = false;
}
- if (j == 2)
- return false;
-
- unsigned int elt;
- if (maybe_ne (bit_field_size (op1), elem_size)
- || !constant_multiple_p (bit_field_offset (op1), elem_size, &elt))
+ else
return false;
- if (j)
- elt += nelts;
- if (elt != i)
- maybe_ident = false;
- sel.quick_push (elt);
}
if (i < nelts)
return false;
@@ -2138,9 +2167,29 @@ simplify_vector_constructor (gimple_stmt
op2 = vec_perm_indices_to_tree (mask_type, indices);
if (!orig[1])
orig[1] = orig[0];
+ if (orig[1] == error_mark_node)
+ {
+ tree_vector_builder vec (type, nelts, 1);
+ for (unsigned i = 0; i < nelts; ++i)
+ if (constants[i])
+ vec.quick_push (constants[i]);
+ else
+ /* ??? Push a don't-care value. */
+ vec.quick_push (one_constant);
+ orig[1] = vec.build ();
+ }
if (conv_code == ERROR_MARK)
gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig[0],
orig[1], op2);
+ else if (TREE_CODE (orig[1]) == VECTOR_CST)
+ {
+ gimple *conv
+ = gimple_build_assign (make_ssa_name (type), conv_code, orig[0]);
+ orig[0] = gimple_assign_lhs (conv);
+ gsi_insert_before (gsi, conv, GSI_SAME_STMT);
+ gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR,
+ orig[0], orig[1], op2);
+ }
else
{
gimple *perm

View File

@ -1,37 +0,0 @@
diff -uprN a/gcc/testsuite/gcc.target/aarch64/sve/slp_fix_1.c b/gcc/testsuite/gcc.target/aarch64/sve/slp_fix_1.c
--- a/gcc/testsuite/gcc.target/aarch64/sve/slp_fix_1.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.target/aarch64/sve/slp_fix_1.c 2020-11-17 02:38:45.284000000 +0800
@@ -0,0 +1,19 @@
+/* { dg-do compiler} */
+/* { dg-options "-O2 -ftree-vectorize -msve-vector-bits=256 -funsafe-math-optimizations" } */
+
+long a, b;
+float c, e;
+float *d;
+void f() {
+ float g, h, i, j;
+ b = 0;
+ for (; b < a; b++) {
+ i = d[0];
+ g = g + i * e;
+ j = d[1];
+ h = h - j * e;
+ d = d + 2;
+ }
+ c = g;
+ e = h;
+}
diff -uprN a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2020-11-16 10:59:36.000000000 +0800
+++ b/gcc/tree-vect-slp.c 2020-11-16 23:30:19.560000000 +0800
@@ -4140,8 +4140,8 @@ vect_schedule_slp_instance (slp_tree nod
gimple *vstmt;
vstmt = gimple_build_assign (make_ssa_name (vectype),
VEC_PERM_EXPR,
- gimple_assign_lhs (v0[j]->stmt),
- gimple_assign_lhs (v1[j]->stmt),
+ gimple_get_lhs (v0[j]->stmt),
+ gimple_get_lhs (v1[j]->stmt),
tmask);
SLP_TREE_VEC_STMTS (node).quick_push
(vect_finish_stmt_generation (stmt_info, vstmt, &si));

View File

@ -1,369 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Remove-gimple_call_types_likely_match_p-PR-70929.patch
7313607478c11e9455a32fb0dbfd7867e04ea96a
diff -uprN a/gcc/auto-profile.c b/gcc/auto-profile.c
--- a/gcc/auto-profile.c 2020-03-31 09:51:52.000000000 +0800
+++ b/gcc/auto-profile.c 2020-07-28 11:15:31.469393370 +0800
@@ -605,8 +605,6 @@ function_instance::find_icall_target_map
get_identifier (afdo_string_table->get_name (callee)));
if (node == NULL)
continue;
- if (!check_ic_target (stmt, node))
- continue;
(*map)[callee] = iter->second->total_count ();
ret += iter->second->total_count ();
}
@@ -1033,7 +1031,7 @@ afdo_indirect_call (gimple_stmt_iterator
print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
}
- if (direct_call == NULL || !check_ic_target (stmt, direct_call))
+ if (direct_call == NULL)
{
if (dump_file)
fprintf (dump_file, " not transforming\n");
diff -uprN a/gcc/cgraph.c b/gcc/cgraph.c
--- a/gcc/cgraph.c 2020-07-28 11:18:05.385393370 +0800
+++ b/gcc/cgraph.c 2020-07-28 11:15:31.469393370 +0800
@@ -876,19 +876,8 @@ symbol_table::create_edge (cgraph_node *
edge->can_throw_external
= call_stmt ? stmt_can_throw_external (DECL_STRUCT_FUNCTION (caller->decl),
call_stmt) : false;
- if (call_stmt
- && callee && callee->decl
- && !gimple_check_call_matching_types (call_stmt, callee->decl,
- false))
- {
- edge->inline_failed = CIF_MISMATCHED_ARGUMENTS;
- edge->call_stmt_cannot_inline_p = true;
- }
- else
- {
- edge->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
- edge->call_stmt_cannot_inline_p = false;
- }
+ edge->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
+ edge->call_stmt_cannot_inline_p = false;
edge->indirect_info = NULL;
edge->indirect_inlining_edge = 0;
@@ -1253,13 +1242,6 @@ cgraph_edge::make_direct (cgraph_node *c
/* Insert to callers list of the new callee. */
edge->set_callee (callee);
- if (call_stmt
- && !gimple_check_call_matching_types (call_stmt, callee->decl, false))
- {
- call_stmt_cannot_inline_p = true;
- inline_failed = CIF_MISMATCHED_ARGUMENTS;
- }
-
/* We need to re-determine the inlining status of the edge. */
initialize_inline_failed (edge);
return edge;
@@ -1288,28 +1270,9 @@ cgraph_edge::redirect_call_stmt_to_calle
substitution), forget about speculating. */
if (decl)
e = e->resolve_speculation (decl);
- /* If types do not match, speculation was likely wrong.
- The direct edge was possibly redirected to the clone with a different
- signature. We did not update the call statement yet, so compare it
- with the reference that still points to the proper type. */
- else if (!gimple_check_call_matching_types (e->call_stmt,
- ref->referred->decl,
- true))
- {
- if (dump_file)
- fprintf (dump_file, "Not expanding speculative call of %s -> %s\n"
- "Type mismatch.\n",
- e->caller->dump_name (),
- e->callee->dump_name ());
- e = e->resolve_speculation ();
- /* We are producing the final function body and will throw away the
- callgraph edges really soon. Reset the counts/frequencies to
- keep verifier happy in the case of roundoff errors. */
- e->count = gimple_bb (e->call_stmt)->count;
- }
- /* Expand speculation into GIMPLE code. */
else
{
+ /* Expand speculation into GIMPLE code. */
if (dump_file)
{
fprintf (dump_file,
@@ -3664,102 +3627,6 @@ cgraph_node::get_fun (void)
return fun;
}
-/* Verify if the type of the argument matches that of the function
- declaration. If we cannot verify this or there is a mismatch,
- return false. */
-
-static bool
-gimple_check_call_args (gimple *stmt, tree fndecl, bool args_count_match)
-{
- tree parms, p;
- unsigned int i, nargs;
-
- /* Calls to internal functions always match their signature. */
- if (gimple_call_internal_p (stmt))
- return true;
-
- nargs = gimple_call_num_args (stmt);
-
- /* Get argument types for verification. */
- if (fndecl)
- parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
- else
- parms = TYPE_ARG_TYPES (gimple_call_fntype (stmt));
-
- /* Verify if the type of the argument matches that of the function
- declaration. If we cannot verify this or there is a mismatch,
- return false. */
- if (fndecl && DECL_ARGUMENTS (fndecl))
- {
- for (i = 0, p = DECL_ARGUMENTS (fndecl);
- i < nargs;
- i++, p = DECL_CHAIN (p))
- {
- tree arg;
- /* We cannot distinguish a varargs function from the case
- of excess parameters, still deferring the inlining decision
- to the callee is possible. */
- if (!p)
- break;
- arg = gimple_call_arg (stmt, i);
- if (p == error_mark_node
- || DECL_ARG_TYPE (p) == error_mark_node
- || arg == error_mark_node
- || (!types_compatible_p (DECL_ARG_TYPE (p), TREE_TYPE (arg))
- && !fold_convertible_p (DECL_ARG_TYPE (p), arg)))
- return false;
- }
- if (args_count_match && p)
- return false;
- }
- else if (parms)
- {
- for (i = 0, p = parms; i < nargs; i++, p = TREE_CHAIN (p))
- {
- tree arg;
- /* If this is a varargs function defer inlining decision
- to callee. */
- if (!p)
- break;
- arg = gimple_call_arg (stmt, i);
- if (TREE_VALUE (p) == error_mark_node
- || arg == error_mark_node
- || TREE_CODE (TREE_VALUE (p)) == VOID_TYPE
- || (!types_compatible_p (TREE_VALUE (p), TREE_TYPE (arg))
- && !fold_convertible_p (TREE_VALUE (p), arg)))
- return false;
- }
- }
- else
- {
- if (nargs != 0)
- return false;
- }
- return true;
-}
-
-/* Verify if the type of the argument and lhs of CALL_STMT matches
- that of the function declaration CALLEE. If ARGS_COUNT_MATCH is
- true, the arg count needs to be the same.
- If we cannot verify this or there is a mismatch, return false. */
-
-bool
-gimple_check_call_matching_types (gimple *call_stmt, tree callee,
- bool args_count_match)
-{
- tree lhs;
-
- if ((DECL_RESULT (callee)
- && !DECL_BY_REFERENCE (DECL_RESULT (callee))
- && (lhs = gimple_call_lhs (call_stmt)) != NULL_TREE
- && !useless_type_conversion_p (TREE_TYPE (DECL_RESULT (callee)),
- TREE_TYPE (lhs))
- && !fold_convertible_p (TREE_TYPE (DECL_RESULT (callee)), lhs))
- || !gimple_check_call_args (call_stmt, callee, args_count_match))
- return false;
- return true;
-}
-
/* Reset all state within cgraph.c so that we can rerun the compiler
within the same process. For use by toplev::finalize. */
diff -uprN a/gcc/cgraph.h b/gcc/cgraph.h
--- a/gcc/cgraph.h 2020-07-28 11:18:04.361393370 +0800
+++ b/gcc/cgraph.h 2020-07-28 11:15:31.469393370 +0800
@@ -2412,8 +2412,6 @@ bool cgraph_function_possibly_inlined_p
const char* cgraph_inline_failed_string (cgraph_inline_failed_t);
cgraph_inline_failed_type_t cgraph_inline_failed_type (cgraph_inline_failed_t);
-extern bool gimple_check_call_matching_types (gimple *, tree, bool);
-
/* In cgraphunit.c */
void cgraphunit_c_finalize (void);
diff -uprN a/gcc/cif-code.def b/gcc/cif-code.def
--- a/gcc/cif-code.def 2020-03-31 09:51:52.000000000 +0800
+++ b/gcc/cif-code.def 2020-07-28 11:15:31.469393370 +0800
@@ -88,10 +88,6 @@ DEFCIFCODE(NOT_DECLARED_INLINED, CIF_FIN
N_("function not declared inline and code size would grow"))
/* Caller and callee disagree on the arguments. */
-DEFCIFCODE(MISMATCHED_ARGUMENTS, CIF_FINAL_ERROR,
- N_("mismatched arguments"))
-
-/* Caller and callee disagree on the arguments. */
DEFCIFCODE(LTO_MISMATCHED_DECLARATIONS, CIF_FINAL_ERROR,
N_("mismatched declarations during linktime optimization"))
diff -uprN a/gcc/ipa-inline.c b/gcc/ipa-inline.c
--- a/gcc/ipa-inline.c 2020-07-28 11:18:04.377393370 +0800
+++ b/gcc/ipa-inline.c 2020-07-28 11:15:31.469393370 +0800
@@ -2844,14 +2844,6 @@ early_inliner (function *fun)
= estimate_num_insns (edge->call_stmt, &eni_size_weights);
es->call_stmt_time
= estimate_num_insns (edge->call_stmt, &eni_time_weights);
-
- if (edge->callee->decl
- && !gimple_check_call_matching_types (
- edge->call_stmt, edge->callee->decl, false))
- {
- edge->inline_failed = CIF_MISMATCHED_ARGUMENTS;
- edge->call_stmt_cannot_inline_p = true;
- }
}
if (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) - 1)
ipa_update_overall_fn_summary (node);
diff -uprN a/gcc/ipa-prop.c b/gcc/ipa-prop.c
--- a/gcc/ipa-prop.c 2020-07-28 11:18:04.377393370 +0800
+++ b/gcc/ipa-prop.c 2020-07-28 11:15:31.469393370 +0800
@@ -3841,11 +3841,6 @@ update_indirect_edges_after_inlining (st
else if (new_direct_edge)
{
new_direct_edge->indirect_inlining_edge = 1;
- if (new_direct_edge->call_stmt)
- new_direct_edge->call_stmt_cannot_inline_p
- = !gimple_check_call_matching_types (
- new_direct_edge->call_stmt,
- new_direct_edge->callee->decl, false);
if (new_edges)
{
new_edges->safe_push (new_direct_edge);
diff -uprN a/gcc/testsuite/gcc.dg/winline-10.c b/gcc/testsuite/gcc.dg/winline-10.c
--- a/gcc/testsuite/gcc.dg/winline-10.c 2020-03-31 09:51:43.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/winline-10.c 2020-07-28 11:15:31.473393370 +0800
@@ -1,9 +1,9 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -Winline" } */
+/* { dg-options "-O2 -Winline -fopt-info-optimized-inline=stderr" } */
struct s { int a; };
-inline void f (x) /* { dg-warning "inlining .* mismatched arg" } */
+inline void f (x)
int x;
{
asm ("");
@@ -11,7 +11,7 @@ inline void f (x) /* { dg-warning "inlin
void g (struct s x)
{
- f (x); /* { dg-message "called from here" } */
+ f (x); /* { dg-optimized "Inlining f.* into g" } */
}
void f (int x); /* { dg-warning "follows non-prototype definition" } */
diff -uprN a/gcc/testsuite/g++.dg/lto/pr70929_0.C b/gcc/testsuite/g++.dg/lto/pr70929_0.C
--- a/gcc/testsuite/g++.dg/lto/pr70929_0.C 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/g++.dg/lto/pr70929_0.C 2020-07-28 11:15:31.469393370 +0800
@@ -0,0 +1,18 @@
+// { dg-lto-do run }
+// { dg-lto-options { "-O3 -flto" } }
+
+struct s
+{
+ int a;
+ s() {a=1;}
+ ~s() {}
+};
+int t(struct s s);
+int main()
+{
+ s s;
+ int v=t(s);
+ if (!__builtin_constant_p (v))
+ __builtin_abort ();
+ return 0;
+}
diff -uprN a/gcc/testsuite/g++.dg/lto/pr70929_1.C b/gcc/testsuite/g++.dg/lto/pr70929_1.C
--- a/gcc/testsuite/g++.dg/lto/pr70929_1.C 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/g++.dg/lto/pr70929_1.C 2020-07-28 11:15:31.473393370 +0800
@@ -0,0 +1,10 @@
+struct s
+{
+ int a;
+ s() {a=1;}
+ ~s() {}
+};
+int t(struct s s)
+{
+ return s.a;
+}
diff -uprN a/gcc/value-prof.c b/gcc/value-prof.c
--- a/gcc/value-prof.c 2020-03-31 09:51:30.000000000 +0800
+++ b/gcc/value-prof.c 2020-07-28 11:17:08.281393370 +0800
@@ -1249,25 +1249,6 @@ find_func_by_profile_id (int profile_id)
return NULL;
}
-/* Perform sanity check on the indirect call target. Due to race conditions,
- false function target may be attributed to an indirect call site. If the
- call expression type mismatches with the target function's type, expand_call
- may ICE. Here we only do very minimal sanity check just to make compiler happy.
- Returns true if TARGET is considered ok for call CALL_STMT. */
-
-bool
-check_ic_target (gcall *call_stmt, struct cgraph_node *target)
-{
- if (gimple_check_call_matching_types (call_stmt, target->decl, true))
- return true;
-
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, call_stmt,
- "Skipping target %s with mismatching types for icall\n",
- target->name ());
- return false;
-}
-
/* Do transformation
if (actual_callee_address == address_of_most_common_function/method)
@@ -1473,21 +1454,6 @@ gimple_ic_transform (gimple_stmt_iterato
return false;
}
- if (!check_ic_target (stmt, direct_call))
- {
- if (dump_file)
- {
- fprintf (dump_file, "Indirect call -> direct call ");
- print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
- fprintf (dump_file, "=> ");
- print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
- fprintf (dump_file, " transformation skipped because of type mismatch");
- print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
- }
- gimple_remove_histogram_value (cfun, stmt, histogram);
- return false;
- }
-
if (dump_file)
{
fprintf (dump_file, "Indirect call -> direct call ");

View File

@ -1,356 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-SLP-SLP-vectorization-vectorize-vector-constructors.patch
818b3293f4545d899148810f4f7d676b81e989dd
diff -N -urp a/gcc/expr.c b/gcc/expr.c
--- a/gcc/expr.c 2020-07-24 11:19:53.840000000 +0800
+++ b/gcc/expr.c 2020-07-24 11:56:50.128000000 +0800
@@ -6788,6 +6788,7 @@ store_constructor (tree exp, rtx target,
&& n_elts.is_constant (&const_n_elts))
{
machine_mode emode = eltmode;
+ bool vector_typed_elts_p = false;
if (CONSTRUCTOR_NELTS (exp)
&& (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value))
@@ -6798,13 +6799,14 @@ store_constructor (tree exp, rtx target,
* TYPE_VECTOR_SUBPARTS (etype),
n_elts));
emode = TYPE_MODE (etype);
+ vector_typed_elts_p = true;
}
icode = convert_optab_handler (vec_init_optab, mode, emode);
if (icode != CODE_FOR_nothing)
{
unsigned int i, n = const_n_elts;
- if (emode != eltmode)
+ if (vector_typed_elts_p)
{
n = CONSTRUCTOR_NELTS (exp);
vec_vec_init_p = true;
diff -N -urp a/gcc/testsuite/gcc.dg/vect/bb-slp-40.c b/gcc/testsuite/gcc.dg/vect/bb-slp-40.c
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-40.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-40.c 2020-07-24 11:56:50.128000000 +0800
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-slp-all" } */
+/* { dg-require-effective-target vect_int } */
+
+char g_d[1024], g_s1[1024], g_s2[1024];
+void foo(void)
+{
+ char *d = g_d, *s1 = g_s1, *s2 = g_s2;
+
+ for ( int y = 0; y < 128; y++ )
+ {
+ d[0 ] = s1[0 ] + s2[0 ];
+ d[1 ] = s1[1 ] + s2[1 ];
+ d[2 ] = s1[2 ] + s2[2 ];
+ d[3 ] = s1[3 ] + s2[3 ];
+ d[4 ] = s1[4 ] + s2[4 ];
+ d[5 ] = s1[5 ] + s2[5 ];
+ d[6 ] = s1[6 ] + s2[6 ];
+ d[7 ] = s1[7 ] + s2[7 ];
+ d[8 ] = s1[8 ] + s2[8 ];
+ d[9 ] = s1[9 ] + s2[9 ];
+ d[10] = s1[10] + s2[10];
+ d[11] = s1[11] + s2[11];
+ d[12] = s1[12] + s2[12];
+ d[13] = s1[13] + s2[13];
+ d[14] = s1[14] + s2[14];
+ d[15] = s1[15] + s2[15];
+ d += 16;
+ }
+}
+
+/* See that we vectorize an SLP instance. */
+/* { dg-final { scan-tree-dump-times "Found vectorizable constructor" 1 "slp1" } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp1" } } */
diff -N -urp a/gcc/testsuite/gcc.dg/vect/bb-slp-41.c b/gcc/testsuite/gcc.dg/vect/bb-slp-41.c
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-41.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-41.c 2020-07-24 11:56:50.128000000 +0800
@@ -0,0 +1,61 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fdump-tree-slp-all -fno-vect-cost-model" } */
+/* { dg-require-effective-target vect_int } */
+
+#define ARR_SIZE 1000
+
+void foo (int *a, int *b)
+{
+ int i;
+ for (i = 0; i < (ARR_SIZE - 2); ++i)
+ a[i] = b[0] + b[1] + b[i+1] + b[i+2];
+}
+
+void bar (int *a, int *b)
+{
+ int i;
+ for (i = 0; i < (ARR_SIZE - 2); ++i)
+ {
+ a[i] = b[0];
+ }
+ for (i = 0; i < (ARR_SIZE - 2); ++i)
+ {
+ a[i] = a[i] + b[1];
+ }
+ for (i = 0; i < (ARR_SIZE - 2); ++i)
+ {
+ a[i] = a[i] + b[i+1];
+ }
+ for (i = 0; i < (ARR_SIZE - 2); ++i)
+ {
+ a[i] = a[i] + b[i+2];
+ }
+}
+
+int main ()
+{
+ int a1[ARR_SIZE];
+ int a2[ARR_SIZE];
+ int b[ARR_SIZE];
+ int i;
+
+ for (i = 0; i < ARR_SIZE; i++)
+ {
+ a1[i] = 0;
+ a2[i] = 0;
+ b[i] = i;
+ }
+
+ foo (a1, b);
+ bar (a2, b);
+
+ for (i = 0; i < ARR_SIZE; i++)
+ if (a1[i] != a2[i])
+ return 1;
+
+ return 0;
+
+}
+/* See that we vectorize an SLP instance. */
+/* { dg-final { scan-tree-dump-times "Found vectorizable constructor" 12 "slp1" } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "slp1" } } */
diff -N -urp a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
--- a/gcc/tree-vectorizer.h 2020-07-24 11:19:51.976000000 +0800
+++ b/gcc/tree-vectorizer.h 2020-07-24 11:56:50.132000000 +0800
@@ -151,6 +151,10 @@ typedef struct _slp_instance {
/* The root of SLP tree. */
slp_tree root;
+ /* For vector constructors, the constructor stmt that the SLP tree is built
+ from, NULL otherwise. */
+ stmt_vec_info root_stmt;
+
/* Size of groups of scalar stmts that will be replaced by SIMD stmt/s. */
unsigned int group_size;
@@ -170,6 +174,7 @@ typedef struct _slp_instance {
#define SLP_INSTANCE_GROUP_SIZE(S) (S)->group_size
#define SLP_INSTANCE_UNROLLING_FACTOR(S) (S)->unrolling_factor
#define SLP_INSTANCE_LOADS(S) (S)->loads
+#define SLP_INSTANCE_ROOT_STMT(S) (S)->root_stmt
#define SLP_TREE_CHILDREN(S) (S)->children
#define SLP_TREE_SCALAR_STMTS(S) (S)->stmts
diff -N -urp a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2020-07-24 11:19:51.980000000 +0800
+++ b/gcc/tree-vect-slp.c 2020-07-24 11:56:50.132000000 +0800
@@ -2019,6 +2019,7 @@ vect_analyze_slp_instance (vec_info *vin
unsigned int i;
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
vec<stmt_vec_info> scalar_stmts;
+ bool constructor = false;
if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
{
@@ -2032,6 +2033,13 @@ vect_analyze_slp_instance (vec_info *vin
vectype = STMT_VINFO_VECTYPE (stmt_info);
group_size = REDUC_GROUP_SIZE (stmt_info);
}
+ else if (is_gimple_assign (stmt_info->stmt)
+ && gimple_assign_rhs_code (stmt_info->stmt) == CONSTRUCTOR)
+ {
+ vectype = TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt));
+ group_size = CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt_info->stmt));
+ constructor = true;
+ }
else
{
gcc_assert (is_a <loop_vec_info> (vinfo));
@@ -2079,6 +2087,25 @@ vect_analyze_slp_instance (vec_info *vin
STMT_VINFO_REDUC_DEF (vect_orig_stmt (stmt_info))
= STMT_VINFO_REDUC_DEF (vect_orig_stmt (scalar_stmts.last ()));
}
+ else if (constructor)
+ {
+ tree rhs = gimple_assign_rhs1 (stmt_info->stmt);
+ tree val;
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
+ {
+ if (TREE_CODE (val) == SSA_NAME)
+ {
+ gimple* def = SSA_NAME_DEF_STMT (val);
+ stmt_vec_info def_info = vinfo->lookup_stmt (def);
+ /* Value is defined in another basic block. */
+ if (!def_info)
+ return false;
+ scalar_stmts.safe_push (def_info);
+ }
+ else
+ return false;
+ }
+ }
else
{
/* Collect reduction statements. */
@@ -2164,6 +2191,8 @@ vect_analyze_slp_instance (vec_info *vin
SLP_INSTANCE_GROUP_SIZE (new_instance) = group_size;
SLP_INSTANCE_UNROLLING_FACTOR (new_instance) = unrolling_factor;
SLP_INSTANCE_LOADS (new_instance) = vNULL;
+ SLP_INSTANCE_ROOT_STMT (new_instance) = constructor ? stmt_info : NULL;
+
vect_gather_slp_loads (new_instance, node);
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
@@ -3032,6 +3061,43 @@ vect_bb_vectorization_profitable_p (bb_v
return true;
}
+/* Find any vectorizable constructors and add them to the grouped_store
+ array. */
+
+static void
+vect_slp_check_for_constructors (bb_vec_info bb_vinfo)
+{
+ gimple_stmt_iterator gsi;
+
+ for (gsi = bb_vinfo->region_begin;
+ gsi_stmt (gsi) != gsi_stmt (bb_vinfo->region_end); gsi_next (&gsi))
+ {
+ gimple *stmt = gsi_stmt (gsi);
+
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == CONSTRUCTOR
+ && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
+ && TREE_CODE (TREE_TYPE (gimple_assign_lhs (stmt))) == VECTOR_TYPE)
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+
+ if (CONSTRUCTOR_NELTS (rhs) == 0)
+ continue;
+
+ poly_uint64 subparts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs));
+
+ if (maybe_ne (subparts, CONSTRUCTOR_NELTS (rhs)))
+ continue;
+
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Found vectorizable constructor: %G\n", stmt);
+ stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (stmt);
+ BB_VINFO_GROUPED_STORES (bb_vinfo).safe_push (stmt_info);
+ }
+ }
+}
+
/* Check if the region described by BB_VINFO can be vectorized, returning
true if so. When returning false, set FATAL to true if the same failure
would prevent vectorization at other vector sizes, false if it is still
@@ -3079,6 +3145,8 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vi
return false;
}
+ vect_slp_check_for_constructors (bb_vinfo);
+
/* If there are no grouped stores in the region there is no need
to continue with pattern recog as vect_analyze_slp will fail
anyway. */
@@ -3135,6 +3203,8 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vi
relevant. */
vect_mark_slp_stmts (SLP_INSTANCE_TREE (instance));
vect_mark_slp_stmts_relevant (SLP_INSTANCE_TREE (instance));
+ if (SLP_INSTANCE_ROOT_STMT (instance))
+ STMT_SLP_TYPE (SLP_INSTANCE_ROOT_STMT (instance)) = pure_slp;
i++;
}
@@ -4175,6 +4245,49 @@ vect_remove_slp_scalar_calls (slp_tree n
vect_remove_slp_scalar_calls (node, visited);
}
+/* Vectorize the instance root. */
+
+void
+vectorize_slp_instance_root_stmt (slp_tree node, slp_instance instance)
+{
+ gassign *rstmt;
+
+ if (SLP_TREE_NUMBER_OF_VEC_STMTS (node) == 1)
+ {
+ stmt_vec_info child_stmt_info;
+ int j;
+
+ FOR_EACH_VEC_ELT (SLP_TREE_VEC_STMTS (node), j, child_stmt_info)
+ {
+ tree vect_lhs = gimple_get_lhs (child_stmt_info->stmt);
+ tree root_lhs = gimple_get_lhs (instance->root_stmt->stmt);
+ rstmt = gimple_build_assign (root_lhs, vect_lhs);
+ break;
+ }
+ }
+ else if (SLP_TREE_NUMBER_OF_VEC_STMTS (node) > 1)
+ {
+ int nelts = SLP_TREE_NUMBER_OF_VEC_STMTS (node);
+ stmt_vec_info child_stmt_info;
+ int j;
+ vec<constructor_elt, va_gc> *v;
+ vec_alloc (v, nelts);
+
+ FOR_EACH_VEC_ELT (SLP_TREE_VEC_STMTS (node), j, child_stmt_info)
+ {
+ CONSTRUCTOR_APPEND_ELT (v,
+ NULL_TREE,
+ gimple_get_lhs (child_stmt_info->stmt));
+ }
+ tree lhs = gimple_get_lhs (instance->root_stmt->stmt);
+ tree rtype = TREE_TYPE (gimple_assign_rhs1 (instance->root_stmt->stmt));
+ tree r_constructor = build_constructor (rtype, v);
+ rstmt = gimple_build_assign (lhs, r_constructor);
+ }
+ gimple_stmt_iterator rgsi = gsi_for_stmt (instance->root_stmt->stmt);
+ gsi_replace (&rgsi, rstmt, true);
+}
+
/* Generate vector code for all SLP instances in the loop/basic block. */
void
@@ -4189,9 +4302,13 @@ vect_schedule_slp (vec_info *vinfo)
slp_instances = vinfo->slp_instances;
FOR_EACH_VEC_ELT (slp_instances, i, instance)
{
+ slp_tree node = SLP_INSTANCE_TREE (instance);
/* Schedule the tree of INSTANCE. */
- vect_schedule_slp_instance (SLP_INSTANCE_TREE (instance),
- instance, bst_map);
+ vect_schedule_slp_instance (node, instance, bst_map);
+
+ if (SLP_INSTANCE_ROOT_STMT (instance))
+ vectorize_slp_instance_root_stmt (node, instance);
+
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"vectorizing stmts using SLP.\n");
@@ -4220,6 +4337,9 @@ vect_schedule_slp (vec_info *vinfo)
if (!STMT_VINFO_DATA_REF (store_info))
break;
+ if (SLP_INSTANCE_ROOT_STMT (instance))
+ continue;
+
store_info = vect_orig_stmt (store_info);
/* Free the attached stmt_vec_info and remove the stmt. */
vinfo->remove_stmt (store_info);

View File

@ -1,93 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-92345-ICE-in-vec-_stmt_vec_i.patch
a6ba623777513e31721030092e4d786f461a0f06
diff -Nurp a/gcc/testsuite/gcc.dg/torture/pr92345.c b/gcc/testsuite/gcc.dg/torture/pr92345.c
--- a/gcc/testsuite/gcc.dg/torture/pr92345.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/torture/pr92345.c 2020-08-10 15:08:19.992000000 +0800
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ftree-vectorize" } */
+
+long int x1;
+int fr;
+
+int
+us (int sk, int jx)
+{
+ while (sk < 1)
+ {
+ jx *= 2;
+ fr += x1 + 1;
+ ++sk;
+ }
+
+ return jx;
+}
diff -Nurp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c 2020-08-10 15:07:44.456000000 +0800
+++ b/gcc/tree-vect-loop.c 2020-08-10 15:08:19.992000000 +0800
@@ -155,7 +155,7 @@ along with GCC; see the file COPYING3.
static void vect_estimate_min_profitable_iters (loop_vec_info, int *, int *);
static stmt_vec_info vect_is_simple_reduction (loop_vec_info, stmt_vec_info,
- bool *);
+ bool *, bool *);
/* Subroutine of vect_determine_vf_for_stmt that handles only one
statement. VECTYPE_MAYBE_SET_P is true if STMT_VINFO_VECTYPE
@@ -489,7 +489,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_i
tree init, step;
auto_vec<stmt_vec_info, 64> worklist;
gphi_iterator gsi;
- bool double_reduc;
+ bool double_reduc, reduc_chain;
DUMP_VECT_SCOPE ("vect_analyze_scalar_cycles");
@@ -561,7 +561,8 @@ vect_analyze_scalar_cycles_1 (loop_vec_i
&& STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_unknown_def_type);
stmt_vec_info reduc_stmt_info
- = vect_is_simple_reduction (loop_vinfo, stmt_vinfo, &double_reduc);
+ = vect_is_simple_reduction (loop_vinfo, stmt_vinfo, &double_reduc,
+ &reduc_chain);
if (reduc_stmt_info)
{
STMT_VINFO_REDUC_DEF (stmt_vinfo) = reduc_stmt_info;
@@ -596,7 +597,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_i
/* Store the reduction cycles for possible vectorization in
loop-aware SLP if it was not detected as reduction
chain. */
- if (! REDUC_GROUP_FIRST_ELEMENT (reduc_stmt_info))
+ if (! reduc_chain)
LOOP_VINFO_REDUCTIONS (loop_vinfo).safe_push
(reduc_stmt_info);
}
@@ -3032,7 +3033,7 @@ check_reduction_path (dump_user_location
static stmt_vec_info
vect_is_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info,
- bool *double_reduc)
+ bool *double_reduc, bool *reduc_chain_p)
{
gphi *phi = as_a <gphi *> (phi_info->stmt);
gimple *phi_use_stmt = NULL;
@@ -3040,6 +3041,7 @@ vect_is_simple_reduction (loop_vec_info
use_operand_p use_p;
*double_reduc = false;
+ *reduc_chain_p = false;
STMT_VINFO_REDUC_TYPE (phi_info) = TREE_CODE_REDUCTION;
tree phi_name = PHI_RESULT (phi);
@@ -3214,6 +3216,7 @@ vect_is_simple_reduction (loop_vec_info
LOOP_VINFO_REDUCTION_CHAINS (loop_info).safe_push (reduc_chain[0]);
REDUC_GROUP_SIZE (reduc_chain[0]) = reduc_chain.length ();
+ *reduc_chain_p = true;
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"reduction: detected reduction chain\n");

File diff suppressed because it is too large Load Diff

View File

@ -1,87 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Don-t-assign-a-cost-to-vectorizable_assignment.patch
e4020b28d02a00d478a3a769855ae6a8d9cc6b26
diff -Nurp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c 2020-07-09 10:42:35.824000000 +0800
+++ b/gcc/tree-vect-loop.c 2020-07-09 10:43:23.920000000 +0800
@@ -1143,7 +1143,9 @@ vect_compute_single_scalar_iteration_cos
else
kind = scalar_store;
}
- else
+ else if (vect_nop_conversion_p (stmt_info))
+ continue;
+ else
kind = scalar_stmt;
record_stmt_cost (&LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo),
diff -Nurp a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
--- a/gcc/tree-vectorizer.h 2020-07-09 10:42:35.824000000 +0800
+++ b/gcc/tree-vectorizer.h 2020-07-09 10:43:23.920000000 +0800
@@ -1645,6 +1645,7 @@ extern tree vect_get_vec_def_for_stmt_co
extern bool vect_transform_stmt (stmt_vec_info, gimple_stmt_iterator *,
slp_tree, slp_instance);
extern void vect_remove_stores (stmt_vec_info);
+extern bool vect_nop_conversion_p (stmt_vec_info);
extern opt_result vect_analyze_stmt (stmt_vec_info, bool *, slp_tree,
slp_instance, stmt_vector_for_cost *);
extern void vect_get_load_cost (stmt_vec_info, int, bool,
diff -Nurp a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2020-07-09 10:42:35.736000000 +0800
+++ b/gcc/tree-vect-slp.c 2020-07-09 10:43:23.920000000 +0800
@@ -2940,6 +2940,8 @@ vect_bb_slp_scalar_cost (basic_block bb,
else
kind = scalar_store;
}
+ else if (vect_nop_conversion_p (stmt_info))
+ continue;
else
kind = scalar_stmt;
record_stmt_cost (cost_vec, 1, kind, stmt_info, 0, vect_body);
diff -Nurp a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
--- a/gcc/tree-vect-stmts.c 2020-07-09 10:42:35.732000000 +0800
+++ b/gcc/tree-vect-stmts.c 2020-07-09 10:43:23.920000000 +0800
@@ -5283,6 +5283,29 @@ vectorizable_conversion (stmt_vec_info s
return true;
}
+/* Return true if we can assume from the scalar form of STMT_INFO that
+ neither the scalar nor the vector forms will generate code. STMT_INFO
+ is known not to involve a data reference. */
+
+bool
+vect_nop_conversion_p (stmt_vec_info stmt_info)
+{
+ gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt);
+ if (!stmt)
+ return false;
+
+ tree lhs = gimple_assign_lhs (stmt);
+ tree_code code = gimple_assign_rhs_code (stmt);
+ tree rhs = gimple_assign_rhs1 (stmt);
+
+ if (code == SSA_NAME || code == VIEW_CONVERT_EXPR)
+ return true;
+
+ if (CONVERT_EXPR_CODE_P (code))
+ return tree_nop_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs));
+
+ return false;
+}
/* Function vectorizable_assignment.
@@ -5398,7 +5421,9 @@ vectorizable_assignment (stmt_vec_info s
{
STMT_VINFO_TYPE (stmt_info) = assignment_vec_info_type;
DUMP_VECT_SCOPE ("vectorizable_assignment");
- vect_model_simple_cost (stmt_info, ncopies, dt, ndts, slp_node, cost_vec);
+ if (!vect_nop_conversion_p (stmt_info))
+ vect_model_simple_cost (stmt_info, ncopies, dt, ndts, slp_node,
+ cost_vec);
return true;
}

View File

@ -1,33 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-92162-ICE-in-vect_create_epi.patch
53b15ca96116544a7a3ca8bc5f4e1649b74f3d45
diff -Nurp gcc-9.3.0_org/gcc/tree-vect-loop.c gcc-9.3.0/gcc/tree-vect-loop.c
--- gcc-9.3.0_org/gcc/tree-vect-loop.c 2020-08-17 10:23:55.768000000 +0800
+++ gcc-9.3.0/gcc/tree-vect-loop.c 2020-08-17 10:27:15.848000000 +0800
@@ -4574,9 +4574,9 @@ vect_create_epilog_for_reduction (stmt_v
(CCOMPARE). The then and else values mirror the main VEC_COND_EXPR:
the reduction phi corresponds to NEW_PHI_TREE and the new values
correspond to INDEX_BEFORE_INCR. */
- gcc_assert (STMT_VINFO_REDUC_IDX (stmt_info) >= 1);
+ gcc_assert (STMT_VINFO_REDUC_IDX (reduc_info) >= 1);
tree index_cond_expr;
- if (STMT_VINFO_REDUC_IDX (stmt_info) == 2)
+ if (STMT_VINFO_REDUC_IDX (reduc_info) == 2)
index_cond_expr = build3 (VEC_COND_EXPR, cr_index_vector_type,
ccompare, indx_before_incr, new_phi_tree);
else
diff -Nurp gcc-9.3.0_org/gcc/tree-vect-stmts.c gcc-9.3.0/gcc/tree-vect-stmts.c
--- gcc-9.3.0_org/gcc/tree-vect-stmts.c 2020-08-17 10:23:53.960000000 +0800
+++ gcc-9.3.0/gcc/tree-vect-stmts.c 2020-08-17 10:27:15.848000000 +0800
@@ -9077,7 +9077,7 @@ vectorizable_condition (stmt_vec_info st
return false;
reduc_info = info_for_reduction (stmt_info);
reduction_type = STMT_VINFO_REDUC_TYPE (reduc_info);
- reduc_index = STMT_VINFO_REDUC_IDX (stmt_info);
+ reduc_index = STMT_VINFO_REDUC_IDX (reduc_info);
gcc_assert (reduction_type != EXTRACT_LAST_REDUCTION
|| reduc_index != -1);
}

View File

@ -1,87 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-92554-ICE-in-vect_create_epi.patch
04c4599d30b1eb7c21d39b15a685aa1d9b8bf968
diff -Nurp a/gcc/testsuite/gcc.dg/vect/pr92554.c b/gcc/testsuite/gcc.dg/vect/pr92554.c
--- a/gcc/testsuite/gcc.dg/vect/pr92554.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/pr92554.c 2020-08-17 11:08:28.424000000 +0800
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+short int w9;
+
+void __attribute__ ((simd))
+zc (int in)
+{
+ int va = 1;
+
+ w9 *= va != 0 ? in < 0 : 0;
+}
diff -Nurp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c 2020-08-17 10:41:56.756000000 +0800
+++ b/gcc/tree-vect-loop.c 2020-08-17 11:09:36.474259880 +0800
@@ -4515,12 +4515,21 @@ vect_create_epilog_for_reduction (stmt_v
zeroes. */
if (STMT_VINFO_REDUC_TYPE (reduc_info) == COND_REDUCTION)
{
- tree indx_before_incr, indx_after_incr;
- poly_uint64 nunits_out = TYPE_VECTOR_SUBPARTS (vectype);
-
- gimple *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info)->stmt;
+ stmt_vec_info cond_info = STMT_VINFO_REDUC_DEF (reduc_info);
+ cond_info = vect_stmt_to_vectorize (cond_info);
+ while (gimple_assign_rhs_code (cond_info->stmt) != COND_EXPR)
+ {
+ cond_info
+ = loop_vinfo->lookup_def (gimple_op (cond_info->stmt,
+ 1 + STMT_VINFO_REDUC_IDX
+ (cond_info)));
+ cond_info = vect_stmt_to_vectorize (cond_info);
+ }
+ gimple *vec_stmt = STMT_VINFO_VEC_STMT (cond_info)->stmt;
gcc_assert (gimple_assign_rhs_code (vec_stmt) == VEC_COND_EXPR);
+ tree indx_before_incr, indx_after_incr;
+ poly_uint64 nunits_out = TYPE_VECTOR_SUBPARTS (vectype);
int scalar_precision
= GET_MODE_PRECISION (SCALAR_TYPE_MODE (TREE_TYPE (vectype)));
tree cr_index_scalar_type = make_unsigned_type (scalar_precision);
@@ -4574,9 +4583,9 @@ vect_create_epilog_for_reduction (stmt_v
(CCOMPARE). The then and else values mirror the main VEC_COND_EXPR:
the reduction phi corresponds to NEW_PHI_TREE and the new values
correspond to INDEX_BEFORE_INCR. */
- gcc_assert (STMT_VINFO_REDUC_IDX (reduc_info) >= 1);
+ gcc_assert (STMT_VINFO_REDUC_IDX (cond_info) >= 1);
tree index_cond_expr;
- if (STMT_VINFO_REDUC_IDX (reduc_info) == 2)
+ if (STMT_VINFO_REDUC_IDX (cond_info) == 2)
index_cond_expr = build3 (VEC_COND_EXPR, cr_index_vector_type,
ccompare, indx_before_incr, new_phi_tree);
else
@@ -4772,10 +4781,11 @@ vect_create_epilog_for_reduction (stmt_v
be zero. */
/* Vector of {0, 0, 0,...}. */
- tree zero_vec = make_ssa_name (vectype);
- tree zero_vec_rhs = build_zero_cst (vectype);
- gimple *zero_vec_stmt = gimple_build_assign (zero_vec, zero_vec_rhs);
- gsi_insert_before (&exit_gsi, zero_vec_stmt, GSI_SAME_STMT);
+ tree zero_vec = build_zero_cst (vectype);
+
+ gimple_seq stmts = NULL;
+ new_phi_result = gimple_convert (&stmts, vectype, new_phi_result);
+ gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT);
/* Find maximum value from the vector of found indexes. */
tree max_index = make_ssa_name (index_scalar_type);
@@ -4843,7 +4853,7 @@ vect_create_epilog_for_reduction (stmt_v
/* Convert the reduced value back to the result type and set as the
result. */
- gimple_seq stmts = NULL;
+ stmts = NULL;
new_temp = gimple_build (&stmts, VIEW_CONVERT_EXPR, scalar_type,
data_reduc);
gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT);

View File

@ -1,54 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-92161-ICE-in-vect_get_vec_de.patch
ae7f3143a3876378d051e64c8e68718f27c41075
diff -Nurp a/gcc/testsuite/gfortran.dg/pr92161.f b/gcc/testsuite/gfortran.dg/pr92161.f
--- a/gcc/testsuite/gfortran.dg/pr92161.f 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gfortran.dg/pr92161.f 2020-08-17 10:18:05.996000000 +0800
@@ -0,0 +1,23 @@
+! { dg-do compile }
+! { dg-options "-O1 -ftree-loop-vectorize -fno-signed-zeros -fno-trapping-math" }
+! { dg-additional-options "-mvsx" { target { powerpc*-*-* } } }
+ COMPLEX FUNCTION R1 (ZR, CC, EA, U6)
+
+ INTEGER ZR, U6, FZ, J2
+ COMPLEX EA(*), CC
+ DOUBLE PRECISION OS, GA, YU, XT
+
+ OS = DBLE(REAL(CC))
+ GA = DBLE(AIMAG(CC))
+ J2 = 1
+
+ DO 5 FZ = 1, ZR
+ YU = DBLE(REAL(EA(J2)))
+ XT = DBLE(AIMAG(EA(J2)))
+ OS = OS + (YU * 2) - (XT * 2)
+ GA = GA + (YU * 3) + (XT * 3)
+ J2 = J2 + U6
+ 5 CONTINUE
+ R1 = CMPLX(REAL(OS), REAL(GA))
+ RETURN
+ END
diff -Nurp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c 2020-08-17 10:17:08.288000000 +0800
+++ b/gcc/tree-vect-loop.c 2020-08-17 10:18:05.996000000 +0800
@@ -2339,6 +2339,17 @@ again:
{
stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si));
STMT_SLP_TYPE (stmt_info) = loop_vect;
+ if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def
+ || STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def)
+ {
+ /* vectorizable_reduction adjusts reduction stmt def-types,
+ restore them to that of the PHI. */
+ STMT_VINFO_DEF_TYPE (STMT_VINFO_REDUC_DEF (stmt_info))
+ = STMT_VINFO_DEF_TYPE (stmt_info);
+ STMT_VINFO_DEF_TYPE (vect_stmt_to_vectorize
+ (STMT_VINFO_REDUC_DEF (stmt_info)))
+ = STMT_VINFO_DEF_TYPE (stmt_info);
+ }
}
for (gimple_stmt_iterator si = gsi_start_bb (bb);
!gsi_end_p (si); gsi_next (&si))

View File

@ -1,381 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-92516-ICE-in-vect_schedule_s.patch
10a73df76280e12886cb20b028727436d73724c5
diff -Nurp a/gcc/testsuite/gcc.dg/vect/vect-ctor-1.c b/gcc/testsuite/gcc.dg/vect/vect-ctor-1.c
--- a/gcc/testsuite/gcc.dg/vect/vect-ctor-1.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/vect-ctor-1.c 2020-08-17 10:33:56.052000000 +0800
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+/* { dg-additional-options "-mavx2" { target { i?86-*-* x86_64-*-* } } } */
+
+typedef struct {
+ unsigned short mprr_2[5][16][16];
+} ImageParameters;
+int s[16][2];
+void intrapred_luma_16x16(ImageParameters *img, int s0)
+{
+ for (int j=0; j < 16; j++)
+ for (int i=0; i < 16; i++)
+ {
+ img->mprr_2[1 ][j][i]=s[j][1];
+ img->mprr_2[2 ][j][i]=s0;
+ }
+}
diff -Nurp a/gcc/testsuite/g++.dg/vect/slp-pr92516.cc b/gcc/testsuite/g++.dg/vect/slp-pr92516.cc
--- a/gcc/testsuite/g++.dg/vect/slp-pr92516.cc 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/g++.dg/vect/slp-pr92516.cc 2020-08-17 10:33:56.052000000 +0800
@@ -0,0 +1,43 @@
+// { dg-do compile }
+// { dg-require-effective-target c++14 }
+
+class a {
+public:
+ typedef int b;
+ operator b();
+};
+class c {
+public:
+ constexpr int m_fn1() const;
+ constexpr int d() const;
+ int e;
+ int f;
+};
+constexpr int c::m_fn1() const { return e; }
+constexpr int c::d() const { return f; }
+class g {
+public:
+ g();
+ constexpr void i(const c &) noexcept;
+ int j;
+ int k;
+ int l;
+ int m;
+};
+constexpr void g::i(const c &n) noexcept {
+ int v = l - j, h = m - k;
+ j = n.m_fn1() - v / 2;
+ k = n.d() - h / 2;
+ l = j + v;
+ m = k + h;
+}
+class o {
+ void m_fn4() const;
+ a p;
+} r;
+void o::m_fn4() const {
+ g q;
+ c t;
+ q.i(t);
+ r.p || 0;
+}
diff -Nurp a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2020-08-17 10:31:58.236000000 +0800
+++ b/gcc/tree-vect-slp.c 2020-08-17 10:36:40.976796520 +0800
@@ -2010,6 +2010,7 @@ calculate_unrolling_factor (poly_uint64
static bool
vect_analyze_slp_instance (vec_info *vinfo,
+ scalar_stmts_to_slp_tree_map_t *bst_map,
stmt_vec_info stmt_info, unsigned max_tree_size)
{
slp_instance new_instance;
@@ -2117,19 +2118,11 @@ vect_analyze_slp_instance (vec_info *vin
/* Build the tree for the SLP instance. */
bool *matches = XALLOCAVEC (bool, group_size);
unsigned npermutes = 0;
- scalar_stmts_to_slp_tree_map_t *bst_map
- = new scalar_stmts_to_slp_tree_map_t ();
poly_uint64 max_nunits = nunits;
unsigned tree_size = 0;
node = vect_build_slp_tree (vinfo, scalar_stmts, group_size,
&max_nunits, matches, &npermutes,
&tree_size, bst_map);
- /* The map keeps a reference on SLP nodes built, release that. */
- for (scalar_stmts_to_slp_tree_map_t::iterator it = bst_map->begin ();
- it != bst_map->end (); ++it)
- if ((*it).second)
- vect_free_slp_tree ((*it).second, false);
- delete bst_map;
if (node != NULL)
{
/* If this is a reduction chain with a conversion in front
@@ -2183,6 +2176,18 @@ vect_analyze_slp_instance (vec_info *vin
matches[group_size / const_max_nunits * const_max_nunits] = false;
vect_free_slp_tree (node, false);
}
+ else if (constructor
+ && SLP_TREE_DEF_TYPE (node) != vect_internal_def)
+ {
+ /* CONSTRUCTOR vectorization relies on a vector stmt being
+ generated, that doesn't work for fully external ones. */
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: CONSTRUCTOR of external "
+ "or constant elements\n");
+ vect_free_slp_tree (node, false);
+ return false;
+ }
else
{
/* Create a new SLP instance. */
@@ -2317,7 +2322,7 @@ vect_analyze_slp_instance (vec_info *vin
stmt_vec_info rest = vect_split_slp_store_group (stmt_info,
group1_size);
- bool res = vect_analyze_slp_instance (vinfo, stmt_info,
+ bool res = vect_analyze_slp_instance (vinfo, bst_map, stmt_info,
max_tree_size);
/* If the first non-match was in the middle of a vector,
skip the rest of that vector. */
@@ -2328,7 +2333,8 @@ vect_analyze_slp_instance (vec_info *vin
rest = vect_split_slp_store_group (rest, const_nunits);
}
if (i < group_size)
- res |= vect_analyze_slp_instance (vinfo, rest, max_tree_size);
+ res |= vect_analyze_slp_instance (vinfo, bst_map,
+ rest, max_tree_size);
return res;
}
/* Even though the first vector did not all match, we might be able to SLP
@@ -2350,9 +2356,12 @@ vect_analyze_slp (vec_info *vinfo, unsig
DUMP_VECT_SCOPE ("vect_analyze_slp");
+ scalar_stmts_to_slp_tree_map_t *bst_map
+ = new scalar_stmts_to_slp_tree_map_t ();
+
/* Find SLP sequences starting from groups of grouped stores. */
FOR_EACH_VEC_ELT (vinfo->grouped_stores, i, first_element)
- vect_analyze_slp_instance (vinfo, first_element, max_tree_size);
+ vect_analyze_slp_instance (vinfo, bst_map, first_element, max_tree_size);
if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
{
@@ -2361,7 +2370,7 @@ vect_analyze_slp (vec_info *vinfo, unsig
{
/* Find SLP sequences starting from reduction chains. */
FOR_EACH_VEC_ELT (loop_vinfo->reduction_chains, i, first_element)
- if (! vect_analyze_slp_instance (vinfo, first_element,
+ if (! vect_analyze_slp_instance (vinfo, bst_map, first_element,
max_tree_size))
{
/* Dissolve reduction chain group. */
@@ -2383,10 +2392,17 @@ vect_analyze_slp (vec_info *vinfo, unsig
/* Find SLP sequences starting from groups of reductions. */
if (loop_vinfo->reductions.length () > 1)
- vect_analyze_slp_instance (vinfo, loop_vinfo->reductions[0],
+ vect_analyze_slp_instance (vinfo, bst_map, loop_vinfo->reductions[0],
max_tree_size);
}
+ /* The map keeps a reference on SLP nodes built, release that. */
+ for (scalar_stmts_to_slp_tree_map_t::iterator it = bst_map->begin ();
+ it != bst_map->end (); ++it)
+ if ((*it).second)
+ vect_free_slp_tree ((*it).second, false);
+ delete bst_map;
+
return opt_result::success ();
}
@@ -2513,13 +2529,6 @@ vect_detect_hybrid_slp_stmts (slp_tree n
vect_detect_hybrid_slp_stmts (child, i, stype, visited);
}
-static void
-vect_detect_hybrid_slp_stmts (slp_tree node, unsigned i, slp_vect_type stype)
-{
- hash_map<slp_tree, unsigned> visited;
- vect_detect_hybrid_slp_stmts (node, i, stype, visited);
-}
-
/* Helpers for vect_detect_hybrid_slp walking pattern stmt uses. */
static tree
@@ -2602,11 +2611,12 @@ vect_detect_hybrid_slp (loop_vec_info lo
/* Then walk the SLP instance trees marking stmts with uses in
non-SLP stmts as hybrid, also propagating hybrid down the
SLP tree, collecting the above info on-the-fly. */
+ hash_map<slp_tree, unsigned> visited;
FOR_EACH_VEC_ELT (slp_instances, i, instance)
{
for (unsigned i = 0; i < SLP_INSTANCE_GROUP_SIZE (instance); ++i)
vect_detect_hybrid_slp_stmts (SLP_INSTANCE_TREE (instance),
- i, pure_slp);
+ i, pure_slp, visited);
}
}
@@ -2763,8 +2773,8 @@ vect_slp_convert_to_external (vec_info *
static bool
vect_slp_analyze_node_operations (vec_info *vinfo, slp_tree node,
slp_instance node_instance,
- scalar_stmts_to_slp_tree_map_t *visited,
- scalar_stmts_to_slp_tree_map_t *lvisited,
+ hash_set<slp_tree> &visited,
+ hash_set<slp_tree> &lvisited,
stmt_vector_for_cost *cost_vec)
{
int i, j;
@@ -2774,27 +2784,13 @@ vect_slp_analyze_node_operations (vec_in
return true;
/* If we already analyzed the exact same set of scalar stmts we're done.
- We share the generated vector stmts for those. */
- slp_tree *leader;
- if ((leader = visited->get (SLP_TREE_SCALAR_STMTS (node)))
- || (leader = lvisited->get (SLP_TREE_SCALAR_STMTS (node))))
- {
- SLP_TREE_NUMBER_OF_VEC_STMTS (node)
- = SLP_TREE_NUMBER_OF_VEC_STMTS (*leader);
- /* Cope with cases in which we made a late decision to build the
- node from scalars. */
- if (SLP_TREE_DEF_TYPE (*leader) == vect_external_def
- && vect_slp_convert_to_external (vinfo, node, node_instance))
- ;
- else
- gcc_assert (SLP_TREE_DEF_TYPE (node) == SLP_TREE_DEF_TYPE (*leader));
- return true;
- }
-
- /* The SLP graph is acyclic so not caching whether we failed or succeeded
+ We share the generated vector stmts for those.
+ The SLP graph is acyclic so not caching whether we failed or succeeded
doesn't result in any issue since we throw away the lvisited set
when we fail. */
- lvisited->put (SLP_TREE_SCALAR_STMTS (node).copy (), node);
+ if (visited.contains (node)
+ || lvisited.add (node))
+ return true;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
if (!vect_slp_analyze_node_operations (vinfo, child, node_instance,
@@ -2867,16 +2863,15 @@ vect_slp_analyze_operations (vec_info *v
DUMP_VECT_SCOPE ("vect_slp_analyze_operations");
- scalar_stmts_to_slp_tree_map_t *visited
- = new scalar_stmts_to_slp_tree_map_t ();
+ hash_set<slp_tree> visited;
for (i = 0; vinfo->slp_instances.iterate (i, &instance); )
{
- scalar_stmts_to_slp_tree_map_t lvisited;
+ hash_set<slp_tree> lvisited;
stmt_vector_for_cost cost_vec;
cost_vec.create (2);
if (!vect_slp_analyze_node_operations (vinfo,
SLP_INSTANCE_TREE (instance),
- instance, visited, &lvisited,
+ instance, visited, lvisited,
&cost_vec))
{
slp_tree node = SLP_INSTANCE_TREE (instance);
@@ -2891,16 +2886,15 @@ vect_slp_analyze_operations (vec_info *v
}
else
{
- for (scalar_stmts_to_slp_tree_map_t::iterator x = lvisited.begin();
+ for (hash_set<slp_tree>::iterator x = lvisited.begin();
x != lvisited.end(); ++x)
- visited->put ((*x).first.copy (), (*x).second);
+ visited.add (*x);
i++;
add_stmt_costs (vinfo->target_cost_data, &cost_vec);
cost_vec.release ();
}
}
- delete visited;
return !vinfo->slp_instances.is_empty ();
}
@@ -2991,15 +2985,6 @@ vect_bb_slp_scalar_cost (basic_block bb,
}
}
-static void
-vect_bb_slp_scalar_cost (basic_block bb,
- slp_tree node, vec<bool, va_heap> *life,
- stmt_vector_for_cost *cost_vec)
-{
- hash_set<slp_tree> visited;
- vect_bb_slp_scalar_cost (bb, node, life, cost_vec, visited);
-}
-
/* Check if vectorization of the basic block is profitable. */
static bool
@@ -3014,13 +2999,14 @@ vect_bb_vectorization_profitable_p (bb_v
/* Calculate scalar cost. */
stmt_vector_for_cost scalar_costs;
scalar_costs.create (0);
+ hash_set<slp_tree> visited;
FOR_EACH_VEC_ELT (slp_instances, i, instance)
{
auto_vec<bool, 20> life;
life.safe_grow_cleared (SLP_INSTANCE_GROUP_SIZE (instance));
vect_bb_slp_scalar_cost (BB_VINFO_BB (bb_vinfo),
SLP_INSTANCE_TREE (instance),
- &life, &scalar_costs);
+ &life, &scalar_costs, visited);
}
void *target_cost_data = init_cost (NULL);
add_stmt_costs (target_cost_data, &scalar_costs);
@@ -4052,8 +4038,7 @@ vect_transform_slp_perm_load (slp_tree n
/* Vectorize SLP instance tree in postorder. */
static void
-vect_schedule_slp_instance (slp_tree node, slp_instance instance,
- scalar_stmts_to_slp_tree_map_t *bst_map)
+vect_schedule_slp_instance (slp_tree node, slp_instance instance)
{
gimple_stmt_iterator si;
stmt_vec_info stmt_info;
@@ -4070,17 +4055,8 @@ vect_schedule_slp_instance (slp_tree nod
if (SLP_TREE_VEC_STMTS (node).exists ())
return;
- /* See if we have already vectorized the same set of stmts and reuse their
- vectorized stmts across instances. */
- if (slp_tree *leader = bst_map->get (SLP_TREE_SCALAR_STMTS (node)))
- {
- SLP_TREE_VEC_STMTS (node).safe_splice (SLP_TREE_VEC_STMTS (*leader));
- return;
- }
-
- bst_map->put (SLP_TREE_SCALAR_STMTS (node).copy (), node);
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
- vect_schedule_slp_instance (child, instance, bst_map);
+ vect_schedule_slp_instance (child, instance);
/* Push SLP node def-type to stmts. */
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
@@ -4297,14 +4273,12 @@ vect_schedule_slp (vec_info *vinfo)
slp_instance instance;
unsigned int i;
- scalar_stmts_to_slp_tree_map_t *bst_map
- = new scalar_stmts_to_slp_tree_map_t ();
slp_instances = vinfo->slp_instances;
FOR_EACH_VEC_ELT (slp_instances, i, instance)
{
slp_tree node = SLP_INSTANCE_TREE (instance);
/* Schedule the tree of INSTANCE. */
- vect_schedule_slp_instance (node, instance, bst_map);
+ vect_schedule_slp_instance (node, instance);
if (SLP_INSTANCE_ROOT_STMT (instance))
vectorize_slp_instance_root_stmt (node, instance);
@@ -4313,7 +4287,6 @@ vect_schedule_slp (vec_info *vinfo)
dump_printf_loc (MSG_NOTE, vect_location,
"vectorizing stmts using SLP.\n");
}
- delete bst_map;
FOR_EACH_VEC_ELT (slp_instances, i, instance)
{

View File

@ -1,47 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-92252-ICE-Segmentation-fault.patch
97c6bea819ec0a773041308e62a7c05c33f093b0
diff -Nurp a/gcc/testsuite/gcc.dg/torture/pr92252.c b/gcc/testsuite/gcc.dg/torture/pr92252.c
--- a/gcc/testsuite/gcc.dg/torture/pr92252.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/torture/pr92252.c 2020-07-03 10:39:44.808000000 +0800
@@ -0,0 +1,23 @@
+/* { do-do compile } */
+/* { dg-additional-options "-ftree-vectorize" } */
+
+long int ar;
+int dt;
+
+long int
+pc (unsigned long int q3, int zw)
+{
+ long int em = 0;
+
+ while (zw < 1)
+ {
+ q3 = zw * 2ul;
+ if (q3 != 0)
+ for (ar = 0; ar < 2; ++ar)
+ em = dt;
+
+ ++zw;
+ }
+
+ return em;
+}
diff -Nurp a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2020-07-03 10:35:59.876000000 +0800
+++ b/gcc/tree-vect-slp.c 2020-07-03 10:39:44.808000000 +0800
@@ -581,6 +581,10 @@ again:
{
swap_ssa_operands (stmt, gimple_assign_rhs2_ptr (stmt),
gimple_assign_rhs3_ptr (stmt));
+ if (STMT_VINFO_REDUC_IDX (stmt_info) == 1)
+ STMT_VINFO_REDUC_IDX (stmt_info) = 2;
+ else if (STMT_VINFO_REDUC_IDX (stmt_info) == 2)
+ STMT_VINFO_REDUC_IDX (stmt_info) = 1;
bool honor_nans = HONOR_NANS (TREE_OPERAND (cond, 0));
code = invert_tree_comparison (TREE_CODE (cond), honor_nans);
gcc_assert (code != ERROR_MARK);

View File

@ -1,96 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-fortran-92094-ice-in-vect_transform_stmt-at-tr.patch
c30587c0200f52f8845a5aea21bd7bef6cbe0bf4
diff -Nurp a/gcc/testsuite/gfortran.dg/pr92094.f90 b/gcc/testsuite/gfortran.dg/pr92094.f90
--- a/gcc/testsuite/gfortran.dg/pr92094.f90 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gfortran.dg/pr92094.f90 2020-08-18 14:25:12.392000000 +0800
@@ -0,0 +1,28 @@
+! { dg-do compile }
+! { dg-options "-O3" }
+ subroutine hesfcn(n, x, h, ldh)
+ integer n,ldh
+ double precision x(n), h(ldh)
+
+ integer i,j,k,kj
+ double precision th,u1,u2,v2
+
+ kj = 0
+ do 770 j = 1, n
+ kj = kj - j
+ do 760 k = 1, j
+ kj = kj + 1
+ v2 = 2 * x(k) - 1
+ u1 = 0
+ u2 = 2
+ do 750 i = 1, n
+ h(kj) = h(kj) + u2
+ th = 4 * v2 + u2 - u1
+ u1 = u2
+ u2 = th
+ th = v2 - 1
+ 750 continue
+ 760 continue
+ 770 continue
+
+ end
diff -Nurp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c 2020-08-18 14:19:43.784000000 +0800
+++ b/gcc/tree-vect-loop.c 2020-08-18 14:25:12.396000000 +0800
@@ -5891,20 +5891,9 @@ vectorizable_reduction (stmt_vec_info st
if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle)
{
if (is_a <gphi *> (stmt_info->stmt))
- {
- /* Analysis for double-reduction is done on the outer
- loop PHI, nested cycles have no further restrictions. */
- STMT_VINFO_TYPE (stmt_info) = cycle_phi_info_type;
- /* For nested cycles we want to let regular vectorizable_*
- routines handle code-generation. */
- if (STMT_VINFO_DEF_TYPE (reduc_info) != vect_double_reduction_def)
- {
- stmt_info = STMT_VINFO_REDUC_DEF (stmt_info);
- STMT_VINFO_DEF_TYPE (stmt_info) = vect_internal_def;
- STMT_VINFO_DEF_TYPE (vect_stmt_to_vectorize (stmt_info))
- = vect_internal_def;
- }
- }
+ /* Analysis for double-reduction is done on the outer
+ loop PHI, nested cycles have no further restrictions. */
+ STMT_VINFO_TYPE (stmt_info) = cycle_phi_info_type;
else
STMT_VINFO_TYPE (stmt_info) = reduc_vec_info_type;
return true;
diff -Nurp a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
--- a/gcc/tree-vect-stmts.c 2020-08-18 14:19:45.556000000 +0800
+++ b/gcc/tree-vect-stmts.c 2020-08-18 14:25:12.396000000 +0800
@@ -10224,13 +10224,16 @@ vect_transform_stmt (stmt_vec_info stmt_
&& STMT_VINFO_REDUC_TYPE (reduc_info) != EXTRACT_LAST_REDUCTION)
{
gphi *phi;
+ edge e;
if (!slp_node
&& (phi = dyn_cast <gphi *>
(STMT_VINFO_REDUC_DEF (orig_stmt_info)->stmt))
&& dominated_by_p (CDI_DOMINATORS,
- gimple_bb (orig_stmt_info->stmt), gimple_bb (phi)))
+ gimple_bb (orig_stmt_info->stmt), gimple_bb (phi))
+ && (e = loop_latch_edge (gimple_bb (phi)->loop_father))
+ && (PHI_ARG_DEF_FROM_EDGE (phi, e)
+ == gimple_get_lhs (orig_stmt_info->stmt)))
{
- edge e = loop_latch_edge (gimple_bb (phi)->loop_father);
stmt_vec_info phi_info
= STMT_VINFO_VEC_STMT (STMT_VINFO_REDUC_DEF (orig_stmt_info));
stmt_vec_info vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
@@ -10250,7 +10253,7 @@ vect_transform_stmt (stmt_vec_info stmt_
{
slp_tree phi_node = slp_node_instance->reduc_phis;
gphi *phi = as_a <gphi *> (SLP_TREE_SCALAR_STMTS (phi_node)[0]->stmt);
- edge e = loop_latch_edge (gimple_bb (phi)->loop_father);
+ e = loop_latch_edge (gimple_bb (phi)->loop_father);
gcc_assert (SLP_TREE_VEC_STMTS (phi_node).length ()
== SLP_TREE_VEC_STMTS (slp_node).length ());
for (unsigned i = 0; i < SLP_TREE_VEC_STMTS (phi_node).length (); ++i)

View File

@ -1,784 +0,0 @@
This backport contains 5 patchs from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
8801ca5c28c3a9e9f36fa39a6a4455b48c8221fa
9ac1403ca2c65ba4f28cf051b5326617fa9298d1
7e99af4816cfad578094fcf08e2377f3ed76e201
ef8777c14ce8694f53eab7a88d24513cbf541ba4
dccbf1e2a6e544f71b4a5795f0c79015db019fc3
diff -Nurp a/gcc/testsuite/gcc.dg/vect/pr92677.c b/gcc/testsuite/gcc.dg/vect/pr92677.c
--- a/gcc/testsuite/gcc.dg/vect/pr92677.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/pr92677.c 2020-10-26 18:31:50.980000000 +0800
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+
+int a, c;
+int *b;
+long d;
+double *e;
+
+void fn1() {
+ long f;
+ double g, h;
+ while (c) {
+ if (d) {
+ g = *e;
+ *(b + 4) = g;
+ }
+ if (f) {
+ h = *(e + 2);
+ *(b + 6) = h;
+ }
+ e += a;
+ b += 8;
+ c--;
+ d += 2;
+ }
+}
diff -Nurp a/gcc/testsuite/gcc.dg/vect/slp-46.c b/gcc/testsuite/gcc.dg/vect/slp-46.c
--- a/gcc/testsuite/gcc.dg/vect/slp-46.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/slp-46.c 2020-10-26 18:31:56.512000000 +0800
@@ -0,0 +1,96 @@
+/* { dg-require-effective-target vect_double } */
+
+#include "tree-vect.h"
+
+double x[1024], y[1024];
+
+void __attribute__((noipa)) foo()
+{
+ for (int i = 0; i < 512; ++i)
+ {
+ x[2*i] = y[i];
+ x[2*i+1] = y[i];
+ }
+}
+
+void __attribute__((noipa)) bar()
+{
+ for (int i = 0; i < 512; ++i)
+ {
+ x[2*i] = y[2*i];
+ x[2*i+1] = y[2*i];
+ }
+}
+
+void __attribute__((noipa)) baz()
+{
+ for (int i = 0; i < 512; ++i)
+ {
+ x[2*i] = y[511-i];
+ x[2*i+1] = y[511-i];
+ }
+}
+
+void __attribute__((noipa)) boo()
+{
+ for (int i = 0; i < 512; ++i)
+ {
+ x[2*i] = y[2*(511-i)];
+ x[2*i+1] = y[2*(511-i)];
+ }
+}
+
+int
+main ()
+{
+ check_vect ();
+
+ for (int i = 0; i < 1024; ++i)
+ {
+ x[i] = 0;
+ y[i] = i;
+ __asm__ volatile ("");
+ }
+
+ foo ();
+ for (int i = 0; i < 1024; ++i)
+ if (x[i] != y[i/2])
+ abort ();
+
+ for (int i = 0; i < 1024; ++i)
+ {
+ x[i] = 0;
+ __asm__ volatile ("");
+ }
+
+ bar ();
+ for (int i = 0; i < 1024; ++i)
+ if (x[i] != y[2*(i/2)])
+ abort ();
+
+ for (int i = 0; i < 1024; ++i)
+ {
+ x[i] = 0;
+ __asm__ volatile ("");
+ }
+
+ baz ();
+ for (int i = 0; i < 1024; ++i)
+ if (x[i] != y[511 - i/2])
+ abort ();
+
+ for (int i = 0; i < 1024; ++i)
+ {
+ x[i] = 0;
+ __asm__ volatile ("");
+ }
+
+ boo ();
+ for (int i = 0; i < 1024; ++i)
+ if (x[i] != y[2*(511 - i/2)])
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/vect/vect-cond-reduc-5.c b/gcc/testsuite/gcc.dg/vect/vect-cond-reduc-5.c
--- a/gcc/testsuite/gcc.dg/vect/vect-cond-reduc-5.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/vect-cond-reduc-5.c 2020-10-26 18:31:53.584000000 +0800
@@ -0,0 +1,36 @@
+#include "tree-vect.h"
+
+#define N 512
+
+int a[N], b[N];
+
+int __attribute__((noipa))
+foo (int aval, int bval)
+{
+ int i, res = 0;
+ for (i=0; i<N; i++)
+ {
+ if (a[i] != 0)
+ res = aval;
+ if (b[i] != 0)
+ res = bval;
+ }
+ return res;
+}
+
+int main()
+{
+ check_vect ();
+ if (foo (1, 2) != 0)
+ abort ();
+ a[3] = 1;
+ b[4] = 1;
+ if (foo (1, 2) != 2)
+ abort ();
+ a[7] = 1;
+ if (foo (1, 2) != 1)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_condition } } } */
diff -Nurp a/gcc/testsuite/g++.dg/pr91221.C b/gcc/testsuite/g++.dg/pr91221.C
--- a/gcc/testsuite/g++.dg/pr91221.C 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/g++.dg/pr91221.C 2020-10-26 18:31:45.768000000 +0800
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-O2 -fno-ipa-pure-const -fpack-struct -Wno-address-of-packed-member" }
+
+void printf(...);
+struct A {
+ A() : bar_(), dbar_() {
+ for (int i;; i++)
+ printf(i, bar_[i]);
+ }
+ int bar_[5];
+ double dbar_[5];
+};
+void fn1() { A a; }
diff -Nurp a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
--- a/gcc/tree-scalar-evolution.c 2020-10-26 18:28:58.720000000 +0800
+++ b/gcc/tree-scalar-evolution.c 2020-10-26 18:31:48.472000000 +0800
@@ -933,8 +933,8 @@ enum t_bool {
};
-static t_bool follow_ssa_edge (struct loop *loop, gimple *, gphi *,
- tree *, int);
+static t_bool follow_ssa_edge_expr (struct loop *loop, gimple *, tree, gphi *,
+ tree *, int);
/* Follow the ssa edge into the binary expression RHS0 CODE RHS1.
Return true if the strongly connected component has been found. */
@@ -969,8 +969,8 @@ follow_ssa_edge_binary (struct loop *loo
(loop->num,
chrec_convert (type, evol, at_stmt),
code, rhs1, at_stmt);
- res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi, &evol, limit);
+ res = follow_ssa_edge_expr
+ (loop, at_stmt, rhs0, halting_phi, &evol, limit);
if (res == t_true)
*evolution_of_loop = evol;
else if (res == t_false)
@@ -979,8 +979,8 @@ follow_ssa_edge_binary (struct loop *loo
(loop->num,
chrec_convert (type, *evolution_of_loop, at_stmt),
code, rhs0, at_stmt);
- res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
+ res = follow_ssa_edge_expr
+ (loop, at_stmt, rhs1, halting_phi,
evolution_of_loop, limit);
if (res == t_true)
;
@@ -1000,8 +1000,8 @@ follow_ssa_edge_binary (struct loop *loo
(loop->num, chrec_convert (type, *evolution_of_loop,
at_stmt),
code, rhs1, at_stmt);
- res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
+ res = follow_ssa_edge_expr
+ (loop, at_stmt, rhs0, halting_phi,
evolution_of_loop, limit);
if (res == t_true)
;
@@ -1018,8 +1018,8 @@ follow_ssa_edge_binary (struct loop *loo
(loop->num, chrec_convert (type, *evolution_of_loop,
at_stmt),
code, rhs0, at_stmt);
- res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
+ res = follow_ssa_edge_expr
+ (loop, at_stmt, rhs1, halting_phi,
evolution_of_loop, limit);
if (res == t_true)
;
@@ -1050,8 +1050,8 @@ follow_ssa_edge_binary (struct loop *loo
*evolution_of_loop = add_to_evolution
(loop->num, chrec_convert (type, *evolution_of_loop, at_stmt),
MINUS_EXPR, rhs1, at_stmt);
- res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
- evolution_of_loop, limit);
+ res = follow_ssa_edge_expr (loop, at_stmt, rhs0, halting_phi,
+ evolution_of_loop, limit);
if (res == t_true)
;
else if (res == t_dont_know)
@@ -1071,140 +1071,6 @@ follow_ssa_edge_binary (struct loop *loo
return res;
}
-/* Follow the ssa edge into the expression EXPR.
- Return true if the strongly connected component has been found. */
-
-static t_bool
-follow_ssa_edge_expr (struct loop *loop, gimple *at_stmt, tree expr,
- gphi *halting_phi, tree *evolution_of_loop,
- int limit)
-{
- enum tree_code code = TREE_CODE (expr);
- tree type = TREE_TYPE (expr), rhs0, rhs1;
- t_bool res;
-
- /* The EXPR is one of the following cases:
- - an SSA_NAME,
- - an INTEGER_CST,
- - a PLUS_EXPR,
- - a POINTER_PLUS_EXPR,
- - a MINUS_EXPR,
- - an ASSERT_EXPR,
- - other cases are not yet handled. */
-
- switch (code)
- {
- CASE_CONVERT:
- /* This assignment is under the form "a_1 = (cast) rhs. */
- res = follow_ssa_edge_expr (loop, at_stmt, TREE_OPERAND (expr, 0),
- halting_phi, evolution_of_loop, limit);
- *evolution_of_loop = chrec_convert (type, *evolution_of_loop, at_stmt);
- break;
-
- case INTEGER_CST:
- /* This assignment is under the form "a_1 = 7". */
- res = t_false;
- break;
-
- case SSA_NAME:
- /* This assignment is under the form: "a_1 = b_2". */
- res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (expr), halting_phi, evolution_of_loop, limit);
- break;
-
- case POINTER_PLUS_EXPR:
- case PLUS_EXPR:
- case MINUS_EXPR:
- /* This case is under the form "rhs0 +- rhs1". */
- rhs0 = TREE_OPERAND (expr, 0);
- rhs1 = TREE_OPERAND (expr, 1);
- type = TREE_TYPE (rhs0);
- STRIP_USELESS_TYPE_CONVERSION (rhs0);
- STRIP_USELESS_TYPE_CONVERSION (rhs1);
- res = follow_ssa_edge_binary (loop, at_stmt, type, rhs0, code, rhs1,
- halting_phi, evolution_of_loop, limit);
- break;
-
- case ADDR_EXPR:
- /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR. */
- if (TREE_CODE (TREE_OPERAND (expr, 0)) == MEM_REF)
- {
- expr = TREE_OPERAND (expr, 0);
- rhs0 = TREE_OPERAND (expr, 0);
- rhs1 = TREE_OPERAND (expr, 1);
- type = TREE_TYPE (rhs0);
- STRIP_USELESS_TYPE_CONVERSION (rhs0);
- STRIP_USELESS_TYPE_CONVERSION (rhs1);
- res = follow_ssa_edge_binary (loop, at_stmt, type,
- rhs0, POINTER_PLUS_EXPR, rhs1,
- halting_phi, evolution_of_loop, limit);
- }
- else
- res = t_false;
- break;
-
- case ASSERT_EXPR:
- /* This assignment is of the form: "a_1 = ASSERT_EXPR <a_2, ...>"
- It must be handled as a copy assignment of the form a_1 = a_2. */
- rhs0 = ASSERT_EXPR_VAR (expr);
- if (TREE_CODE (rhs0) == SSA_NAME)
- res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs0),
- halting_phi, evolution_of_loop, limit);
- else
- res = t_false;
- break;
-
- default:
- res = t_false;
- break;
- }
-
- return res;
-}
-
-/* Follow the ssa edge into the right hand side of an assignment STMT.
- Return true if the strongly connected component has been found. */
-
-static t_bool
-follow_ssa_edge_in_rhs (struct loop *loop, gimple *stmt,
- gphi *halting_phi, tree *evolution_of_loop,
- int limit)
-{
- enum tree_code code = gimple_assign_rhs_code (stmt);
- tree type = gimple_expr_type (stmt), rhs1, rhs2;
- t_bool res;
-
- switch (code)
- {
- CASE_CONVERT:
- /* This assignment is under the form "a_1 = (cast) rhs. */
- res = follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
- halting_phi, evolution_of_loop, limit);
- *evolution_of_loop = chrec_convert (type, *evolution_of_loop, stmt);
- break;
-
- case POINTER_PLUS_EXPR:
- case PLUS_EXPR:
- case MINUS_EXPR:
- rhs1 = gimple_assign_rhs1 (stmt);
- rhs2 = gimple_assign_rhs2 (stmt);
- type = TREE_TYPE (rhs1);
- res = follow_ssa_edge_binary (loop, stmt, type, rhs1, code, rhs2,
- halting_phi, evolution_of_loop, limit);
- break;
-
- default:
- if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
- res = follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
- halting_phi, evolution_of_loop, limit);
- else
- res = t_false;
- break;
- }
-
- return res;
-}
-
/* Checks whether the I-th argument of a PHI comes from a backedge. */
static bool
@@ -1244,8 +1110,8 @@ follow_ssa_edge_in_condition_phi_branch
if (TREE_CODE (branch) == SSA_NAME)
{
*evolution_of_branch = init_cond;
- return follow_ssa_edge (loop, SSA_NAME_DEF_STMT (branch), halting_phi,
- evolution_of_branch, limit);
+ return follow_ssa_edge_expr (loop, condition_phi, branch, halting_phi,
+ evolution_of_branch, limit);
}
/* This case occurs when one of the condition branches sets
@@ -1352,65 +1218,158 @@ follow_ssa_edge_inner_loop_phi (struct l
evolution_of_loop, limit);
}
-/* Follow an SSA edge from a loop-phi-node to itself, constructing a
- path that is analyzed on the return walk. */
+/* Follow the ssa edge into the expression EXPR.
+ Return true if the strongly connected component has been found. */
static t_bool
-follow_ssa_edge (struct loop *loop, gimple *def, gphi *halting_phi,
- tree *evolution_of_loop, int limit)
+follow_ssa_edge_expr (struct loop *loop, gimple *at_stmt, tree expr,
+ gphi *halting_phi, tree *evolution_of_loop,
+ int limit)
{
- struct loop *def_loop;
+ enum tree_code code;
+ tree type, rhs0, rhs1 = NULL_TREE;
- if (gimple_nop_p (def))
- return t_false;
+ /* The EXPR is one of the following cases:
+ - an SSA_NAME,
+ - an INTEGER_CST,
+ - a PLUS_EXPR,
+ - a POINTER_PLUS_EXPR,
+ - a MINUS_EXPR,
+ - an ASSERT_EXPR,
+ - other cases are not yet handled. */
- /* Give up if the path is longer than the MAX that we allow. */
- if (limit > PARAM_VALUE (PARAM_SCEV_MAX_EXPR_COMPLEXITY))
- return t_dont_know;
-
- def_loop = loop_containing_stmt (def);
-
- switch (gimple_code (def))
- {
- case GIMPLE_PHI:
- if (!loop_phi_node_p (def))
- /* DEF is a condition-phi-node. Follow the branches, and
- record their evolutions. Finally, merge the collected
- information and set the approximation to the main
- variable. */
- return follow_ssa_edge_in_condition_phi
- (loop, as_a <gphi *> (def), halting_phi, evolution_of_loop,
- limit);
-
- /* When the analyzed phi is the halting_phi, the
- depth-first search is over: we have found a path from
- the halting_phi to itself in the loop. */
- if (def == halting_phi)
- return t_true;
+ /* For SSA_NAME look at the definition statement, handling
+ PHI nodes and otherwise expand appropriately for the expression
+ handling below. */
+ if (TREE_CODE (expr) == SSA_NAME)
+ {
+ gimple *def = SSA_NAME_DEF_STMT (expr);
- /* Otherwise, the evolution of the HALTING_PHI depends
- on the evolution of another loop-phi-node, i.e. the
- evolution function is a higher degree polynomial. */
- if (def_loop == loop)
+ if (gimple_nop_p (def))
return t_false;
- /* Inner loop. */
- if (flow_loop_nested_p (loop, def_loop))
- return follow_ssa_edge_inner_loop_phi
- (loop, as_a <gphi *> (def), halting_phi, evolution_of_loop,
- limit + 1);
+ /* Give up if the path is longer than the MAX that we allow. */
+ if (limit > PARAM_VALUE (PARAM_SCEV_MAX_EXPR_COMPLEXITY))
+ return t_dont_know;
- /* Outer loop. */
- return t_false;
+ if (gphi *phi = dyn_cast <gphi *>(def))
+ {
+ if (!loop_phi_node_p (phi))
+ /* DEF is a condition-phi-node. Follow the branches, and
+ record their evolutions. Finally, merge the collected
+ information and set the approximation to the main
+ variable. */
+ return follow_ssa_edge_in_condition_phi
+ (loop, phi, halting_phi, evolution_of_loop, limit);
+
+ /* When the analyzed phi is the halting_phi, the
+ depth-first search is over: we have found a path from
+ the halting_phi to itself in the loop. */
+ if (phi == halting_phi)
+ return t_true;
+
+ /* Otherwise, the evolution of the HALTING_PHI depends
+ on the evolution of another loop-phi-node, i.e. the
+ evolution function is a higher degree polynomial. */
+ class loop *def_loop = loop_containing_stmt (def);
+ if (def_loop == loop)
+ return t_false;
+
+ /* Inner loop. */
+ if (flow_loop_nested_p (loop, def_loop))
+ return follow_ssa_edge_inner_loop_phi
+ (loop, phi, halting_phi, evolution_of_loop,
+ limit + 1);
- case GIMPLE_ASSIGN:
- return follow_ssa_edge_in_rhs (loop, def, halting_phi,
- evolution_of_loop, limit);
+ /* Outer loop. */
+ return t_false;
+ }
- default:
/* At this level of abstraction, the program is just a set
of GIMPLE_ASSIGNs and PHI_NODEs. In principle there is no
- other node to be handled. */
+ other def to be handled. */
+ if (!is_gimple_assign (def))
+ return t_false;
+
+ code = gimple_assign_rhs_code (def);
+ switch (get_gimple_rhs_class (code))
+ {
+ case GIMPLE_BINARY_RHS:
+ rhs0 = gimple_assign_rhs1 (def);
+ rhs1 = gimple_assign_rhs2 (def);
+ break;
+ case GIMPLE_UNARY_RHS:
+ case GIMPLE_SINGLE_RHS:
+ rhs0 = gimple_assign_rhs1 (def);
+ break;
+ default:
+ return t_false;
+ }
+ type = TREE_TYPE (gimple_assign_lhs (def));
+ at_stmt = def;
+ }
+ else
+ {
+ code = TREE_CODE (expr);
+ type = TREE_TYPE (expr);
+ switch (code)
+ {
+ CASE_CONVERT:
+ rhs0 = TREE_OPERAND (expr, 0);
+ break;
+ case POINTER_PLUS_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ rhs0 = TREE_OPERAND (expr, 0);
+ rhs1 = TREE_OPERAND (expr, 1);
+ break;
+ default:
+ rhs0 = expr;
+ }
+ }
+
+ switch (code)
+ {
+ CASE_CONVERT:
+ {
+ /* This assignment is under the form "a_1 = (cast) rhs. */
+ t_bool res = follow_ssa_edge_expr (loop, at_stmt, rhs0, halting_phi,
+ evolution_of_loop, limit);
+ *evolution_of_loop = chrec_convert (type, *evolution_of_loop, at_stmt);
+ return res;
+ }
+
+ case INTEGER_CST:
+ /* This assignment is under the form "a_1 = 7". */
+ return t_false;
+
+ case ADDR_EXPR:
+ {
+ /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR. */
+ if (TREE_CODE (TREE_OPERAND (rhs0, 0)) != MEM_REF)
+ return t_false;
+ tree mem = TREE_OPERAND (rhs0, 0);
+ rhs0 = TREE_OPERAND (mem, 0);
+ rhs1 = TREE_OPERAND (mem, 1);
+ code = POINTER_PLUS_EXPR;
+ }
+ /* Fallthru. */
+ case POINTER_PLUS_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ /* This case is under the form "rhs0 +- rhs1". */
+ STRIP_USELESS_TYPE_CONVERSION (rhs0);
+ STRIP_USELESS_TYPE_CONVERSION (rhs1);
+ return follow_ssa_edge_binary (loop, at_stmt, type, rhs0, code, rhs1,
+ halting_phi, evolution_of_loop, limit);
+
+ case ASSERT_EXPR:
+ /* This assignment is of the form: "a_1 = ASSERT_EXPR <a_2, ...>"
+ It must be handled as a copy assignment of the form a_1 = a_2. */
+ return follow_ssa_edge_expr (loop, at_stmt, ASSERT_EXPR_VAR (rhs0),
+ halting_phi, evolution_of_loop, limit);
+
+ default:
return t_false;
}
}
@@ -1504,7 +1463,6 @@ analyze_evolution_in_loop (gphi *loop_ph
for (i = 0; i < n; i++)
{
tree arg = PHI_ARG_DEF (loop_phi_node, i);
- gimple *ssa_chain;
tree ev_fn;
t_bool res;
@@ -1517,11 +1475,10 @@ analyze_evolution_in_loop (gphi *loop_ph
{
bool val = false;
- ssa_chain = SSA_NAME_DEF_STMT (arg);
-
/* Pass in the initial condition to the follow edge function. */
ev_fn = init_cond;
- res = follow_ssa_edge (loop, ssa_chain, loop_phi_node, &ev_fn, 0);
+ res = follow_ssa_edge_expr (loop, loop_phi_node, arg,
+ loop_phi_node, &ev_fn, 0);
/* If ev_fn has no evolution in the inner loop, and the
init_cond is not equal to ev_fn, then we have an
diff -Nurp a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
--- a/gcc/tree-ssa-sccvn.c 2020-10-26 18:28:58.736000000 +0800
+++ b/gcc/tree-ssa-sccvn.c 2020-10-26 18:31:45.768000000 +0800
@@ -2456,7 +2456,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree
(vuse, vr->set, vr->type, vr->operands, val);
}
/* For now handle clearing memory with partial defs. */
- else if (integer_zerop (gimple_call_arg (def_stmt, 1))
+ else if (known_eq (ref->size, maxsize)
+ && integer_zerop (gimple_call_arg (def_stmt, 1))
&& tree_to_poly_int64 (len).is_constant (&leni)
&& offset.is_constant (&offseti)
&& offset2.is_constant (&offset2i)
@@ -2494,7 +2495,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree
return vn_reference_lookup_or_insert_for_pieces
(vuse, vr->set, vr->type, vr->operands, val);
}
- else if (maxsize.is_constant (&maxsizei)
+ else if (known_eq (ref->size, maxsize)
+ && maxsize.is_constant (&maxsizei)
&& maxsizei % BITS_PER_UNIT == 0
&& offset.is_constant (&offseti)
&& offseti % BITS_PER_UNIT == 0
diff -Nurp a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
--- a/gcc/tree-vect-data-refs.c 2020-10-26 18:28:58.792000000 +0800
+++ b/gcc/tree-vect-data-refs.c 2020-10-26 18:31:56.512000000 +0800
@@ -1045,7 +1045,7 @@ vect_compute_data_ref_alignment (dr_vec_
if (tree_int_cst_sgn (drb->step) < 0)
/* PLUS because STEP is negative. */
misalignment += ((TYPE_VECTOR_SUBPARTS (vectype) - 1)
- * TREE_INT_CST_LOW (drb->step));
+ * -TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (vectype))));
unsigned int const_misalignment;
if (!known_misalignment (misalignment, vect_align_c, &const_misalignment))
diff -Nurp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c 2020-10-26 18:28:58.728000000 +0800
+++ b/gcc/tree-vect-loop.c 2020-10-26 18:31:53.584000000 +0800
@@ -1850,7 +1850,10 @@ vect_dissolve_slp_only_groups (loop_vec_
DR_GROUP_FIRST_ELEMENT (vinfo) = vinfo;
DR_GROUP_NEXT_ELEMENT (vinfo) = NULL;
DR_GROUP_SIZE (vinfo) = 1;
- DR_GROUP_GAP (vinfo) = group_size - 1;
+ if (STMT_VINFO_STRIDED_P (first_element))
+ DR_GROUP_GAP (vinfo) = 0;
+ else
+ DR_GROUP_GAP (vinfo) = group_size - 1;
vinfo = next;
}
}
@@ -4516,18 +4519,26 @@ vect_create_epilog_for_reduction (stmt_v
zeroes. */
if (STMT_VINFO_REDUC_TYPE (reduc_info) == COND_REDUCTION)
{
+ auto_vec<std::pair<tree, bool>, 2> ccompares;
stmt_vec_info cond_info = STMT_VINFO_REDUC_DEF (reduc_info);
cond_info = vect_stmt_to_vectorize (cond_info);
- while (gimple_assign_rhs_code (cond_info->stmt) != COND_EXPR)
+ while (cond_info != reduc_info)
{
+ if (gimple_assign_rhs_code (cond_info->stmt) == COND_EXPR)
+ {
+ gimple *vec_stmt = STMT_VINFO_VEC_STMT (cond_info)->stmt;
+ gcc_assert (gimple_assign_rhs_code (vec_stmt) == VEC_COND_EXPR);
+ ccompares.safe_push
+ (std::make_pair (unshare_expr (gimple_assign_rhs1 (vec_stmt)),
+ STMT_VINFO_REDUC_IDX (cond_info) == 2));
+ }
cond_info
= loop_vinfo->lookup_def (gimple_op (cond_info->stmt,
1 + STMT_VINFO_REDUC_IDX
(cond_info)));
cond_info = vect_stmt_to_vectorize (cond_info);
}
- gimple *vec_stmt = STMT_VINFO_VEC_STMT (cond_info)->stmt;
- gcc_assert (gimple_assign_rhs_code (vec_stmt) == VEC_COND_EXPR);
+ gcc_assert (ccompares.length () != 0);
tree indx_before_incr, indx_after_incr;
poly_uint64 nunits_out = TYPE_VECTOR_SUBPARTS (vectype);
@@ -4569,37 +4580,35 @@ vect_create_epilog_for_reduction (stmt_v
add_phi_arg (as_a <gphi *> (new_phi), vec_zero,
loop_preheader_edge (loop), UNKNOWN_LOCATION);
- /* Now take the condition from the loops original cond_expr
- (VEC_STMT) and produce a new cond_expr (INDEX_COND_EXPR) which for
+ /* Now take the condition from the loops original cond_exprs
+ and produce a new cond_exprs (INDEX_COND_EXPR) which for
every match uses values from the induction variable
(INDEX_BEFORE_INCR) otherwise uses values from the phi node
(NEW_PHI_TREE).
Finally, we update the phi (NEW_PHI_TREE) to take the value of
the new cond_expr (INDEX_COND_EXPR). */
-
- /* Duplicate the condition from vec_stmt. */
- tree ccompare = unshare_expr (gimple_assign_rhs1 (vec_stmt));
-
- /* Create a conditional, where the condition is taken from vec_stmt
- (CCOMPARE). The then and else values mirror the main VEC_COND_EXPR:
- the reduction phi corresponds to NEW_PHI_TREE and the new values
- correspond to INDEX_BEFORE_INCR. */
- gcc_assert (STMT_VINFO_REDUC_IDX (cond_info) >= 1);
- tree index_cond_expr;
- if (STMT_VINFO_REDUC_IDX (cond_info) == 2)
- index_cond_expr = build3 (VEC_COND_EXPR, cr_index_vector_type,
- ccompare, indx_before_incr, new_phi_tree);
- else
- index_cond_expr = build3 (VEC_COND_EXPR, cr_index_vector_type,
- ccompare, new_phi_tree, indx_before_incr);
- induction_index = make_ssa_name (cr_index_vector_type);
- gimple *index_condition = gimple_build_assign (induction_index,
- index_cond_expr);
- gsi_insert_before (&incr_gsi, index_condition, GSI_SAME_STMT);
- stmt_vec_info index_vec_info = loop_vinfo->add_stmt (index_condition);
+ gimple_seq stmts = NULL;
+ for (int i = ccompares.length () - 1; i != -1; --i)
+ {
+ tree ccompare = ccompares[i].first;
+ if (ccompares[i].second)
+ new_phi_tree = gimple_build (&stmts, VEC_COND_EXPR,
+ cr_index_vector_type,
+ ccompare,
+ indx_before_incr, new_phi_tree);
+ else
+ new_phi_tree = gimple_build (&stmts, VEC_COND_EXPR,
+ cr_index_vector_type,
+ ccompare,
+ new_phi_tree, indx_before_incr);
+ }
+ gsi_insert_seq_before (&incr_gsi, stmts, GSI_SAME_STMT);
+ stmt_vec_info index_vec_info
+ = loop_vinfo->add_stmt (SSA_NAME_DEF_STMT (new_phi_tree));
STMT_VINFO_VECTYPE (index_vec_info) = cr_index_vector_type;
/* Update the phi with the vec cond. */
+ induction_index = new_phi_tree;
add_phi_arg (as_a <gphi *> (new_phi), induction_index,
loop_latch_edge (loop), UNKNOWN_LOCATION);
}

View File

@ -1,71 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-vect-ICE-in-vectorizable_load-at-tree-vect-stmts.c-9.patch:
f14b41d27124601284347a10d496362c8b4b8e1c
diff -Nurp a/gcc/testsuite/gcc.target/aarch64/pr94398.c b/gcc/testsuite/gcc.target/aarch64/pr94398.c
--- a/gcc/testsuite/gcc.target/aarch64/pr94398.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.target/aarch64/pr94398.c 2020-04-17 17:15:58.176000000 +0800
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-vectorize -funsafe-math-optimizations -march=armv8.2-a+sve -mstrict-align" } */
+
+float
+foo(long n, float *x, int inc_x,
+ float *y, int inc_y)
+{
+ float dot = 0.0;
+ int ix = 0, iy = 0;
+
+ if (n < 0) {
+ return dot;
+ }
+
+ int i = 0;
+ while (i < n) {
+ dot += y[iy] * x[ix];
+ ix += inc_x;
+ iy += inc_y;
+ i++;
+ }
+
+ return dot;
+}
diff -Nurp a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
--- a/gcc/tree-vect-stmts.c 2020-04-17 17:10:14.796000000 +0800
+++ b/gcc/tree-vect-stmts.c 2020-04-17 17:15:08.611850850 +0800
@@ -7025,8 +7025,14 @@ vectorizable_store (stmt_vec_info stmt_i
auto_vec<tree> dr_chain (group_size);
oprnds.create (group_size);
- alignment_support_scheme
- = vect_supportable_dr_alignment (first_dr_info, false);
+ /* Gather-scatter accesses perform only component accesses, alignment
+ is irrelevant for them. */
+ if (memory_access_type == VMAT_GATHER_SCATTER)
+ alignment_support_scheme = dr_unaligned_supported;
+ else
+ alignment_support_scheme
+ = vect_supportable_dr_alignment (first_dr_info, false);
+
gcc_assert (alignment_support_scheme);
vec_loop_masks *loop_masks
= (loop_vinfo && LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)
@@ -8162,8 +8168,14 @@ vectorizable_load (stmt_vec_info stmt_in
ref_type = reference_alias_ptr_type (DR_REF (first_dr_info->dr));
}
- alignment_support_scheme
- = vect_supportable_dr_alignment (first_dr_info, false);
+ /* Gather-scatter accesses perform only component accesses, alignment
+ is irrelevant for them. */
+ if (memory_access_type == VMAT_GATHER_SCATTER)
+ alignment_support_scheme = dr_unaligned_supported;
+ else
+ alignment_support_scheme
+ = vect_supportable_dr_alignment (first_dr_info, false);
+
gcc_assert (alignment_support_scheme);
vec_loop_masks *loop_masks
= (loop_vinfo && LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)

View File

@ -1,18 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Fix-reduc_index-calculation-in-vectorizable_conditio.patch
1d149b7260bcc4c0c6367b3aea47a8b91a1cf345
diff -Nurp a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
--- a/gcc/tree-vect-stmts.c 2020-08-18 19:35:06.352000000 +0800
+++ b/gcc/tree-vect-stmts.c 2020-08-18 19:35:20.792000000 +0800
@@ -9077,7 +9077,7 @@ vectorizable_condition (stmt_vec_info st
return false;
reduc_info = info_for_reduction (stmt_info);
reduction_type = STMT_VINFO_REDUC_TYPE (reduc_info);
- reduc_index = STMT_VINFO_REDUC_IDX (reduc_info);
+ reduc_index = STMT_VINFO_REDUC_IDX (stmt_info);
gcc_assert (reduction_type != EXTRACT_LAST_REDUCTION
|| reduc_index != -1);
}

View File

@ -1,47 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-92461-ICE-verify_ssa-failed-.patch
830d1b18526dd1f085e8a2e1467a6dde18fc6434
diff -Nurp a/gcc/testsuite/gcc.dg/torture/pr92461.c b/gcc/testsuite/gcc.dg/torture/pr92461.c
--- a/gcc/testsuite/gcc.dg/torture/pr92461.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/torture/pr92461.c 2020-07-28 19:48:09.324000000 +0800
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ftree-vectorize" } */
+
+short int zb;
+
+void
+gs (void)
+{
+ while (zb < 1)
+ {
+ int at;
+
+ zb %= 1;
+
+ for (at = 0; at < 56; ++at)
+ zb += zb;
+
+ ++zb;
+ }
+}
diff -Nurp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c 2020-07-28 19:47:53.896000000 +0800
+++ b/gcc/tree-vect-loop.c 2020-07-28 19:48:09.324000000 +0800
@@ -5459,8 +5459,11 @@ vect_create_epilog_for_reduction (stmt_v
orig_name = PHI_RESULT (exit_phi);
scalar_result = scalar_results[k];
FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, orig_name)
- FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
- SET_USE (use_p, scalar_result);
+ {
+ FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
+ SET_USE (use_p, scalar_result);
+ update_stmt (use_stmt);
+ }
}
phis.release ();

View File

@ -1,88 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-arm-aarch64-Handle-no_insn-in-TARGET_SCHED_VARIABLE_.patch
d0bc0cb66bcb0e6a5a5a31a9e900e8ccc98e34e5
diff -Nurp a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
--- a/gcc/config/aarch64/aarch64.c 2020-09-03 15:54:20.136000000 +0800
+++ b/gcc/config/aarch64/aarch64.c 2020-09-03 15:55:22.736000000 +0800
@@ -11044,6 +11044,23 @@ aarch64_sched_issue_rate (void)
return aarch64_tune_params.issue_rate;
}
+/* Implement TARGET_SCHED_VARIABLE_ISSUE. */
+static int
+aarch64_sched_variable_issue (FILE *, int, rtx_insn *insn, int more)
+{
+ if (DEBUG_INSN_P (insn))
+ return more;
+
+ rtx_code code = GET_CODE (PATTERN (insn));
+ if (code == USE || code == CLOBBER)
+ return more;
+
+ if (get_attr_type (insn) == TYPE_NO_INSN)
+ return more;
+
+ return more - 1;
+}
+
static int
aarch64_sched_first_cycle_multipass_dfa_lookahead (void)
{
@@ -19428,6 +19445,9 @@ aarch64_libgcc_floating_mode_supported_p
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE aarch64_sched_issue_rate
+#undef TARGET_SCHED_VARIABLE_ISSUE
+#define TARGET_SCHED_VARIABLE_ISSUE aarch64_sched_variable_issue
+
#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
aarch64_sched_first_cycle_multipass_dfa_lookahead
diff -Nurp a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
--- a/gcc/config/arm/arm.c 2020-09-03 15:54:20.100000000 +0800
+++ b/gcc/config/arm/arm.c 2020-09-03 15:55:22.740000000 +0800
@@ -258,6 +258,7 @@ static bool arm_sched_can_speculate_insn
static bool arm_macro_fusion_p (void);
static bool arm_cannot_copy_insn_p (rtx_insn *);
static int arm_issue_rate (void);
+static int arm_sched_variable_issue (FILE *, int, rtx_insn *, int);
static int arm_first_cycle_multipass_dfa_lookahead (void);
static int arm_first_cycle_multipass_dfa_lookahead_guard (rtx_insn *, int);
static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
@@ -666,6 +667,9 @@ static const struct attribute_spec arm_a
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE arm_issue_rate
+#undef TARGET_SCHED_VARIABLE_ISSUE
+#define TARGET_SCHED_VARIABLE_ISSUE arm_sched_variable_issue
+
#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
arm_first_cycle_multipass_dfa_lookahead
@@ -28316,6 +28320,23 @@ arm_issue_rate (void)
return current_tune->issue_rate;
}
+/* Implement TARGET_SCHED_VARIABLE_ISSUE. */
+static int
+arm_sched_variable_issue (FILE *, int, rtx_insn *insn, int more)
+{
+ if (DEBUG_INSN_P (insn))
+ return more;
+
+ rtx_code code = GET_CODE (PATTERN (insn));
+ if (code == USE || code == CLOBBER)
+ return more;
+
+ if (get_attr_type (insn) == TYPE_NO_INSN)
+ return more;
+
+ return more - 1;
+}
+
/* Return how many instructions should scheduler lookahead to choose the
best one. */
static int

View File

@ -1,109 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-ssa-sccvn.c-class-pass_fre-Add-may_iterate-pass.patch
744fd446c321f78f9a1ce4ef5f83df8dcfa44a9e
diff -Nurp a/gcc/passes.def b/gcc/passes.def
--- a/gcc/passes.def 2020-08-17 09:46:40.340000000 +0800
+++ b/gcc/passes.def 2020-08-17 10:09:10.808000000 +0800
@@ -83,7 +83,7 @@ along with GCC; see the file COPYING3.
/* pass_build_ealias is a dummy pass that ensures that we
execute TODO_rebuild_alias at this point. */
NEXT_PASS (pass_build_ealias);
- NEXT_PASS (pass_fre);
+ NEXT_PASS (pass_fre, true /* may_iterate */);
NEXT_PASS (pass_early_vrp);
NEXT_PASS (pass_merge_phi);
NEXT_PASS (pass_dse);
@@ -117,7 +117,7 @@ along with GCC; see the file COPYING3.
NEXT_PASS (pass_oacc_kernels);
PUSH_INSERT_PASSES_WITHIN (pass_oacc_kernels)
NEXT_PASS (pass_ch);
- NEXT_PASS (pass_fre);
+ NEXT_PASS (pass_fre, true /* may_iterate */);
/* We use pass_lim to rewrite in-memory iteration and reduction
variable accesses in loops into local variables accesses. */
NEXT_PASS (pass_lim);
@@ -201,7 +201,7 @@ along with GCC; see the file COPYING3.
execute TODO_rebuild_alias at this point. */
NEXT_PASS (pass_build_alias);
NEXT_PASS (pass_return_slot);
- NEXT_PASS (pass_fre);
+ NEXT_PASS (pass_fre, true /* may_iterate */);
NEXT_PASS (pass_merge_phi);
NEXT_PASS (pass_thread_jumps);
NEXT_PASS (pass_vrp, true /* warn_array_bounds_p */);
@@ -312,6 +312,7 @@ along with GCC; see the file COPYING3.
NEXT_PASS (pass_strength_reduction);
NEXT_PASS (pass_split_paths);
NEXT_PASS (pass_tracer);
+ NEXT_PASS (pass_fre, false /* may_iterate */);
NEXT_PASS (pass_thread_jumps);
NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
NEXT_PASS (pass_strlen);
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c 2020-08-17 09:46:41.332000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c 2020-08-17 10:09:10.808000000 +0800
@@ -125,7 +125,7 @@ enum STATES FMS( u8 **in , u32 *transiti
jump threading opportunities. Skip the later tests on aarch64. */
/* { dg-final { scan-tree-dump "Jumps threaded: 1\[1-9\]" "thread1" } } */
/* { dg-final { scan-tree-dump-times "Invalid sum" 3 "thread1" } } */
-/* { dg-final { scan-tree-dump-not "not considered" "thread1" } } */
-/* { dg-final { scan-tree-dump-not "not considered" "thread2" } } */
-/* { dg-final { scan-tree-dump-not "not considered" "thread3" { target { ! aarch64*-*-* } } } } */
-/* { dg-final { scan-tree-dump-not "not considered" "thread4" { target { ! aarch64*-*-* } } } } */
+/* { dg-final { scan-tree-dump-not "optimizing for size" "thread1" } } */
+/* { dg-final { scan-tree-dump-not "optimizing for size" "thread2" } } */
+/* { dg-final { scan-tree-dump-not "optimizing for size" "thread3" { target { ! aarch64*-*-* } } } } */
+/* { dg-final { scan-tree-dump-not "optimizing for size" "thread4" { target { ! aarch64*-*-* } } } } */
diff -Nurp a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
--- a/gcc/tree-ssa-sccvn.c 2020-08-17 09:46:42.212000000 +0800
+++ b/gcc/tree-ssa-sccvn.c 2020-08-17 10:09:10.808000000 +0800
@@ -7232,14 +7232,24 @@ class pass_fre : public gimple_opt_pass
{
public:
pass_fre (gcc::context *ctxt)
- : gimple_opt_pass (pass_data_fre, ctxt)
+ : gimple_opt_pass (pass_data_fre, ctxt), may_iterate (true)
{}
/* opt_pass methods: */
opt_pass * clone () { return new pass_fre (m_ctxt); }
- virtual bool gate (function *) { return flag_tree_fre != 0; }
+ void set_pass_param (unsigned int n, bool param)
+ {
+ gcc_assert (n == 0);
+ may_iterate = param;
+ }
+ virtual bool gate (function *)
+ {
+ return flag_tree_fre != 0 && (may_iterate || optimize > 1);
+ }
virtual unsigned int execute (function *);
+private:
+ bool may_iterate;
}; // class pass_fre
unsigned int
@@ -7248,15 +7258,16 @@ pass_fre::execute (function *fun)
unsigned todo = 0;
/* At -O[1g] use the cheap non-iterating mode. */
+ bool iterate_p = may_iterate && (optimize > 1);
calculate_dominance_info (CDI_DOMINATORS);
- if (optimize > 1)
+ if (iterate_p)
loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
default_vn_walk_kind = VN_WALKREWRITE;
- todo = do_rpo_vn (fun, NULL, NULL, optimize > 1, true);
+ todo = do_rpo_vn (fun, NULL, NULL, iterate_p, true);
free_rpo_vn ();
- if (optimize > 1)
+ if (iterate_p)
loop_optimizer_finalize ();
return todo;

View File

@ -1,78 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-92537-ICE-in-vect_slp_analyz.patch
2439d584d5def75d705f33218bb3b97fca4c11a1
diff -Nurp a/gcc/testsuite/gfortran.dg/pr92537.f90 b/gcc/testsuite/gfortran.dg/pr92537.f90
--- a/gcc/testsuite/gfortran.dg/pr92537.f90 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gfortran.dg/pr92537.f90 2020-09-03 16:53:43.024000000 +0800
@@ -0,0 +1,32 @@
+! { dg-do compile }
+! { dg-options "-O2 -ftree-vectorize -fno-inline" }
+! { dg-additional-options "-march=skylake" { target x86_64-*-* i?86-*-* } }
+MODULE pr93527
+ implicit none
+ integer, parameter :: wp = kind (1.d0)
+ interface p_min
+ module procedure p_min_wp
+ end interface
+contains
+ subroutine foo (pr)
+ real(wp), pointer :: pr(:)
+ integer :: nzd
+ real(wp) :: pmin
+ real(wp) :: pmin_diag
+ integer :: i
+ nzd = 15
+ allocate (pr(nzd))
+ pmin_diag = 4000._wp
+ pmin = p_min(pmin_diag)
+ pmin = min (pmin,pmin_diag)
+ pr(1) = log(pmin)
+ do i=1,nzd-1
+ pr(i+1) = log(pmin) + i
+ end do
+ end subroutine foo
+ function p_min_wp (x) result (p_min)
+ real(wp), intent(in) :: x
+ real(wp) :: p_min
+ p_min = x
+ end function p_min_wp
+end module pr93527
diff -Nurp a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2020-09-03 16:53:22.668000000 +0800
+++ b/gcc/tree-vect-slp.c 2020-09-03 16:53:43.024000000 +0800
@@ -2176,18 +2176,6 @@ vect_analyze_slp_instance (vec_info *vin
matches[group_size / const_max_nunits * const_max_nunits] = false;
vect_free_slp_tree (node, false);
}
- else if (constructor
- && SLP_TREE_DEF_TYPE (node) != vect_internal_def)
- {
- /* CONSTRUCTOR vectorization relies on a vector stmt being
- generated, that doesn't work for fully external ones. */
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "Build SLP failed: CONSTRUCTOR of external "
- "or constant elements\n");
- vect_free_slp_tree (node, false);
- return false;
- }
else
{
/* Create a new SLP instance. */
@@ -2872,7 +2860,12 @@ vect_slp_analyze_operations (vec_info *v
if (!vect_slp_analyze_node_operations (vinfo,
SLP_INSTANCE_TREE (instance),
instance, visited, lvisited,
- &cost_vec))
+ &cost_vec)
+ /* Instances with a root stmt require vectorized defs for the
+ SLP tree root. */
+ || (SLP_INSTANCE_ROOT_STMT (instance)
+ && (SLP_TREE_DEF_TYPE (SLP_INSTANCE_TREE (instance))
+ != vect_internal_def)))
{
slp_tree node = SLP_INSTANCE_TREE (instance);
stmt_vec_info stmt_info = SLP_TREE_SCALAR_STMTS (node)[0];

View File

@ -1,151 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-optimization-96698-fix-ICE-when-vectorizing-nes.patch
2130efe6ac7beba72d289e3dd145daa10aeaed54
diff -uprN a/gcc/testsuite/gcc.dg/vect/pr96698.c b/gcc/testsuite/gcc.dg/vect/pr96698.c
--- a/gcc/testsuite/gcc.dg/vect/pr96698.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/pr96698.c 2020-08-27 17:53:24.396000000 +0800
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+void test(int a, int* i)
+{
+ for (; a < 5; ++a)
+ {
+ int b = 0;
+ int c = 0;
+ for (; b != -11; b--)
+ for (int d = 0; d ==0; d++)
+ {
+ *i += c & a;
+ c = b;
+ }
+ }
+}
+
+/* We should be able to vectorize the inner cycle. */
+/* { dg-final { scan-tree-dump "OUTER LOOP VECTORIZED" "vect" { target vect_int } } } */
diff -uprN a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c 2020-08-27 09:25:58.000000000 +0800
+++ b/gcc/tree-vect-loop.c 2020-08-27 18:41:41.016000000 +0800
@@ -4325,7 +4325,8 @@ info_for_reduction (stmt_vec_info stmt_i
{
stmt_info = vect_orig_stmt (stmt_info);
gcc_assert (STMT_VINFO_REDUC_DEF (stmt_info));
- if (!is_a <gphi *> (stmt_info->stmt))
+ if (!is_a <gphi *> (stmt_info->stmt)
+ || !VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info)))
stmt_info = STMT_VINFO_REDUC_DEF (stmt_info);
gphi *phi = as_a <gphi *> (stmt_info->stmt);
if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_double_reduction_def)
@@ -8622,6 +8623,43 @@ vect_transform_loop (loop_vec_info loop_
}
}
+ /* Fill in backedge defs of reductions. */
+ for (unsigned i = 0; i < loop_vinfo->reduc_latch_defs.length (); ++i)
+ {
+ stmt_vec_info stmt_info = loop_vinfo->reduc_latch_defs[i];
+ stmt_vec_info orig_stmt_info = vect_orig_stmt (stmt_info);
+ stmt_vec_info phi_info
+ = STMT_VINFO_VEC_STMT (STMT_VINFO_REDUC_DEF (orig_stmt_info));
+ stmt_vec_info vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
+ gphi *phi
+ = dyn_cast <gphi *> (STMT_VINFO_REDUC_DEF (orig_stmt_info)->stmt);
+ edge e = loop_latch_edge (gimple_bb (phi_info->stmt)->loop_father);
+ do
+ {
+ add_phi_arg (as_a <gphi *> (phi_info->stmt),
+ gimple_get_lhs (vec_stmt->stmt), e,
+ gimple_phi_arg_location (phi, e->dest_idx));
+ phi_info = STMT_VINFO_RELATED_STMT (phi_info);
+ vec_stmt = STMT_VINFO_RELATED_STMT (vec_stmt);
+ }
+ while (phi_info);
+ gcc_assert (!vec_stmt);
+ }
+ for (unsigned i = 0; i < loop_vinfo->reduc_latch_slp_defs.length (); ++i)
+ {
+ slp_tree slp_node = loop_vinfo->reduc_latch_slp_defs[i].first;
+ slp_tree phi_node = loop_vinfo->reduc_latch_slp_defs[i].second;
+ gphi *phi = as_a <gphi *> (SLP_TREE_SCALAR_STMTS (phi_node)[0]->stmt);
+ e = loop_latch_edge (gimple_bb (phi)->loop_father);
+ gcc_assert (SLP_TREE_VEC_STMTS (phi_node).length ()
+ == SLP_TREE_VEC_STMTS (slp_node).length ());
+ for (unsigned j = 0; j < SLP_TREE_VEC_STMTS (phi_node).length (); ++j)
+ add_phi_arg (as_a <gphi *> (SLP_TREE_VEC_STMTS (phi_node)[j]->stmt),
+ gimple_get_lhs
+ (SLP_TREE_VEC_STMTS (slp_node)[j]->stmt),
+ e, gimple_phi_arg_location (phi, e->dest_idx));
+ }
+
/* Stub out scalar statements that must not survive vectorization.
Doing this here helps with grouped statements, or statements that
are involved in patterns. */
diff -uprN a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
--- a/gcc/tree-vectorizer.h 2020-08-27 09:25:57.000000000 +0800
+++ b/gcc/tree-vectorizer.h 2020-08-27 17:53:24.400000000 +0800
@@ -575,6 +575,11 @@ typedef struct _loop_vec_info : public v
stmt in the chain. */
auto_vec<stmt_vec_info> reduction_chains;
+ /* The vectorized stmts defining the latch values of the reduction
+ they are involved with. */
+ auto_vec<stmt_vec_info> reduc_latch_defs;
+ auto_vec<std::pair<slp_tree, slp_tree> > reduc_latch_slp_defs;
+
/* Cost vector for a single scalar iteration. */
auto_vec<stmt_info_for_cost> scalar_cost_vec;
diff -uprN a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
--- a/gcc/tree-vect-stmts.c 2020-08-27 09:25:58.000000000 +0800
+++ b/gcc/tree-vect-stmts.c 2020-08-27 17:53:24.400000000 +0800
@@ -10213,8 +10213,8 @@ vect_transform_stmt (stmt_vec_info stmt_
if (STMT_VINFO_TYPE (stmt_info) == store_vec_info_type)
return is_store;
- /* If this stmt defines a value used on a backedge, update the
- vectorized PHIs. */
+ /* If this stmt defines a value used on a backedge, record it so
+ we can update the vectorized PHIs later. */
stmt_vec_info orig_stmt_info = vect_orig_stmt (stmt_info);
stmt_vec_info reduc_info;
if (STMT_VINFO_REDUC_DEF (orig_stmt_info)
@@ -10234,32 +10234,13 @@ vect_transform_stmt (stmt_vec_info stmt_
&& (PHI_ARG_DEF_FROM_EDGE (phi, e)
== gimple_get_lhs (orig_stmt_info->stmt)))
{
- stmt_vec_info phi_info
- = STMT_VINFO_VEC_STMT (STMT_VINFO_REDUC_DEF (orig_stmt_info));
- stmt_vec_info vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
- do
- {
- add_phi_arg (as_a <gphi *> (phi_info->stmt),
- gimple_get_lhs (vec_stmt->stmt), e,
- gimple_phi_arg_location (phi, e->dest_idx));
- phi_info = STMT_VINFO_RELATED_STMT (phi_info);
- vec_stmt = STMT_VINFO_RELATED_STMT (vec_stmt);
- }
- while (phi_info);
- gcc_assert (!vec_stmt);
+ as_a <loop_vec_info> (vinfo)->reduc_latch_defs.safe_push (stmt_info);
}
else if (slp_node
&& slp_node != slp_node_instance->reduc_phis)
{
- slp_tree phi_node = slp_node_instance->reduc_phis;
- gphi *phi = as_a <gphi *> (SLP_TREE_SCALAR_STMTS (phi_node)[0]->stmt);
- e = loop_latch_edge (gimple_bb (phi)->loop_father);
- gcc_assert (SLP_TREE_VEC_STMTS (phi_node).length ()
- == SLP_TREE_VEC_STMTS (slp_node).length ());
- for (unsigned i = 0; i < SLP_TREE_VEC_STMTS (phi_node).length (); ++i)
- add_phi_arg (as_a <gphi *> (SLP_TREE_VEC_STMTS (phi_node)[i]->stmt),
- gimple_get_lhs (SLP_TREE_VEC_STMTS (slp_node)[i]->stmt),
- e, gimple_phi_arg_location (phi, e->dest_idx));
+ as_a <loop_vec_info> (vinfo)->reduc_latch_slp_defs.safe_push
+ (std::make_pair (slp_node, slp_node_instance->reduc_phis));
}
}

View File

@ -1,152 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-vect-PR-92351-When-peeling-for-alignment-make-alignm.patch
4e9d58d16767b1bc686f0c4b3bd2da25dc71e8f3
diff --git a/gcc/testsuite/gcc.dg/vect/vect-peel-2-epilogues.c b/gcc/testsuite/gcc.dg/vect/vect-peel-2-epilogues.c
new file mode 100644
index 00000000000..c06fa442faf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-peel-2-epilogues.c
@@ -0,0 +1,3 @@
+/* { dg-require-effective-target vect_int } */
+
+#include "vect-peel-2-src.c"
diff --git a/gcc/testsuite/gcc.dg/vect/vect-peel-2-src.c b/gcc/testsuite/gcc.dg/vect/vect-peel-2-src.c
new file mode 100644
index 00000000000..f6fc134c870
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-peel-2-src.c
@@ -0,0 +1,48 @@
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 128
+
+/* unaligned store. */
+
+int ib[N+7];
+
+__attribute__ ((noinline))
+int main1 ()
+{
+ int i;
+ int ia[N+1];
+
+ /* The store is aligned and the loads are misaligned with the same
+ misalignment. Cost model is disabled. If misaligned stores are supported,
+ we peel according to the loads to align them. */
+ for (i = 0; i <= N; i++)
+ {
+ ia[i] = ib[i+2] + ib[i+6];
+ }
+
+ /* check results: */
+ for (i = 1; i <= N; i++)
+ {
+ if (ia[i] != ib[i+2] + ib[i+6])
+ abort ();
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ int i;
+
+ check_vect ();
+
+ for (i = 0; i <= N+6; i++)
+ {
+ asm volatile ("" : "+r" (i));
+ ib[i] = i;
+ }
+
+ return main1 ();
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-peel-2.c b/gcc/testsuite/gcc.dg/vect/vect-peel-2.c
index b6061c3b855..65e70bd4417 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-peel-2.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-peel-2.c
@@ -1,52 +1,8 @@
/* { dg-require-effective-target vect_int } */
+/* Disabling epilogues until we find a better way to deal with scans. */
+/* { dg-additional-options "--param vect-epilogues-nomask=0" } */
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 128
-
-/* unaligned store. */
-
-int ib[N+7];
-
-__attribute__ ((noinline))
-int main1 ()
-{
- int i;
- int ia[N+1];
-
- /* The store is aligned and the loads are misaligned with the same
- misalignment. Cost model is disabled. If misaligned stores are supported,
- we peel according to the loads to align them. */
- for (i = 0; i <= N; i++)
- {
- ia[i] = ib[i+2] + ib[i+6];
- }
-
- /* check results: */
- for (i = 1; i <= N; i++)
- {
- if (ia[i] != ib[i+2] + ib[i+6])
- abort ();
- }
-
- return 0;
-}
-
-int main (void)
-{
- int i;
-
- check_vect ();
-
- for (i = 0; i <= N+6; i++)
- {
- asm volatile ("" : "+r" (i));
- ib[i] = i;
- }
-
- return main1 ();
-}
+#include "vect-peel-2-src.c"
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target { { vect_element_align } && { vect_aligned_arrays } } } } } */
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 36639b697f1..88f14e73d65 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -938,6 +938,18 @@ vect_compute_data_ref_alignment (dr_vec_info *dr_info)
= exact_div (vect_calculate_target_alignment (dr_info), BITS_PER_UNIT);
DR_TARGET_ALIGNMENT (dr_info) = vector_alignment;
+ /* If the main loop has peeled for alignment we have no way of knowing
+ whether the data accesses in the epilogues are aligned. We can't at
+ compile time answer the question whether we have entered the main loop or
+ not. Fixes PR 92351. */
+ if (loop_vinfo)
+ {
+ loop_vec_info orig_loop_vinfo = LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo);
+ if (orig_loop_vinfo
+ && LOOP_VINFO_PEELING_FOR_ALIGNMENT (orig_loop_vinfo) != 0)
+ return;
+ }
+
unsigned HOST_WIDE_INT vect_align_c;
if (!vector_alignment.is_constant (&vect_align_c))
return;

View File

@ -1,47 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-optimization-95717-fix-SSA-update-for-vectorize.patch
d0909f5858ad81e6d8b73fa6193be19cb5e6ed7b
diff -Nurp a/gcc/testsuite/g++.dg/torture/pr95717.C b/gcc/testsuite/g++.dg/torture/pr95717.C
--- a/gcc/testsuite/g++.dg/torture/pr95717.C 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/g++.dg/torture/pr95717.C 2020-08-24 21:45:48.436000000 +0800
@@ -0,0 +1,12 @@
+// { dg-do compile }
+
+bool a;
+extern bool b[];
+long c, d;
+int *f;
+void g(bool h)
+{
+ for (short e = 0; e < c; e = 4)
+ for (; d; d++)
+ b[d] = a = f[d] ? c ? h : 0 : h;
+}
diff -Nurp a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
--- a/gcc/tree-vect-loop-manip.c 2020-08-24 21:45:23.620000000 +0800
+++ b/gcc/tree-vect-loop-manip.c 2020-08-24 21:45:48.436000000 +0800
@@ -1073,6 +1073,10 @@ slpeel_tree_duplicate_loop_to_edge_cfg (
add_phi_args_after_copy (new_bbs, scalar_loop->num_nodes + 1, NULL);
+ /* Skip new preheader since it's deleted if copy loop is added at entry. */
+ for (unsigned i = (at_exit ? 0 : 1); i < scalar_loop->num_nodes + 1; i++)
+ rename_variables_in_bb (new_bbs[i], duplicate_outer_loop);
+
if (scalar_loop != loop)
{
/* If we copied from SCALAR_LOOP rather than LOOP, SSA_NAMEs from
@@ -1150,10 +1154,6 @@ slpeel_tree_duplicate_loop_to_edge_cfg (
loop_preheader_edge (new_loop)->src);
}
- /* Skip new preheader since it's deleted if copy loop is added at entry. */
- for (unsigned i = (at_exit ? 0 : 1); i < scalar_loop->num_nodes + 1; i++)
- rename_variables_in_bb (new_bbs[i], duplicate_outer_loop);
-
if (scalar_loop != loop)
{
/* Update new_loop->header PHIs, so that on the preheader

View File

@ -1,87 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-aarch64-Fix-SYMBOL_TINY_GOT-handling-for-ILP32-PR942.patch:
d91480dee934478063fe5945b73ff3c108e40a91
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index b0cbb6e2d55..58d38f74bde 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2739,8 +2739,21 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
}
case SYMBOL_TINY_GOT:
- emit_insn (gen_ldr_got_tiny (dest, imm));
- return;
+ {
+ rtx insn;
+ machine_mode mode = GET_MODE (dest);
+
+ if (mode == ptr_mode)
+ insn = gen_ldr_got_tiny (mode, dest, imm);
+ else
+ {
+ gcc_assert (mode == Pmode);
+ insn = gen_ldr_got_tiny_sidi (dest, imm);
+ }
+
+ emit_insn (insn);
+ return;
+ }
case SYMBOL_TINY_TLSIE:
{
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 7ad4e918578..c7c4d1dd519 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -6766,13 +6766,23 @@
[(set_attr "type" "load_4")]
)
-(define_insn "ldr_got_tiny"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
- UNSPEC_GOTTINYPIC))]
+(define_insn "@ldr_got_tiny_<mode>"
+ [(set (match_operand:PTR 0 "register_operand" "=r")
+ (unspec:PTR [(match_operand:PTR 1 "aarch64_valid_symref" "S")]
+ UNSPEC_GOTTINYPIC))]
""
- "ldr\\t%0, %L1"
- [(set_attr "type" "load_8")]
+ "ldr\t%<w>0, %L1"
+ [(set_attr "type" "load_<ldst_sz>")]
+)
+
+(define_insn "ldr_got_tiny_sidi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (unspec:SI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
+ UNSPEC_GOTTINYPIC)))]
+ "TARGET_ILP32"
+ "ldr\t%w0, %L1"
+ [(set_attr "type" "load_4")]
)
(define_insn "aarch64_load_tp_hard"
diff --git a/gcc/testsuite/gcc.target/aarch64/pr94201.c b/gcc/testsuite/gcc.target/aarch64/pr94201.c
new file mode 100644
index 00000000000..69176169186
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr94201.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-mcmodel=tiny -mabi=ilp32 -fPIC" } */
+
+extern int bar (void *);
+extern long long a;
+
+int
+foo (void)
+{
+ a = 1;
+ return bar ((void *)bar);
+}
+

View File

@ -1,30 +0,0 @@
diff -uprN a/gcc/lra.c b/gcc/lra.c
--- a/gcc/lra.c 2020-12-14 15:26:36.331633230 +0800
+++ b/gcc/lra.c 2020-12-15 18:56:33.699633230 +0800
@@ -507,6 +507,26 @@ lra_emit_move (rtx x, rtx y)
data. */
if (old != max_reg_num ())
expand_reg_data (old);
+ while (insn != NULL)
+ {
+ if (GET_CODE (PATTERN (insn)) == SET
+ && GET_CODE (SET_SRC (PATTERN (insn))) == LO_SUM
+ && GET_CODE (SET_DEST (PATTERN (insn))) == REG
+ && strcmp (insn_data[recog_memoized (insn)].name,
+ "add_losym_di") == 0)
+ {
+ rtx add_losym_dest = SET_DEST (PATTERN (insn));
+ for (int i = (int) max_reg_num () - 1; i >= old; i--)
+ {
+ if (regno_reg_rtx[i] == add_losym_dest)
+ {
+ setup_reg_classes (i, GENERAL_REGS,
+ NO_REGS, GENERAL_REGS);
+ }
+ }
+ }
+ insn = PREV_INSN (insn);
+ }
return;
}
lra_emit_add (x, XEXP (y, 0), XEXP (y, 1));

View File

@ -1,115 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-aarch64-Fix-an-ICE-in-vect_recog_mask_conversion_pattern.patch:
91d80cf4bd2827dd9c40fe6a7c719c909d79083d
diff -Nurp a/gcc/testsuite/gcc.target/aarch64/pr96757.c b/gcc/testsuite/gcc.target/aarch64/pr96757.c
--- a/gcc/testsuite/gcc.target/aarch64/pr96757.c 1969-12-31 19:00:00.000000000 -0500
+++ b/gcc/testsuite/gcc.target/aarch64/pr96757.c 2020-10-12 08:32:12.192000000 -0400
@@ -0,0 +1,23 @@
+/* PR target/96757 */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+short
+fun1(short i, short j)
+{
+ return i * j;
+}
+
+int
+fun(int a, int b, int c)
+{
+ int *v, z, k, m;
+ short f, d;
+ for (int i=0; i<c; i++)
+ {
+ f= 4 <= d;
+ k= a > m;
+ z = f > k;
+ *v += fun1(z,b);
+ }
+}
diff -Nurp a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
--- a/gcc/tree-vect-patterns.c 2020-10-12 08:05:18.924000000 -0400
+++ b/gcc/tree-vect-patterns.c 2020-10-12 08:50:56.996000000 -0400
@@ -3917,6 +3917,8 @@ vect_recog_mask_conversion_pattern (stmt
tree vectype1, vectype2;
stmt_vec_info pattern_stmt_info;
vec_info *vinfo = stmt_vinfo->vinfo;
+ tree rhs1_op0 = NULL_TREE, rhs1_op1 = NULL_TREE;
+ tree rhs1_op0_type = NULL_TREE, rhs1_op1_type = NULL_TREE;
/* Check for MASK_LOAD ans MASK_STORE calls requiring mask conversion. */
if (is_gimple_call (last_stmt)
@@ -4016,9 +4018,37 @@ vect_recog_mask_conversion_pattern (stmt
it is better for b1 and b2 to use the mask type associated
with int elements rather bool (byte) elements. */
- rhs1_type = search_type_for_mask (TREE_OPERAND (rhs1, 0), vinfo);
- if (!rhs1_type)
- rhs1_type = TREE_TYPE (TREE_OPERAND (rhs1, 0));
+ rhs1_op0 = TREE_OPERAND (rhs1, 0);
+ rhs1_op1 = TREE_OPERAND (rhs1, 1);
+ if (!rhs1_op0 || !rhs1_op1)
+ return NULL;
+ rhs1_op0_type = search_type_for_mask (rhs1_op0, vinfo);
+ rhs1_op1_type = search_type_for_mask (rhs1_op1, vinfo);
+
+ if (!rhs1_op0_type)
+ rhs1_type = TREE_TYPE (rhs1_op0);
+ else if (!rhs1_op1_type)
+ rhs1_type = TREE_TYPE (rhs1_op1);
+ else if (TYPE_PRECISION (rhs1_op0_type)
+ != TYPE_PRECISION (rhs1_op1_type))
+ {
+ int tmp0 = (int) TYPE_PRECISION (rhs1_op0_type)
+ - (int) TYPE_PRECISION (TREE_TYPE (lhs));
+ int tmp1 = (int) TYPE_PRECISION (rhs1_op1_type)
+ - (int) TYPE_PRECISION (TREE_TYPE (lhs));
+ if ((tmp0 > 0 && tmp1 > 0) || (tmp0 < 0 && tmp1 < 0))
+ {
+ if (abs (tmp0) > abs (tmp1))
+ rhs1_type = rhs1_op1_type;
+ else
+ rhs1_type = rhs1_op0_type;
+ }
+ else
+ rhs1_type = build_nonstandard_integer_type
+ (TYPE_PRECISION (TREE_TYPE (lhs)), 1);
+ }
+ else
+ rhs1_type = rhs1_op0_type;
}
else
return NULL;
@@ -4036,8 +4066,8 @@ vect_recog_mask_conversion_pattern (stmt
name from the outset. */
if (known_eq (TYPE_VECTOR_SUBPARTS (vectype1),
TYPE_VECTOR_SUBPARTS (vectype2))
- && (TREE_CODE (rhs1) == SSA_NAME
- || rhs1_type == TREE_TYPE (TREE_OPERAND (rhs1, 0))))
+ && !rhs1_op0_type
+ && !rhs1_op1_type)
return NULL;
/* If rhs1 is invariant and we can promote it leave the COND_EXPR
@@ -4069,7 +4099,16 @@ vect_recog_mask_conversion_pattern (stmt
if (TREE_CODE (rhs1) != SSA_NAME)
{
tmp = vect_recog_temp_ssa_var (TREE_TYPE (rhs1), NULL);
- pattern_stmt = gimple_build_assign (tmp, rhs1);
+ if (rhs1_op0_type
+ && TYPE_PRECISION (rhs1_op0_type) != TYPE_PRECISION (rhs1_type))
+ rhs1_op0 = build_mask_conversion (rhs1_op0,
+ vectype2, stmt_vinfo);
+ if (rhs1_op1_type
+ && TYPE_PRECISION (rhs1_op1_type) != TYPE_PRECISION (rhs1_type))
+ rhs1_op1 = build_mask_conversion (rhs1_op1,
+ vectype2, stmt_vinfo);
+ pattern_stmt = gimple_build_assign (tmp, TREE_CODE (rhs1),
+ rhs1_op0, rhs1_op1);
rhs1 = tmp;
append_pattern_def_seq (stmt_vinfo, pattern_stmt, vectype2);
}

View File

@ -1,85 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-optimization-94963-avoid-bogus-uninit-warning-with-store-motion.patch
371905d12259c180efb9b1f1b5716e969feb60f9
diff --git a/gcc/testsuite/gcc.dg/pr94963.c b/gcc/testsuite/gcc.dg/pr94963.c
new file mode 100644
index 00000000000..aca9e161301
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94963.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+typedef struct
+{
+ int p1;
+ int p2;
+ int p3;
+} P;
+struct S
+{
+ int field;
+};
+extern int v2;
+extern void foo (struct S *map);
+static struct S var;
+const P *pv;
+int ps;
+void
+f (void)
+{
+ if (pv != 0)
+ for (const P *ph = pv; ph < &pv[ps]; ++ph)
+ switch (ph->p1)
+ {
+ case 1:
+ v2 = ph->p2;
+ break;
+ case 2:
+ var.field = ph->p3;
+ break;
+ }
+ if (var.field != 0) /* { dg-bogus "uninitialized" } */
+ foo (&var);
+}
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 554dd4be5bb..3056b4bfed2 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -1994,8 +1994,6 @@ execute_sm_if_changed (edge ex, tree mem, tree tmp_var, tree flag,
gsi = gsi_start_bb (then_bb);
/* Insert actual store. */
stmt = gimple_build_assign (unshare_expr (mem), tmp_var);
- /* Make sure to not warn about maybe-uninit uses of tmp_var here. */
- gimple_set_no_warning (stmt, true);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
edge e1 = single_succ_edge (new_bb);
@@ -2149,13 +2147,19 @@ execute_sm (class loop *loop, vec<edge> exits, im_mem_ref *ref)
store then. */
if ((!always_stored && !multi_threaded_model_p)
|| (ref->loaded && bitmap_bit_p (ref->loaded, loop->num)))
+ load = gimple_build_assign (tmp_var, unshare_expr (ref->mem.ref));
+ else
{
- load = gimple_build_assign (tmp_var, unshare_expr (ref->mem.ref));
- lim_data = init_lim_data (load);
- lim_data->max_loop = loop;
- lim_data->tgt_loop = loop;
- gsi_insert_before (&gsi, load, GSI_SAME_STMT);
+ /* If not emitting a load mark the uninitialized state on the
+ loop entry as not to be warned for. */
+ tree uninit = create_tmp_reg (TREE_TYPE (tmp_var));
+ TREE_NO_WARNING (uninit) = 1;
+ load = gimple_build_assign (tmp_var, uninit);
}
+ lim_data = init_lim_data (load);
+ lim_data->max_loop = loop;
+ lim_data->tgt_loop = loop;
+ gsi_insert_before (&gsi, load, GSI_SAME_STMT);
if (multi_threaded_model_p)
{

View File

@ -1,301 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-target-91124-gcc.target-i386-avx512vl-vpshldvd.patch
946732df902dbb23dd44abe97fea41e154e6e5f9
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 3ce22395c65..12d6dc0cb7e 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -5927,16 +5927,16 @@
(set_attr "btver2_decode" "vector")
(set_attr "mode" "OI")])
-(define_insn "sse2_cvtpd2dq<mask_name>"
+(define_insn "sse2_cvtpd2dq"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(vec_concat:V4SI
(unspec:V2SI [(match_operand:V2DF 1 "vector_operand" "vBm")]
UNSPEC_FIX_NOTRUNC)
(const_vector:V2SI [(const_int 0) (const_int 0)])))]
- "TARGET_SSE2 && <mask_avx512vl_condition>"
+ "TARGET_SSE2"
{
if (TARGET_AVX)
- return "vcvtpd2dq{x}\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}";
+ return "vcvtpd2dq{x}\t{%1, %0|%0, %1}";
else
return "cvtpd2dq\t{%1, %0|%0, %1}";
}
@@ -5949,6 +5949,38 @@
(set_attr "athlon_decode" "vector")
(set_attr "bdver1_decode" "double")])
+(define_insn "sse2_cvtpd2dq_mask"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "vm")]
+ UNSPEC_FIX_NOTRUNC)
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "nonimm_or_0_operand" "0C")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvtpd2dq{x}\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "*sse2_cvtpd2dq_mask_1"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "vm")]
+ UNSPEC_FIX_NOTRUNC)
+ (const_vector:V2SI [(const_int 0) (const_int 0)])
+ (match_operand:QI 2 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvtpd2dq{x}\t{%1, %0%{%2%}%{z%}|%0%{%2%}%{z%}, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
;; For ufix_notrunc* insn patterns
(define_mode_attr pd2udqsuff
[(V8DF "") (V4DF "{y}")])
@@ -5964,15 +5996,49 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "ufix_notruncv2dfv2si2<mask_name>"
+(define_insn "ufix_notruncv2dfv2si2"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(vec_concat:V4SI
(unspec:V2SI
[(match_operand:V2DF 1 "nonimmediate_operand" "vm")]
- UNSPEC_UNSIGNED_FIX_NOTRUNC)
+ UNSPEC_UNSIGNED_FIX_NOTRUNC)
(const_vector:V2SI [(const_int 0) (const_int 0)])))]
"TARGET_AVX512VL"
- "vcvtpd2udq{x}\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
+ "vcvtpd2udq{x}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "ufix_notruncv2dfv2si2_mask"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unspec:V2SI
+ [(match_operand:V2DF 1 "nonimmediate_operand" "vm")]
+ UNSPEC_UNSIGNED_FIX_NOTRUNC)
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "nonimm_or_0_operand" "0C")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvtpd2udq{x}\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "*ufix_notruncv2dfv2si2_mask_1"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unspec:V2SI
+ [(match_operand:V2DF 1 "nonimmediate_operand" "vm")]
+ UNSPEC_UNSIGNED_FIX_NOTRUNC)
+ (const_vector:V2SI [(const_int 0) (const_int 0)])
+ (match_operand:QI 2 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvtpd2udq{x}\t{%1, %0%{%2%}%{z%}|%0%{%2%}%{z%}, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "TI")])
@@ -5987,13 +6053,43 @@
(set_attr "prefix" "evex")
(set_attr "mode" "OI")])
-(define_insn "ufix_truncv2dfv2si2<mask_name>"
+(define_insn "ufix_truncv2dfv2si2"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(vec_concat:V4SI
(unsigned_fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
(const_vector:V2SI [(const_int 0) (const_int 0)])))]
"TARGET_AVX512VL"
- "vcvttpd2udq{x}\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
+ "vcvttpd2udq{x}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "ufix_truncv2dfv2si2_mask"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unsigned_fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "nonimm_or_0_operand" "0C")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvttpd2udq{x}\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "*ufix_truncv2dfv2si2_mask_1"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unsigned_fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])
+ (match_operand:QI 2 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvttpd2udq{x}\t{%1, %0%{%2%}%{z%}|%0%{%2%}%{z%}, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "TI")])
@@ -6138,15 +6234,15 @@
"TARGET_AVX"
"operands[2] = CONST0_RTX (V4SImode);")
-(define_insn "sse2_cvttpd2dq<mask_name>"
+(define_insn "sse2_cvttpd2dq"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(vec_concat:V4SI
(fix:V2SI (match_operand:V2DF 1 "vector_operand" "vBm"))
(const_vector:V2SI [(const_int 0) (const_int 0)])))]
- "TARGET_SSE2 && <mask_avx512vl_condition>"
+ "TARGET_SSE2"
{
if (TARGET_AVX)
- return "vcvttpd2dq{x}\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}";
+ return "vcvttpd2dq{x}\t{%1, %0|%0, %1}";
else
return "cvttpd2dq\t{%1, %0|%0, %1}";
}
@@ -6157,6 +6253,36 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
+(define_insn "sse2_cvttpd2dq_mask"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "nonimm_or_0_operand" "0C")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvttpd2dq{x}\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "*sse2_cvttpd2dq_mask_1"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])
+ (match_operand:QI 2 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvttpd2dq{x}\t{%1, %0%{%2%}%{z%}|%0%{%2%}%{z%}, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
(define_insn "sse2_cvtsd2ss<round_name>"
[(set (match_operand:V4SF 0 "register_operand" "=x,x,v")
(vec_merge:V4SF
@@ -6276,26 +6402,28 @@
(define_expand "sse2_cvtpd2ps_mask"
[(set (match_operand:V4SF 0 "register_operand")
- (vec_merge:V4SF
- (vec_concat:V4SF
+ (vec_concat:V4SF
+ (vec_merge:V2SF
(float_truncate:V2SF
(match_operand:V2DF 1 "vector_operand"))
- (match_dup 4))
- (match_operand:V4SF 2 "register_operand")
- (match_operand:QI 3 "register_operand")))]
+ (vec_select:V2SF
+ (match_operand:V4SF 2 "nonimm_or_0_operand")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand"))
+ (match_dup 4)))]
"TARGET_SSE2"
"operands[4] = CONST0_RTX (V2SFmode);")
-(define_insn "*sse2_cvtpd2ps<mask_name>"
+(define_insn "*sse2_cvtpd2ps"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(vec_concat:V4SF
(float_truncate:V2SF
(match_operand:V2DF 1 "vector_operand" "vBm"))
- (match_operand:V2SF 2 "const0_operand")))]
- "TARGET_SSE2 && <mask_avx512vl_condition>"
+ (match_operand:V2SF 2 "const0_operand" "C")))]
+ "TARGET_SSE2"
{
if (TARGET_AVX)
- return "vcvtpd2ps{x}\t{%1, %0<mask_operand3>|%0<mask_operand3>, %1}";
+ return "vcvtpd2ps{x}\t{%1, %0|%0, %1}";
else
return "cvtpd2ps\t{%1, %0|%0, %1}";
}
@@ -6307,6 +6435,38 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "V4SF")])
+(define_insn "*sse2_cvtpd2ps_mask"
+ [(set (match_operand:V4SF 0 "register_operand" "=v")
+ (vec_concat:V4SF
+ (vec_merge:V2SF
+ (float_truncate:V2SF
+ (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (vec_select:V2SF
+ (match_operand:V4SF 2 "nonimm_or_0_operand" "0C")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand" "Yk"))
+ (match_operand:V2SF 4 "const0_operand" "C")))]
+ "TARGET_AVX512VL"
+ "vcvtpd2ps{x}\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "*sse2_cvtpd2ps_mask_1"
+ [(set (match_operand:V4SF 0 "register_operand" "=v")
+ (vec_concat:V4SF
+ (vec_merge:V2SF
+ (float_truncate:V2SF
+ (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (match_operand:V2SF 3 "const0_operand" "C")
+ (match_operand:QI 2 "register_operand" "Yk"))
+ (match_operand:V2SF 4 "const0_operand" "C")))]
+ "TARGET_AVX512VL"
+ "vcvtpd2ps{x}\t{%1, %0%{%2%}%{z%}|%0%{%2%}%{z%}, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "V4SF")])
+
;; For <sse2_avx_avx512f>_cvtps2pd<avxsizesuffix> insn pattern
(define_mode_attr sf2dfmode
[(V8DF "V8SF") (V4DF "V4SF")])

View File

@ -1,19 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
AArch64-Fix-cost-of-plus-.-const_int-C.patch:
commit 835d50c66aa5bde2f354a6e63a2afa7d2f76a05a
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 56a4a47db73..71d44de1d0a 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -10753,7 +10753,7 @@ cost_plus:
}
if (GET_MODE_CLASS (mode) == MODE_INT
- && ((CONST_INT_P (op1) && aarch64_uimm12_shift (INTVAL (op1)))
+ && (aarch64_plus_immediate (op1, mode)
|| aarch64_sve_addvl_addpl_immediate (op1, mode)))
{
*cost += rtx_cost (op0, mode, PLUS, 0, speed);

View File

@ -1,27 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-vect-slp.c-vect_build_slp_tree_2-Do-not-build-o.patch
f99d62629933adf91e7e0bc1b1ff344ffb68e1a2
diff -Nurp a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2020-08-24 21:31:24.780000000 +0800
+++ b/gcc/tree-vect-slp.c 2020-08-24 21:31:53.516000000 +0800
@@ -1326,7 +1326,7 @@ vect_build_slp_tree_2 (vec_info *vinfo,
slp_tree grandchild;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (child), j, grandchild)
- if (SLP_TREE_DEF_TYPE (grandchild) == vect_internal_def)
+ if (SLP_TREE_DEF_TYPE (grandchild) != vect_external_def)
break;
if (!grandchild)
{
@@ -1486,7 +1486,7 @@ vect_build_slp_tree_2 (vec_info *vinfo,
slp_tree grandchild;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (child), j, grandchild)
- if (SLP_TREE_DEF_TYPE (grandchild) == vect_internal_def)
+ if (SLP_TREE_DEF_TYPE (grandchild) != vect_external_def)
break;
if (!grandchild)
{

View File

@ -1,928 +0,0 @@
This patch is a combine of following 8 commits
commit e944354ec05891474b0d204c6c239c04ee7b527b
Author: Robin Dapp <rdapp@linux.ibm.com>
Date: Mon Aug 26 10:18:24 2019 +0000
[PATCH 1/2] Allow folding all statements.
commit df7d46d925c7baca7bf9961aee900876d8aef225
Author: Robin Dapp <rdapp@linux.ibm.com>
Date: Mon Aug 26 10:24:44 2019 +0000
[PATCH 2/2] Add simplify rule for wrapped addition.
commit 6c14d008122fcee4157be79a60f8d6685869ad19
Author: Robin Dapp <rdapp@linux.ibm.com>
Date: Tue Aug 27 12:08:58 2019 +0000
re PR testsuite/91549 (gcc.dg/wrapped-binop-simplify.c fails starting with r274925)
commit 129bd066049f065e522990e63bb10ff92b3c018d
Author: Jakub Jelinek <jakub@redhat.com>
Date: Tue Dec 3 10:20:43 2019 +0100
re PR tree-optimization/92734 (Missing match.pd simplification done by fold_binary_loc on generic)
commit 526b4c716a340ee9464965e63eee2b9954fe21f1
Author: Jakub Jelinek <jakub@redhat.com>
Date: Wed Dec 4 10:38:48 2019 +0100
re PR tree-optimization/92734 (Missing match.pd simplification done by fold_binary_loc on generic)
commit 28fabd43d9d249134244eb9d7815917c7ae44b64
Author: Richard Biener <rguenther@suse.de>
Date: Fri Dec 6 10:25:08 2019 +0000
genmatch.c (enum tree_code): Remove CONVERT{0,1,2} and VIEW_CONVERT{0,1,2}.
commit e150da383346adc762bc904342f9877f2f071265
Author: Richard Biener <rguenther@suse.de>
Date: Fri Dec 6 11:44:27 2019 +0000
match.pd (nop_convert): Remove empty match.
commit 496f4f884716ae061f771a62e44868a32dbd502f
Author: Jakub Jelinek <jakub@redhat.com>
Date: Mon May 4 11:01:08 2020 +0200
match.pd: Decrease number of nop conversions around bitwise ops [PR94718]
diff -Nurp a/gcc/genmatch.c b/gcc/genmatch.c
--- a/gcc/genmatch.c 2020-03-12 19:07:21.000000000 +0800
+++ b/gcc/genmatch.c 2020-11-24 14:49:12.792000000 +0800
@@ -224,12 +224,6 @@ output_line_directive (FILE *f, location
#define DEFTREECODE(SYM, STRING, TYPE, NARGS) SYM,
enum tree_code {
#include "tree.def"
-CONVERT0,
-CONVERT1,
-CONVERT2,
-VIEW_CONVERT0,
-VIEW_CONVERT1,
-VIEW_CONVERT2,
MAX_TREE_CODES
};
#undef DEFTREECODE
@@ -695,11 +689,12 @@ struct expr : public operand
expr (id_base *operation_, location_t loc, bool is_commutative_ = false)
: operand (OP_EXPR, loc), operation (operation_),
ops (vNULL), expr_type (NULL), is_commutative (is_commutative_),
- is_generic (false), force_single_use (false) {}
+ is_generic (false), force_single_use (false), opt_grp (0) {}
expr (expr *e)
: operand (OP_EXPR, e->location), operation (e->operation),
ops (vNULL), expr_type (e->expr_type), is_commutative (e->is_commutative),
- is_generic (e->is_generic), force_single_use (e->force_single_use) {}
+ is_generic (e->is_generic), force_single_use (e->force_single_use),
+ opt_grp (e->opt_grp) {}
void append_op (operand *op) { ops.safe_push (op); }
/* The operator and its operands. */
id_base *operation;
@@ -714,6 +709,8 @@ struct expr : public operand
/* Whether pushing any stmt to the sequence should be conditional
on this expression having a single-use. */
bool force_single_use;
+ /* If non-zero, the group for optional handling. */
+ unsigned char opt_grp;
virtual void gen_transform (FILE *f, int, const char *, bool, int,
const char *, capture_info *,
dt_operand ** = 0, int = 0);
@@ -1079,18 +1076,17 @@ lower_commutative (simplify *s, vec<simp
}
}
-/* Strip conditional conversios using operator OPER from O and its
- children if STRIP, else replace them with an unconditional convert. */
+/* Strip conditional operations using group GRP from O and its
+ children if STRIP, else replace them with an unconditional operation. */
operand *
-lower_opt_convert (operand *o, enum tree_code oper,
- enum tree_code to_oper, bool strip)
+lower_opt (operand *o, unsigned char grp, bool strip)
{
if (capture *c = dyn_cast<capture *> (o))
{
if (c->what)
return new capture (c->location, c->where,
- lower_opt_convert (c->what, oper, to_oper, strip),
+ lower_opt (c->what, grp, strip),
c->value_match);
else
return c;
@@ -1100,36 +1096,34 @@ lower_opt_convert (operand *o, enum tree
if (!e)
return o;
- if (*e->operation == oper)
+ if (e->opt_grp == grp)
{
if (strip)
- return lower_opt_convert (e->ops[0], oper, to_oper, strip);
+ return lower_opt (e->ops[0], grp, strip);
expr *ne = new expr (e);
- ne->operation = (to_oper == CONVERT_EXPR
- ? get_operator ("CONVERT_EXPR")
- : get_operator ("VIEW_CONVERT_EXPR"));
- ne->append_op (lower_opt_convert (e->ops[0], oper, to_oper, strip));
+ ne->opt_grp = 0;
+ ne->append_op (lower_opt (e->ops[0], grp, strip));
return ne;
}
expr *ne = new expr (e);
for (unsigned i = 0; i < e->ops.length (); ++i)
- ne->append_op (lower_opt_convert (e->ops[i], oper, to_oper, strip));
+ ne->append_op (lower_opt (e->ops[i], grp, strip));
return ne;
}
-/* Determine whether O or its children uses the conditional conversion
- operator OPER. */
+/* Determine whether O or its children uses the conditional operation
+ group GRP. */
static bool
-has_opt_convert (operand *o, enum tree_code oper)
+has_opt (operand *o, unsigned char grp)
{
if (capture *c = dyn_cast<capture *> (o))
{
if (c->what)
- return has_opt_convert (c->what, oper);
+ return has_opt (c->what, grp);
else
return false;
}
@@ -1138,11 +1132,11 @@ has_opt_convert (operand *o, enum tree_c
if (!e)
return false;
- if (*e->operation == oper)
+ if (e->opt_grp == grp)
return true;
for (unsigned i = 0; i < e->ops.length (); ++i)
- if (has_opt_convert (e->ops[i], oper))
+ if (has_opt (e->ops[i], grp))
return true;
return false;
@@ -1152,34 +1146,24 @@ has_opt_convert (operand *o, enum tree_c
if required. */
static vec<operand *>
-lower_opt_convert (operand *o)
+lower_opt (operand *o)
{
vec<operand *> v1 = vNULL, v2;
v1.safe_push (o);
- enum tree_code opers[]
- = { CONVERT0, CONVERT_EXPR,
- CONVERT1, CONVERT_EXPR,
- CONVERT2, CONVERT_EXPR,
- VIEW_CONVERT0, VIEW_CONVERT_EXPR,
- VIEW_CONVERT1, VIEW_CONVERT_EXPR,
- VIEW_CONVERT2, VIEW_CONVERT_EXPR };
-
- /* Conditional converts are lowered to a pattern with the
- conversion and one without. The three different conditional
- convert codes are lowered separately. */
+ /* Conditional operations are lowered to a pattern with the
+ operation and one without. All different conditional operation
+ groups are lowered separately. */
- for (unsigned i = 0; i < sizeof (opers) / sizeof (enum tree_code); i += 2)
+ for (unsigned i = 1; i <= 10; ++i)
{
v2 = vNULL;
for (unsigned j = 0; j < v1.length (); ++j)
- if (has_opt_convert (v1[j], opers[i]))
+ if (has_opt (v1[j], i))
{
- v2.safe_push (lower_opt_convert (v1[j],
- opers[i], opers[i+1], false));
- v2.safe_push (lower_opt_convert (v1[j],
- opers[i], opers[i+1], true));
+ v2.safe_push (lower_opt (v1[j], i, false));
+ v2.safe_push (lower_opt (v1[j], i, true));
}
if (v2 != vNULL)
@@ -1197,9 +1181,9 @@ lower_opt_convert (operand *o)
the resulting multiple patterns to SIMPLIFIERS. */
static void
-lower_opt_convert (simplify *s, vec<simplify *>& simplifiers)
+lower_opt (simplify *s, vec<simplify *>& simplifiers)
{
- vec<operand *> matchers = lower_opt_convert (s->match);
+ vec<operand *> matchers = lower_opt (s->match);
for (unsigned i = 0; i < matchers.length (); ++i)
{
simplify *ns = new simplify (s->kind, s->id, matchers[i], s->result,
@@ -1543,7 +1527,7 @@ lower (vec<simplify *>& simplifiers, boo
{
auto_vec<simplify *> out_simplifiers;
for (unsigned i = 0; i < simplifiers.length (); ++i)
- lower_opt_convert (simplifiers[i], out_simplifiers);
+ lower_opt (simplifiers[i], out_simplifiers);
simplifiers.truncate (0);
for (unsigned i = 0; i < out_simplifiers.length (); ++i)
@@ -3927,7 +3911,7 @@ private:
unsigned get_internal_capture_id ();
- id_base *parse_operation ();
+ id_base *parse_operation (unsigned char &);
operand *parse_capture (operand *, bool);
operand *parse_expr ();
c_expr *parse_c_expr (cpp_ttype);
@@ -4118,47 +4102,36 @@ parser::record_operlist (location_t loc,
convert2? */
id_base *
-parser::parse_operation ()
+parser::parse_operation (unsigned char &opt_grp)
{
const cpp_token *id_tok = peek ();
+ char *alt_id = NULL;
const char *id = get_ident ();
const cpp_token *token = peek ();
- if (strcmp (id, "convert0") == 0)
- fatal_at (id_tok, "use 'convert?' here");
- else if (strcmp (id, "view_convert0") == 0)
- fatal_at (id_tok, "use 'view_convert?' here");
+ opt_grp = 0;
if (token->type == CPP_QUERY
&& !(token->flags & PREV_WHITE))
{
- if (strcmp (id, "convert") == 0)
- id = "convert0";
- else if (strcmp (id, "convert1") == 0)
- ;
- else if (strcmp (id, "convert2") == 0)
- ;
- else if (strcmp (id, "view_convert") == 0)
- id = "view_convert0";
- else if (strcmp (id, "view_convert1") == 0)
- ;
- else if (strcmp (id, "view_convert2") == 0)
- ;
- else
- fatal_at (id_tok, "non-convert operator conditionalized");
-
if (!parsing_match_operand)
fatal_at (id_tok, "conditional convert can only be used in "
"match expression");
+ if (ISDIGIT (id[strlen (id) - 1]))
+ {
+ opt_grp = id[strlen (id) - 1] - '0' + 1;
+ alt_id = xstrdup (id);
+ alt_id[strlen (id) - 1] = '\0';
+ if (opt_grp == 1)
+ fatal_at (id_tok, "use '%s?' here", alt_id);
+ }
+ else
+ opt_grp = 1;
eat_token (CPP_QUERY);
}
- else if (strcmp (id, "convert1") == 0
- || strcmp (id, "convert2") == 0
- || strcmp (id, "view_convert1") == 0
- || strcmp (id, "view_convert2") == 0)
- fatal_at (id_tok, "expected '?' after conditional operator");
- id_base *op = get_operator (id);
+ id_base *op = get_operator (alt_id ? alt_id : id);
if (!op)
- fatal_at (id_tok, "unknown operator %s", id);
-
+ fatal_at (id_tok, "unknown operator %s", alt_id ? alt_id : id);
+ if (alt_id)
+ free (alt_id);
user_id *p = dyn_cast<user_id *> (op);
if (p && p->is_oper_list)
{
@@ -4214,7 +4187,8 @@ struct operand *
parser::parse_expr ()
{
const cpp_token *token = peek ();
- expr *e = new expr (parse_operation (), token->src_loc);
+ unsigned char opt_grp;
+ expr *e = new expr (parse_operation (opt_grp), token->src_loc);
token = peek ();
operand *op;
bool is_commutative = false;
@@ -4310,6 +4284,12 @@ parser::parse_expr ()
"commutative");
}
e->expr_type = expr_type;
+ if (opt_grp != 0)
+ {
+ if (e->ops.length () != 1)
+ fatal_at (token, "only unary operations can be conditional");
+ e->opt_grp = opt_grp;
+ }
return op;
}
else if (!(token->flags & PREV_WHITE))
@@ -4692,10 +4672,6 @@ parser::parse_for (location_t)
id_base *idb = get_operator (oper, true);
if (idb == NULL)
fatal_at (token, "no such operator '%s'", oper);
- if (*idb == CONVERT0 || *idb == CONVERT1 || *idb == CONVERT2
- || *idb == VIEW_CONVERT0 || *idb == VIEW_CONVERT1
- || *idb == VIEW_CONVERT2)
- fatal_at (token, "conditional operators cannot be used inside for");
if (arity == -1)
arity = idb->nargs;
@@ -5102,12 +5078,6 @@ main (int argc, char **argv)
add_operator (SYM, # SYM, # TYPE, NARGS);
#define END_OF_BASE_TREE_CODES
#include "tree.def"
-add_operator (CONVERT0, "convert0", "tcc_unary", 1);
-add_operator (CONVERT1, "convert1", "tcc_unary", 1);
-add_operator (CONVERT2, "convert2", "tcc_unary", 1);
-add_operator (VIEW_CONVERT0, "view_convert0", "tcc_unary", 1);
-add_operator (VIEW_CONVERT1, "view_convert1", "tcc_unary", 1);
-add_operator (VIEW_CONVERT2, "view_convert2", "tcc_unary", 1);
#undef END_OF_BASE_TREE_CODES
#undef DEFTREECODE
diff -Nurp a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc
--- a/gcc/gimple-loop-versioning.cc 2020-03-12 19:07:21.000000000 +0800
+++ b/gcc/gimple-loop-versioning.cc 2020-11-24 14:49:12.792000000 +0800
@@ -1264,6 +1264,12 @@ loop_versioning::record_address_fragment
continue;
}
}
+ if (CONVERT_EXPR_CODE_P (code))
+ {
+ tree op1 = gimple_assign_rhs1 (assign);
+ address->terms[i].expr = strip_casts (op1);
+ continue;
+ }
}
i += 1;
}
diff -Nurp a/gcc/match.pd b/gcc/match.pd
--- a/gcc/match.pd 2020-11-24 14:54:43.576000000 +0800
+++ b/gcc/match.pd 2020-11-24 14:49:12.792000000 +0800
@@ -97,8 +97,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(define_operator_list COND_TERNARY
IFN_COND_FMA IFN_COND_FMS IFN_COND_FNMA IFN_COND_FNMS)
-/* As opposed to convert?, this still creates a single pattern, so
- it is not a suitable replacement for convert? in all cases. */
+/* With nop_convert? combine convert? and view_convert? in one pattern
+ plus conditionalize on tree_nop_conversion_p conversions. */
(match (nop_convert @0)
(convert @0)
(if (tree_nop_conversion_p (type, TREE_TYPE (@0)))))
@@ -108,9 +108,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& known_eq (TYPE_VECTOR_SUBPARTS (type),
TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0)))
&& tree_nop_conversion_p (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (@0))))))
-/* This one has to be last, or it shadows the others. */
-(match (nop_convert @0)
- @0)
/* Transform likes of (char) ABS_EXPR <(int) x> into (char) ABSU_EXPR <x>
ABSU_EXPR returns unsigned absolute value of the operand and the operand
@@ -1260,7 +1257,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
We combine the above two cases by using a conditional convert. */
(for bitop (bit_and bit_ior bit_xor)
(simplify
- (bitop (convert @0) (convert? @1))
+ (bitop (convert@2 @0) (convert?@3 @1))
(if (((TREE_CODE (@1) == INTEGER_CST
&& INTEGRAL_TYPE_P (TREE_TYPE (@0))
&& int_fits_type_p (@1, TREE_TYPE (@0)))
@@ -1279,8 +1276,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|| GET_MODE_CLASS (TYPE_MODE (type)) != MODE_INT
/* Or if the precision of TO is not the same as the precision
of its mode. */
- || !type_has_mode_precision_p (type)))
- (convert (bitop @0 (convert @1))))))
+ || !type_has_mode_precision_p (type)
+ /* In GIMPLE, getting rid of 2 conversions for one new results
+ in smaller IL. */
+ || (GIMPLE
+ && TREE_CODE (@1) != INTEGER_CST
+ && tree_nop_conversion_p (type, TREE_TYPE (@0))
+ && single_use (@2)
+ && single_use (@3))))
+ (convert (bitop @0 (convert @1)))))
+ /* In GIMPLE, getting rid of 2 conversions for one new results
+ in smaller IL. */
+ (simplify
+ (convert (bitop:cs@2 (nop_convert:s @0) @1))
+ (if (GIMPLE
+ && TREE_CODE (@1) != INTEGER_CST
+ && tree_nop_conversion_p (type, TREE_TYPE (@2))
+ && types_match (type, @0))
+ (bitop @0 (convert @1)))))
(for bitop (bit_and bit_ior)
rbitop (bit_ior bit_and)
@@ -1374,7 +1387,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* Convert - (~A) to A + 1. */
(simplify
- (negate (nop_convert (bit_not @0)))
+ (negate (nop_convert? (bit_not @0)))
(plus (view_convert @0) { build_each_one_cst (type); }))
/* Convert ~ (A - 1) or ~ (A + -1) to -A. */
@@ -1401,7 +1414,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* Otherwise prefer ~(X ^ Y) to ~X ^ Y as more canonical. */
(simplify
- (bit_xor:c (nop_convert:s (bit_not:s @0)) @1)
+ (bit_xor:c (nop_convert?:s (bit_not:s @0)) @1)
(if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
(bit_not (bit_xor (view_convert @0) @1))))
@@ -1614,7 +1627,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* For equality, this is also true with wrapping overflow. */
(for op (eq ne)
(simplify
- (op:c (nop_convert@3 (plus:c@2 @0 (convert1? @1))) (convert2? @1))
+ (op:c (nop_convert?@3 (plus:c@2 @0 (convert1? @1))) (convert2? @1))
(if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
&& (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
|| TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
@@ -1623,7 +1636,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@1)))
(op @0 { build_zero_cst (TREE_TYPE (@0)); })))
(simplify
- (op:c (nop_convert@3 (pointer_plus@2 (convert1? @0) @1)) (convert2? @0))
+ (op:c (nop_convert?@3 (pointer_plus@2 (convert1? @0) @1)) (convert2? @0))
(if (tree_nop_conversion_p (TREE_TYPE (@2), TREE_TYPE (@0))
&& tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@0))
&& (CONSTANT_CLASS_P (@1) || (single_use (@2) && single_use (@3))))
@@ -1866,7 +1879,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|| !HONOR_SIGN_DEPENDENT_ROUNDING (type)))
(convert (negate @1))))
(simplify
- (negate (nop_convert (negate @1)))
+ (negate (nop_convert? (negate @1)))
(if (!TYPE_OVERFLOW_SANITIZED (type)
&& !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@1)))
(view_convert @1)))
@@ -1883,20 +1896,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* A - (A +- B) -> -+ B */
/* A +- (B -+ A) -> +- B */
(simplify
- (minus (plus:c @0 @1) @0)
- @1)
- (simplify
- (minus (minus @0 @1) @0)
- (negate @1))
+ (minus (nop_convert1? (plus:c (nop_convert2? @0) @1)) @0)
+ (view_convert @1))
(simplify
- (plus:c (minus @0 @1) @1)
- @0)
+ (minus (nop_convert1? (minus (nop_convert2? @0) @1)) @0)
+ (if (!ANY_INTEGRAL_TYPE_P (type)
+ || TYPE_OVERFLOW_WRAPS (type))
+ (negate (view_convert @1))
+ (view_convert (negate @1))))
+ (simplify
+ (plus:c (nop_convert1? (minus @0 (nop_convert2? @1))) @1)
+ (view_convert @0))
+ (simplify
+ (minus @0 (nop_convert1? (plus:c (nop_convert2? @0) @1)))
+ (if (!ANY_INTEGRAL_TYPE_P (type)
+ || TYPE_OVERFLOW_WRAPS (type))
+ (negate (view_convert @1))
+ (view_convert (negate @1))))
(simplify
- (minus @0 (plus:c @0 @1))
- (negate @1))
- (simplify
- (minus @0 (minus @0 @1))
- @1)
+ (minus @0 (nop_convert1? (minus (nop_convert2? @0) @1)))
+ (view_convert @1))
/* (A +- B) + (C - A) -> C +- B */
/* (A + B) - (A - C) -> B + C */
/* More cases are handled with comparisons. */
@@ -1922,7 +1941,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(for inner_op (plus minus)
neg_inner_op (minus plus)
(simplify
- (outer_op (nop_convert (inner_op @0 CONSTANT_CLASS_P@1))
+ (outer_op (nop_convert? (inner_op @0 CONSTANT_CLASS_P@1))
CONSTANT_CLASS_P@2)
/* If one of the types wraps, use that one. */
(if (!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type))
@@ -1961,17 +1980,70 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* (CST1 - A) +- CST2 -> CST3 - A */
(for outer_op (plus minus)
(simplify
- (outer_op (minus CONSTANT_CLASS_P@1 @0) CONSTANT_CLASS_P@2)
- (with { tree cst = const_binop (outer_op, type, @1, @2); }
- (if (cst && !TREE_OVERFLOW (cst))
- (minus { cst; } @0)))))
-
- /* CST1 - (CST2 - A) -> CST3 + A */
- (simplify
- (minus CONSTANT_CLASS_P@1 (minus CONSTANT_CLASS_P@2 @0))
- (with { tree cst = const_binop (MINUS_EXPR, type, @1, @2); }
- (if (cst && !TREE_OVERFLOW (cst))
- (plus { cst; } @0))))
+ (outer_op (nop_convert? (minus CONSTANT_CLASS_P@1 @0)) CONSTANT_CLASS_P@2)
+ /* If one of the types wraps, use that one. */
+ (if (!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type))
+ /* If all 3 captures are CONSTANT_CLASS_P, punt, as we might recurse
+ forever if something doesn't simplify into a constant. */
+ (if (!CONSTANT_CLASS_P (@0))
+ (minus (outer_op (view_convert @1) @2) (view_convert @0)))
+ (if (!ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
+ (view_convert (minus (outer_op @1 (view_convert @2)) @0))
+ (if (types_match (type, @0))
+ (with { tree cst = const_binop (outer_op, type, @1, @2); }
+ (if (cst && !TREE_OVERFLOW (cst))
+ (minus { cst; } @0))))))))
+
+ /* CST1 - (CST2 - A) -> CST3 + A
+ Use view_convert because it is safe for vectors and equivalent for
+ scalars. */
+ (simplify
+ (minus CONSTANT_CLASS_P@1 (nop_convert? (minus CONSTANT_CLASS_P@2 @0)))
+ /* If one of the types wraps, use that one. */
+ (if (!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type))
+ /* If all 3 captures are CONSTANT_CLASS_P, punt, as we might recurse
+ forever if something doesn't simplify into a constant. */
+ (if (!CONSTANT_CLASS_P (@0))
+ (plus (view_convert @0) (minus @1 (view_convert @2))))
+ (if (!ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
+ (view_convert (plus @0 (minus (view_convert @1) @2)))
+ (if (types_match (type, @0))
+ (with { tree cst = const_binop (MINUS_EXPR, type, @1, @2); }
+ (if (cst && !TREE_OVERFLOW (cst))
+ (plus { cst; } @0)))))))
+
+/* ((T)(A)) + CST -> (T)(A + CST) */
+#if GIMPLE
+ (simplify
+ (plus (convert SSA_NAME@0) INTEGER_CST@1)
+ (if (TREE_CODE (TREE_TYPE (@0)) == INTEGER_TYPE
+ && TREE_CODE (type) == INTEGER_TYPE
+ && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0))
+ && int_fits_type_p (@1, TREE_TYPE (@0)))
+ /* Perform binary operation inside the cast if the constant fits
+ and (A + CST)'s range does not overflow. */
+ (with
+ {
+ wi::overflow_type min_ovf = wi::OVF_OVERFLOW,
+ max_ovf = wi::OVF_OVERFLOW;
+ tree inner_type = TREE_TYPE (@0);
+
+ wide_int w1 = wide_int::from (wi::to_wide (@1), TYPE_PRECISION (inner_type),
+ TYPE_SIGN (inner_type));
+
+ wide_int wmin0, wmax0;
+ if (get_range_info (@0, &wmin0, &wmax0) == VR_RANGE)
+ {
+ wi::add (wmin0, w1, TYPE_SIGN (inner_type), &min_ovf);
+ wi::add (wmax0, w1, TYPE_SIGN (inner_type), &max_ovf);
+ }
+ }
+ (if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE)
+ (convert (plus @0 { wide_int_to_tree (TREE_TYPE (@0), w1); } )))
+ )))
+#endif
/* ~A + A -> -1 */
(simplify
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c 2020-03-12 19:07:22.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c 2020-11-24 14:49:14.568000000 +0800
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-ch2-details" } */
+/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-ch2-details" } */
int is_sorted(int *a, int n)
{
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c 2020-03-12 19:07:22.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c 2020-11-24 14:49:14.568000000 +0800
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-ch2-details --param logical-op-non-short-circuit=0" } */
+/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-ch2-details --param logical-op-non-short-circuit=0" } */
int is_sorted(int *a, int n, int m, int k)
{
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c 2020-03-12 19:07:22.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c 2020-11-24 14:49:14.568000000 +0800
@@ -19,7 +19,7 @@ int bla(void)
}
/* Since the loop is removed, there should be no addition. */
-/* { dg-final { scan-tree-dump-times " \\+ " 0 "optimized" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times " \\+ " 0 "optimized" } } */
/* { dg-final { scan-tree-dump-times " \\* " 1 "optimized" } } */
/* The if from the loop header copying remains in the code. */
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c 2020-03-12 19:07:22.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c 2020-11-24 14:49:14.568000000 +0800
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-ccp -fdisable-tree-evrp -fdump-tree-vrp1" } */
+/* { dg-options "-O2 -fno-tree-ccp -fdisable-tree-evrp -fdump-tree-vrp1-details" } */
void h (void);
@@ -17,4 +17,4 @@ int g (int i, int j)
return 1;
}
-/* { dg-final { scan-tree-dump-times "Folding predicate.*to 1" 1 "vrp1" } } */
+/* { dg-final { scan-tree-dump-times "gimple_simplified" 1 "vrp1" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr92734-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr92734-2.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr92734-2.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr92734-2.c 2020-11-24 14:49:14.568000000 +0800
@@ -0,0 +1,76 @@
+/* PR tree-optimization/92734 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* Verify there are no binary additions or subtractions left. There can
+ be just casts and negations. */
+/* { dg-final { scan-tree-dump-not " \[+-] " "optimized" } } */
+
+int
+f1 (int x, unsigned y)
+{
+ int a = x + y;
+ return a - x;
+}
+
+unsigned
+f2 (unsigned x, int y)
+{
+ unsigned a = (int) x + y;
+ return a - x;
+}
+
+int
+f3 (int x, unsigned y)
+{
+ int a = x - y;
+ return a - x;
+}
+
+unsigned
+f4 (unsigned x, int y)
+{
+ unsigned a = (int) x - y;
+ return a - x;
+}
+
+int
+f5 (unsigned x, int y)
+{
+ int a = x - y;
+ return a + y;
+}
+
+unsigned
+f6 (int x, unsigned y)
+{
+ unsigned a = x - (int) y;
+ return a + y;
+}
+
+int
+f7 (int x, unsigned y)
+{
+ int a = x + y;
+ return x - a;
+}
+
+unsigned
+f8 (unsigned x, int y)
+{
+ unsigned a = (int) x + y;
+ return x - a;
+}
+
+int
+f9 (int x, unsigned y)
+{
+ int a = x - y;
+ return x - a;
+}
+
+unsigned
+f10 (unsigned x, int y)
+{
+ unsigned a = (int) x - y;
+ return x - a;
+}
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr92734.c b/gcc/testsuite/gcc.dg/tree-ssa/pr92734.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr92734.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr92734.c 2020-11-24 14:49:14.568000000 +0800
@@ -0,0 +1,31 @@
+/* PR tree-optimization/92734 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1" } */
+/* { dg-final { scan-tree-dump-times "return t_\[0-9]*\\\(D\\\);" 4 "forwprop1" } } */
+
+int
+f1 (int t)
+{
+ return 1 - (int) (1U - t);
+}
+
+int
+f2 (int t)
+{
+ int a = 7U - t;
+ return 7 - a;
+}
+
+int
+f3 (int t)
+{
+ int a = 32U - t;
+ return 32 - a;
+}
+
+int
+f4 (int t)
+{
+ int a = 32 - t;
+ return (int) (32 - (unsigned) a);
+}
diff -Nurp a/gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-3.c 2020-11-24 14:49:14.568000000 +0800
@@ -0,0 +1,45 @@
+/* PR tree-optimization/94718 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " \\\(int\\\) " 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \\\(unsigned int\\\) " 2 "optimized" } } */
+
+int
+f1 (int x, int y)
+{
+ return (int) ((unsigned) x | (unsigned) y);
+}
+
+int
+f2 (int x, int y)
+{
+ unsigned a = x;
+ unsigned b = y;
+ return a | b;
+}
+
+int
+f3 (int x, unsigned y)
+{
+ return (int) ((unsigned) x | y);
+}
+
+int
+f4 (int x, unsigned y)
+{
+ unsigned a = x;
+ return a | y;
+}
+
+unsigned
+f5 (int x, unsigned y)
+{
+ return (unsigned) (x | (int) y);
+}
+
+unsigned
+f6 (int x, unsigned y)
+{
+ int a = y;
+ return x | a;
+}
diff -Nurp a/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c b/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c
--- a/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c 2020-11-24 14:49:14.484000000 +0800
@@ -0,0 +1,43 @@
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* s390*-*-* } && lp64 } } } */
+/* { dg-options "-O2 -fdump-tree-vrp2-details" } */
+/* { dg-final { scan-tree-dump-times "gimple_simplified to" 4 "vrp2" } } */
+
+void v1 (unsigned long *in, unsigned long *out, unsigned int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ out[i] = in[i];
+ }
+}
+
+void v2 (unsigned long *in, unsigned long *out, int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ out[i] = in[i];
+ }
+}
+
+void v3 (unsigned long *in, unsigned long *out, unsigned int n)
+{
+ unsigned int i;
+
+ for (i = 0; i < n; i++)
+ {
+ out[i] = in[i];
+ }
+}
+
+void v4 (unsigned long *in, unsigned long *out, int n)
+{
+ unsigned int i;
+
+ for (i = 0; i < n; i++)
+ {
+ out[i] = in[i];
+ }
+}
diff -Nurp a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
--- a/gcc/tree-ssa-propagate.c 2020-11-24 14:54:42.556000000 +0800
+++ b/gcc/tree-ssa-propagate.c 2020-11-24 14:49:12.792000000 +0800
@@ -814,7 +814,6 @@ ssa_propagation_engine::ssa_propagate (v
ssa_prop_fini ();
}
-
/* Return true if STMT is of the form 'mem_ref = RHS', where 'mem_ref'
is a non-volatile pointer dereference, a structure reference or a
reference to a single _DECL. Ignore volatile memory references
@@ -1071,6 +1070,14 @@ substitute_and_fold_dom_walker::before_d
stmt = gsi_stmt (i);
gimple_set_modified (stmt, true);
}
+ /* Also fold if we want to fold all statements. */
+ else if (substitute_and_fold_engine->fold_all_stmts
+ && fold_stmt (&i, follow_single_use_edges))
+ {
+ did_replace = true;
+ stmt = gsi_stmt (i);
+ gimple_set_modified (stmt, true);
+ }
/* Some statements may be simplified using propagator
specific information. Do this before propagating
diff -Nurp a/gcc/tree-ssa-propagate.h b/gcc/tree-ssa-propagate.h
--- a/gcc/tree-ssa-propagate.h 2020-03-12 19:07:23.000000000 +0800
+++ b/gcc/tree-ssa-propagate.h 2020-11-24 14:49:12.792000000 +0800
@@ -100,6 +100,8 @@ class ssa_propagation_engine
class substitute_and_fold_engine
{
public:
+ substitute_and_fold_engine (bool fold_all_stmts = false)
+ : fold_all_stmts (fold_all_stmts) { }
virtual ~substitute_and_fold_engine (void) { }
virtual bool fold_stmt (gimple_stmt_iterator *) { return false; }
virtual tree get_value (tree) { return NULL_TREE; }
@@ -107,6 +109,10 @@ class substitute_and_fold_engine
bool substitute_and_fold (basic_block = NULL);
bool replace_uses_in (gimple *);
bool replace_phi_args_in (gphi *);
+
+ /* Users like VRP can set this when they want to perform
+ folding for every propagation. */
+ bool fold_all_stmts;
};
#endif /* _TREE_SSA_PROPAGATE_H */
diff -Nurp a/gcc/tree-vrp.c b/gcc/tree-vrp.c
--- a/gcc/tree-vrp.c 2020-11-24 14:54:43.564000000 +0800
+++ b/gcc/tree-vrp.c 2020-11-24 14:49:12.792000000 +0800
@@ -6384,6 +6384,7 @@ vrp_prop::visit_phi (gphi *phi)
class vrp_folder : public substitute_and_fold_engine
{
public:
+ vrp_folder () : substitute_and_fold_engine (/* Fold all stmts. */ true) { }
tree get_value (tree) FINAL OVERRIDE;
bool fold_stmt (gimple_stmt_iterator *) FINAL OVERRIDE;
bool fold_predicate_in (gimple_stmt_iterator *);

View File

@ -1,108 +0,0 @@
commit f6e1a4cd83190746b6544917f7526fa480ca5f18
Author: Bin Cheng <bin.cheng@linux.alibaba.com>
Date: Wed May 13 11:37:47 2020 +0800
Add missing unit dependence vector in data dependence analysis
Current data dependence analysis misses unit distant vector if DRs in
DDR have the same invariant access functions. This adds the vector as
the constant access function case.
2020-05-13 Bin Cheng <bin.cheng@linux.alibaba.com>
PR tree-optimization/94969
gcc/
* tree-data-dependence.c (constant_access_functions): Rename to...
(invariant_access_functions): ...this. Add parameter. Check for
invariant access function, rather than constant.
(build_classic_dist_vector): Call above function.
* tree-loop-distribution.c (pg_add_dependence_edges): Add comment.
gcc/testsuite/
* gcc.dg/tree-ssa/pr94969.c: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94969.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94969.c
new file mode 100644
index 00000000000..056b015f97c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94969.c
@@ -0,0 +1,28 @@
+/* PR tree-optimization/52267 */
+/* { dg-do run } */
+/* { dg-options "-O3 -fdump-tree-ldist-details" } */
+
+int a = 0, b = 0, c = 0;
+struct S {
+ signed m : 7;
+ signed e : 2;
+};
+struct S f[2] = {{0, 0}, {0, 0}};
+struct S g = {0, 0};
+
+void __attribute__((noinline))
+k()
+{
+ for (; c <= 1; c++) {
+ f[b] = g;
+ f[b].e ^= 1;
+ }
+}
+int main()
+{
+ k();
+ if (f[b].e != 1)
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-tree-dump-not "ldist" "Loop 1 distributed: split to 3 loops"} } */
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 851225e1171..5505ba46778 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -4821,17 +4821,19 @@ build_classic_dist_vector_1 (struct data_dependence_relation *ddr,
return true;
}
-/* Return true when the DDR contains only constant access functions. */
+/* Return true when the DDR contains only invariant access functions wrto. loop
+ number LNUM. */
static bool
-constant_access_functions (const struct data_dependence_relation *ddr)
+invariant_access_functions (const struct data_dependence_relation *ddr,
+ int lnum)
{
unsigned i;
subscript *sub;
FOR_EACH_VEC_ELT (DDR_SUBSCRIPTS (ddr), i, sub)
- if (!evolution_function_is_constant_p (SUB_ACCESS_FN (sub, 0))
- || !evolution_function_is_constant_p (SUB_ACCESS_FN (sub, 1)))
+ if (!evolution_function_is_invariant_p (SUB_ACCESS_FN (sub, 0), lnum)
+ || !evolution_function_is_invariant_p (SUB_ACCESS_FN (sub, 1), lnum))
return false;
return true;
@@ -5030,7 +5032,7 @@ build_classic_dist_vector (struct data_dependence_relation *ddr,
dist_v = lambda_vector_new (DDR_NB_LOOPS (ddr));
save_dist_v (ddr, dist_v);
- if (constant_access_functions (ddr))
+ if (invariant_access_functions (ddr, loop_nest->num))
add_distance_for_zero_overlaps (ddr);
if (DDR_NB_LOOPS (ddr) > 1)
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 44423215332..b122c3964a0 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -2080,7 +2080,8 @@ loop_distribution::pg_add_dependence_edges (struct graph *rdg, int dir,
this_dir = -this_dir;
/* Known dependences can still be unordered througout the
- iteration space, see gcc.dg/tree-ssa/ldist-16.c. */
+ iteration space, see gcc.dg/tree-ssa/ldist-16.c and
+ gcc.dg/tree-ssa/pr94969.c. */
if (DDR_NUM_DIST_VECTS (ddr) != 1)
this_dir = 2;
/* If the overlap is exact preserve stmt order. */

View File

@ -1,55 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-optimization-94949-fix-load-eliding-in-SM.patch
0424a5ece5307cc22bbc0fe97edf4707d7a798ed
diff -Nurp a/gcc/testsuite/gcc.dg/torture/pr94949.c b/gcc/testsuite/gcc.dg/torture/pr94949.c
--- a/gcc/testsuite/gcc.dg/torture/pr94949.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/torture/pr94949.c 2020-08-24 21:40:32.208000000 +0800
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fallow-store-data-races" } */
+
+static int x = 1;
+static volatile int y = -1;
+int
+main()
+{
+ for (int i = 0; i < 128; ++i)
+ {
+ if (i == y)
+ x = i;
+ }
+ if (x != 1)
+ __builtin_abort ();
+ return 0;
+}
diff -Nurp a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
--- a/gcc/tree-ssa-loop-im.c 2020-08-24 21:40:14.164000000 +0800
+++ b/gcc/tree-ssa-loop-im.c 2020-08-24 21:40:32.208000000 +0800
@@ -2115,9 +2115,9 @@ execute_sm (struct loop *loop, vec<edge>
fmt_data.orig_loop = loop;
for_each_index (&ref->mem.ref, force_move_till, &fmt_data);
+ bool always_stored = ref_always_accessed_p (loop, ref, true);
if (bb_in_transaction (loop_preheader_edge (loop)->src)
- || (! flag_store_data_races
- && ! ref_always_accessed_p (loop, ref, true)))
+ || (! flag_store_data_races && ! always_stored))
multi_threaded_model_p = true;
if (multi_threaded_model_p)
@@ -2132,8 +2132,10 @@ execute_sm (struct loop *loop, vec<edge>
/* Avoid doing a load if there was no load of the ref in the loop.
Esp. when the ref is not always stored we cannot optimize it
- away later. */
- if (ref->loaded && bitmap_bit_p (ref->loaded, loop->num))
+ away later. But when it is not always stored we must use a conditional
+ store then. */
+ if ((!always_stored && !multi_threaded_model_p)
+ || (ref->loaded && bitmap_bit_p (ref->loaded, loop->num)))
{
load = gimple_build_assign (tmp_var, unshare_expr (ref->mem.ref));
lim_data = init_lim_data (load);

View File

@ -1,69 +0,0 @@
This backport contains 1 patch from gcc main stream tree. ^M
The commit id of these patchs list as following in the order of time.
0001-Make-ifcvt-clean-up-dead-comparisons.patch
f1f10541903b082d27114db38947fb31f5364bcc
diff -Nurp a/gcc/basic-block.h b/gcc/basic-block.h
--- a/gcc/basic-block.h 2020-09-12 14:42:34.268000000 +0800
+++ b/gcc/basic-block.h 2020-09-12 14:42:48.448000000 +0800
@@ -507,6 +507,8 @@ ei_cond (edge_iterator ei, edge *p)
#define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */
#define CLEANUP_CFG_CHANGED 64 /* The caller changed the CFG. */
#define CLEANUP_NO_PARTITIONING 128 /* Do not try to fix partitions. */
+#define CLEANUP_FORCE_FAST_DCE 0x100 /* Force run_fast_dce to be called
+ at least once. */
/* Return true if BB is in a transaction. */
diff -Nurp a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
--- a/gcc/cfgcleanup.c 2020-09-12 14:42:34.292000000 +0800
+++ b/gcc/cfgcleanup.c 2020-09-12 14:42:48.448000000 +0800
@@ -3197,7 +3197,10 @@ cleanup_cfg (int mode)
&& !delete_trivially_dead_insns (get_insns (), max_reg_num ()))
break;
if ((mode & CLEANUP_CROSSJUMP) && crossjumps_occurred)
- run_fast_dce ();
+ {
+ run_fast_dce ();
+ mode &= ~CLEANUP_FORCE_FAST_DCE;
+ }
}
else
break;
@@ -3206,6 +3209,9 @@ cleanup_cfg (int mode)
if (mode & CLEANUP_CROSSJUMP)
remove_fake_exit_edges ();
+ if (mode & CLEANUP_FORCE_FAST_DCE)
+ run_fast_dce ();
+
/* Don't call delete_dead_jumptables in cfglayout mode, because
that function assumes that jump tables are in the insns stream.
But we also don't _have_ to delete dead jumptables in cfglayout
diff -Nurp a/gcc/ifcvt.c b/gcc/ifcvt.c
--- a/gcc/ifcvt.c 2020-09-12 14:42:34.300000000 +0800
+++ b/gcc/ifcvt.c 2020-09-12 14:42:48.448000000 +0800
@@ -5457,6 +5457,8 @@ if_convert (bool after_combine)
static unsigned int
rest_of_handle_if_conversion (void)
{
+ int flags = 0;
+
if (flag_if_conversion)
{
if (dump_file)
@@ -5466,9 +5468,12 @@ rest_of_handle_if_conversion (void)
}
cleanup_cfg (CLEANUP_EXPENSIVE);
if_convert (false);
+ if (num_updated_if_blocks)
+ /* Get rid of any dead CC-related instructions. */
+ flags |= CLEANUP_FORCE_FAST_DCE;
}
- cleanup_cfg (0);
+ cleanup_cfg (flags);
return 0;
}

View File

@ -1,74 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-optimization-98117-fix-range-set-by-vectorizati.patch
cdcbef3c3310a14f2994982b44cb1f8e14c77232
diff --git a/gcc/testsuite/gcc.dg/torture/pr98117.c b/gcc/testsuite/gcc.dg/torture/pr98117.c
new file mode 100644
index 00000000000..f2160257263
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr98117.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fno-tree-scev-cprop" } */
+
+unsigned char c;
+void __attribute__((noipa))
+e()
+{
+ do
+ {
+ }
+ while (++c);
+}
+int main()
+{
+ e();
+ if (c != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 36179188f6d..2370b879b21 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -2034,13 +2034,29 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters,
niters_vector = force_gimple_operand (niters_vector, &stmts, true, var);
gsi_insert_seq_on_edge_immediate (pe, stmts);
/* Peeling algorithm guarantees that vector loop bound is at least ONE,
- we set range information to make niters analyzer's life easier. */
+ we set range information to make niters analyzer's life easier.
+ Note the number of latch iteration value can be TYPE_MAX_VALUE so
+ we have to represent the vector niter TYPE_MAX_VALUE + 1 >> log_vf. */
if (stmts != NULL && log_vf)
- set_range_info (niters_vector, VR_RANGE,
- wi::to_wide (build_int_cst (type, 1)),
- wi::to_wide (fold_build2 (RSHIFT_EXPR, type,
- TYPE_MAX_VALUE (type),
- log_vf)));
+ {
+ if (niters_no_overflow)
+ set_range_info (niters_vector, VR_RANGE,
+ wi::one (TYPE_PRECISION (type)),
+ wi::rshift (wi::max_value (TYPE_PRECISION (type),
+ TYPE_SIGN (type)),
+ exact_log2 (const_vf),
+ TYPE_SIGN (type)));
+ /* For VF == 1 the vector IV might also overflow so we cannot
+ assert a minimum value of 1. */
+ else if (const_vf > 1)
+ set_range_info (niters_vector, VR_RANGE,
+ wi::one (TYPE_PRECISION (type)),
+ wi::rshift (wi::max_value (TYPE_PRECISION (type),
+ TYPE_SIGN (type))
+ - (const_vf - 1),
+ exact_log2 (const_vf), TYPE_SIGN (type))
+ + 1);
+ }
}
*niters_vector_ptr = niters_vector;
*step_vector_ptr = step_vector;
--
2.19.1

View File

@ -1,18 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-PR93561-bounds-checking-memory-overflow-for-spill_fo.patch:
d26f37a16e3ed3d75a93ffb1da10c44c36a8a36d
diff -Nurp a/gcc/lra-assigns.c b/gcc/lra-assigns.c
--- a/gcc/lra-assigns.c 2020-04-17 16:27:46.192000000 +0800
+++ b/gcc/lra-assigns.c 2020-04-17 16:29:37.125688580 +0800
@@ -968,6 +968,8 @@ spill_for (int regno, bitmap spilled_pse
bitmap_clear (&spill_pseudos_bitmap);
for (j = hard_regno_nregs (hard_regno, mode) - 1; j >= 0; j--)
{
+ if (hard_regno + j >= FIRST_PSEUDO_REGISTER)
+ break;
if (try_hard_reg_pseudos_check[hard_regno + j] != curr_pseudo_check)
continue;
lra_assert (!bitmap_empty_p (&try_hard_reg_pseudos[hard_regno + j]));

View File

@ -1,371 +0,0 @@
This backport contains 3 patchs from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-tree-ssa-dse.c-initialize_ao_ref_for_dse-Handle-_chk.patch
4a61cf9c62212fd04f21704efc2decffe9544651
0002-tree-ssa-dse.c-initialize_ao_ref_for_dse-Fix-formatt.patch
caffb6e56c2914e64e65f3c336b770c178f265a3
0003-tree-ssa-dse.c-initialize_ao_ref_for_dse-Handle-strn.patch
192ece9e15d25fd9b6534b2a8bd271684bf76d38
diff --git a/gcc/testsuite/gcc.c-torture/execute/builtins/builtins.exp b/gcc/testsuite/gcc.c-torture/execute/builtins/builtins.exp
index 3560a1ff2..e9d3c9aab 100644
--- a/gcc/testsuite/gcc.c-torture/execute/builtins/builtins.exp
+++ b/gcc/testsuite/gcc.c-torture/execute/builtins/builtins.exp
@@ -37,7 +37,7 @@ load_lib c-torture.exp
torture-init
set-torture-options $C_TORTURE_OPTIONS {{}} $LTO_TORTURE_OPTIONS
-set additional_flags "-fno-tree-loop-distribute-patterns -fno-tracer -fno-ipa-ra -fno-inline-functions"
+set additional_flags "-fno-tree-dse -fno-tree-loop-distribute-patterns -fno-tracer -fno-ipa-ra -fno-inline-functions"
if [istarget "powerpc-*-darwin*"] {
lappend additional_flags "-Wl,-multiply_defined,suppress"
}
diff --git a/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c b/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c
index afd07ddd0..40cfa0472 100644
--- a/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c
+++ b/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c
@@ -1,7 +1,7 @@
/* Test whether buffer overflow warnings for __*_chk builtins
are emitted properly. */
/* { dg-do compile } */
-/* { dg-options "-O2 -Wno-format -std=gnu99 -ftrack-macro-expansion=0" } */
+/* { dg-options "-O2 -Wno-format -std=gnu99 -ftrack-macro-expansion=0 -fno-tree-dse" } */
// { dg-skip-if "packed attribute missing for t" { "epiphany-*-*" } }
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/memcpy-2.c b/gcc/testsuite/gcc.dg/memcpy-2.c
index 7f839d27a..6ad887416 100644
--- a/gcc/testsuite/gcc.dg/memcpy-2.c
+++ b/gcc/testsuite/gcc.dg/memcpy-2.c
@@ -1,6 +1,6 @@
/* PR middle-end/38454 */
/* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fno-tree-dse" } */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/pr40340-1.c b/gcc/testsuite/gcc.dg/pr40340-1.c
index 8fbb206a2..6307e064c 100644
--- a/gcc/testsuite/gcc.dg/pr40340-1.c
+++ b/gcc/testsuite/gcc.dg/pr40340-1.c
@@ -1,6 +1,6 @@
/* PR middle-end/40340 */
/* { dg-do compile } */
-/* { dg-options "-O2 -Wall -Wno-system-headers" } */
+/* { dg-options "-O2 -Wall -Wno-system-headers -fno-tree-dse" } */
#include "pr40340.h"
diff --git a/gcc/testsuite/gcc.dg/pr40340-2.c b/gcc/testsuite/gcc.dg/pr40340-2.c
index 10083acd1..ea76e1008 100644
--- a/gcc/testsuite/gcc.dg/pr40340-2.c
+++ b/gcc/testsuite/gcc.dg/pr40340-2.c
@@ -1,6 +1,6 @@
/* PR middle-end/40340 */
/* { dg-do compile } */
-/* { dg-options "-O2 -Wall -Wno-system-headers" } */
+/* { dg-options "-O2 -Wall -Wno-system-headers -fno-tree-dse" } */
#include "pr40340.h"
diff --git a/gcc/testsuite/gcc.dg/pr40340-5.c b/gcc/testsuite/gcc.dg/pr40340-5.c
index 0e48a2ca9..99e58f2ab 100644
--- a/gcc/testsuite/gcc.dg/pr40340-5.c
+++ b/gcc/testsuite/gcc.dg/pr40340-5.c
@@ -1,6 +1,6 @@
/* PR middle-end/40340 */
/* { dg-do compile } */
-/* { dg-options "-O2 -Wall -Wsystem-headers -g" } */
+/* { dg-options "-O2 -Wall -Wsystem-headers -g -fno-tree-dse" } */
#define TEST3
#include "pr40340.h"
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c
new file mode 100644
index 000000000..56251fc34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c
@@ -0,0 +1,60 @@
+/* { dg-options "-O2 -fdump-tree-dse-details -fno-tree-fre" } */
+
+
+#ifndef SCOPE
+#define SCOPE
+#endif
+
+extern void frob (char *);
+
+void g (char *s)
+{
+ SCOPE char a[8];
+ __builtin_strncpy (a, s, sizeof a);
+ __builtin_memset (a, 0, sizeof a);
+ frob (a);
+}
+
+void h (char *s)
+{
+ SCOPE char a[8];
+ __builtin_memset (a, 0, sizeof a);
+ __builtin_strncpy (a, s, sizeof a);
+ frob (a);
+}
+
+void i (char *s)
+{
+ SCOPE char a[8];
+ __builtin_strncpy (a, s, sizeof a);
+ __builtin_memset (a, 0, sizeof a - 5);
+ frob (a);
+}
+
+void j (char *s)
+{
+ SCOPE char a[8];
+ __builtin_memset (a, 0, sizeof a);
+ __builtin_strncpy (a, s, sizeof a - 5);
+ frob (a);
+}
+
+void l (char *s)
+{
+ SCOPE char a[8];
+ __builtin_strncpy (a, s, sizeof a);
+ __builtin_memset (a + 2, 0, sizeof a - 2);
+ frob (a);
+}
+
+void m (char *s)
+{
+ SCOPE char a[8];
+ __builtin_memset (a, 0, sizeof a);
+ __builtin_strncpy (a + 2, s, sizeof a - 2);
+ frob (a);
+}
+
+/* { dg-final { scan-tree-dump-times "Deleted dead call" 2 "dse1" } } */
+/* { dg-final { scan-tree-dump-times "Trimming statement " 4 "dse1" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c
new file mode 100644
index 000000000..7ae33bfd1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c
@@ -0,0 +1,12 @@
+/* { dg-options "-O2 -fdump-tree-dse-details -fno-tree-fre" } */
+
+
+/* This changes the scope of the destination object and exposes
+ missed optimizations in DSE. */
+#define SCOPE extern
+#include "ssa-dse-37.c"
+
+/* { dg-final { scan-tree-dump-times "Deleted dead call" 2 "dse1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Trimming statement " 4 "dse1" { xfail *-*-* } } } */
+
+
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 2fb471b69..b593b0d81 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -100,39 +100,42 @@ initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write)
{
switch (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)))
{
- case BUILT_IN_MEMCPY:
- case BUILT_IN_MEMMOVE:
- case BUILT_IN_MEMSET:
- {
- tree size = NULL_TREE;
- if (gimple_call_num_args (stmt) == 3)
- size = gimple_call_arg (stmt, 2);
- tree ptr = gimple_call_arg (stmt, 0);
- ao_ref_init_from_ptr_and_size (write, ptr, size);
- return true;
- }
+ case BUILT_IN_MEMCPY:
+ case BUILT_IN_MEMMOVE:
+ case BUILT_IN_MEMSET:
+ case BUILT_IN_MEMCPY_CHK:
+ case BUILT_IN_MEMMOVE_CHK:
+ case BUILT_IN_MEMSET_CHK:
+ case BUILT_IN_STRNCPY:
+ case BUILT_IN_STRNCPY_CHK:
+ {
+ tree size = gimple_call_arg (stmt, 2);
+ tree ptr = gimple_call_arg (stmt, 0);
+ ao_ref_init_from_ptr_and_size (write, ptr, size);
+ return true;
+ }
- /* A calloc call can never be dead, but it can make
- subsequent stores redundant if they store 0 into
- the same memory locations. */
- case BUILT_IN_CALLOC:
- {
- tree nelem = gimple_call_arg (stmt, 0);
- tree selem = gimple_call_arg (stmt, 1);
- tree lhs;
- if (TREE_CODE (nelem) == INTEGER_CST
- && TREE_CODE (selem) == INTEGER_CST
- && (lhs = gimple_call_lhs (stmt)) != NULL_TREE)
- {
- tree size = fold_build2 (MULT_EXPR, TREE_TYPE (nelem),
- nelem, selem);
- ao_ref_init_from_ptr_and_size (write, lhs, size);
- return true;
- }
- }
+ /* A calloc call can never be dead, but it can make
+ subsequent stores redundant if they store 0 into
+ the same memory locations. */
+ case BUILT_IN_CALLOC:
+ {
+ tree nelem = gimple_call_arg (stmt, 0);
+ tree selem = gimple_call_arg (stmt, 1);
+ tree lhs;
+ if (TREE_CODE (nelem) == INTEGER_CST
+ && TREE_CODE (selem) == INTEGER_CST
+ && (lhs = gimple_call_lhs (stmt)) != NULL_TREE)
+ {
+ tree size = fold_build2 (MULT_EXPR, TREE_TYPE (nelem),
+ nelem, selem);
+ ao_ref_init_from_ptr_and_size (write, lhs, size);
+ return true;
+ }
+ }
- default:
- break;
+ default:
+ break;
}
}
else if (is_gimple_assign (stmt))
@@ -459,6 +462,10 @@ maybe_trim_memstar_call (ao_ref *ref, sbitmap live, gimple *stmt)
{
case BUILT_IN_MEMCPY:
case BUILT_IN_MEMMOVE:
+ case BUILT_IN_STRNCPY:
+ case BUILT_IN_MEMCPY_CHK:
+ case BUILT_IN_MEMMOVE_CHK:
+ case BUILT_IN_STRNCPY_CHK:
{
int head_trim, tail_trim;
compute_trims (ref, live, &head_trim, &tail_trim, stmt);
@@ -480,6 +487,7 @@ maybe_trim_memstar_call (ao_ref *ref, sbitmap live, gimple *stmt)
}
case BUILT_IN_MEMSET:
+ case BUILT_IN_MEMSET_CHK:
{
int head_trim, tail_trim;
compute_trims (ref, live, &head_trim, &tail_trim, stmt);
@@ -956,54 +964,60 @@ dse_dom_walker::dse_optimize_stmt (gimple_stmt_iterator *gsi)
tree fndecl = gimple_call_fndecl (stmt);
switch (DECL_FUNCTION_CODE (fndecl))
{
- case BUILT_IN_MEMCPY:
- case BUILT_IN_MEMMOVE:
- case BUILT_IN_MEMSET:
- {
- /* Occasionally calls with an explicit length of zero
- show up in the IL. It's pointless to do analysis
- on them, they're trivially dead. */
- tree size = gimple_call_arg (stmt, 2);
- if (integer_zerop (size))
- {
- delete_dead_or_redundant_call (gsi, "dead");
- return;
- }
-
- /* If this is a memset call that initializes an object
- to zero, it may be redundant with an earlier memset
- or empty CONSTRUCTOR of a larger object. */
- if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMSET
- || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMSET_CHK)
- && integer_zerop (gimple_call_arg (stmt, 1)))
- dse_optimize_redundant_stores (stmt);
-
- enum dse_store_status store_status;
- m_byte_tracking_enabled
- = setup_live_bytes_from_ref (&ref, m_live_bytes);
- store_status = dse_classify_store (&ref, stmt,
- m_byte_tracking_enabled,
- m_live_bytes);
- if (store_status == DSE_STORE_LIVE)
- return;
-
- if (store_status == DSE_STORE_MAYBE_PARTIAL_DEAD)
- {
- maybe_trim_memstar_call (&ref, m_live_bytes, stmt);
- return;
- }
-
- if (store_status == DSE_STORE_DEAD)
+ case BUILT_IN_MEMCPY:
+ case BUILT_IN_MEMMOVE:
+ case BUILT_IN_STRNCPY:
+ case BUILT_IN_MEMSET:
+ case BUILT_IN_MEMCPY_CHK:
+ case BUILT_IN_MEMMOVE_CHK:
+ case BUILT_IN_STRNCPY_CHK:
+ case BUILT_IN_MEMSET_CHK:
+ {
+ /* Occasionally calls with an explicit length of zero
+ show up in the IL. It's pointless to do analysis
+ on them, they're trivially dead. */
+ tree size = gimple_call_arg (stmt, 2);
+ if (integer_zerop (size))
+ {
delete_dead_or_redundant_call (gsi, "dead");
+ return;
+ }
+
+ /* If this is a memset call that initializes an object
+ to zero, it may be redundant with an earlier memset
+ or empty CONSTRUCTOR of a larger object. */
+ if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMSET
+ || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMSET_CHK)
+ && integer_zerop (gimple_call_arg (stmt, 1)))
+ dse_optimize_redundant_stores (stmt);
+
+ enum dse_store_status store_status;
+ m_byte_tracking_enabled
+ = setup_live_bytes_from_ref (&ref, m_live_bytes);
+ store_status = dse_classify_store (&ref, stmt,
+ m_byte_tracking_enabled,
+ m_live_bytes);
+ if (store_status == DSE_STORE_LIVE)
return;
- }
- case BUILT_IN_CALLOC:
- /* We already know the arguments are integer constants. */
- dse_optimize_redundant_stores (stmt);
+ if (store_status == DSE_STORE_MAYBE_PARTIAL_DEAD)
+ {
+ maybe_trim_memstar_call (&ref, m_live_bytes, stmt);
+ return;
+ }
- default:
+ if (store_status == DSE_STORE_DEAD)
+ delete_dead_or_redundant_call (gsi, "dead");
return;
+ }
+
+ case BUILT_IN_CALLOC:
+ /* We already know the arguments are integer constants. */
+ dse_optimize_redundant_stores (stmt);
+ return;
+
+ default:
+ return;
}
}

View File

@ -1,71 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-bootstrap-92301-Wrong-vectorizer-code-since-r2.patch
b76f4e6c06bd494d2383c4c16d1e1a034da74641
diff -Nurp a/gcc/testsuite/gcc.dg/pr92301.c b/gcc/testsuite/gcc.dg/pr92301.c
--- a/gcc/testsuite/gcc.dg/pr92301.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/pr92301.c 2020-08-24 21:36:23.556000000 +0800
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+
+unsigned int m;
+
+#define N 128
+unsigned int a[N];
+
+unsigned int
+__attribute__((noipa))
+df_count_refs (_Bool include_defs)
+{
+ int size = 0;
+
+ for (unsigned int regno = 0; regno < m; regno++)
+ if (include_defs)
+ size += a[regno];
+ return size;
+}
+
+int main(int argc, char **argv)
+{
+ for (unsigned i = 0; i < N; i++)
+ a[i] = i;
+
+ if (argc == 1)
+ m = 17;
+
+ unsigned int r = df_count_refs(1);
+ __builtin_printf ("r: %d\n", r);
+ if (r != 136)
+ __builtin_abort ();
+
+ return 0;
+}
diff -Nurp a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
--- a/gcc/tree-vect-stmts.c 2020-08-24 21:35:23.664000000 +0800
+++ b/gcc/tree-vect-stmts.c 2020-08-24 21:36:23.556000000 +0800
@@ -474,6 +474,22 @@ process_use (stmt_vec_info stmt_vinfo, t
basic_block def_bb = gimple_bb (dstmt_vinfo->stmt);
basic_block bb = gimple_bb (stmt_vinfo->stmt);
+ /* case 2: A reduction phi (STMT) defined by a reduction stmt (DSTMT_VINFO).
+ We have to force the stmt live since the epilogue loop needs it to
+ continue computing the reduction. */
+ if (gimple_code (stmt_vinfo->stmt) == GIMPLE_PHI
+ && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
+ && gimple_code (dstmt_vinfo->stmt) != GIMPLE_PHI
+ && STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def
+ && bb->loop_father == def_bb->loop_father)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "reduc-stmt defining reduc-phi in the same nest.\n");
+ vect_mark_relevant (worklist, dstmt_vinfo, relevant, true);
+ return opt_result::success ();
+ }
+
/* case 3a: outer-loop stmt defining an inner-loop stmt:
outer-loop-header-bb:
d = dstmt_vinfo

596
gcc.spec
View File

@ -1,7 +1,7 @@
%global DATE 20210628 %global DATE 20210727
%global gcc_version 9.3.1 %global gcc_version 10.3.0
%global gcc_major 9.3.1 %global gcc_major 10.3.0
%global _unpackaged_files_terminate_build 0 %global _unpackaged_files_terminate_build 0
%global _performance_build 1 %global _performance_build 1
@ -13,7 +13,7 @@
%global build_go 0 %global build_go 0
%global build_d 0 %global build_d 0
%global build_check 0 %global build_check 0
%ifarch %{ix86} x86_64 ia64 ppc64le aarch64 %ifarch %{ix86} x86_64 ia64 ppc64le
%global build_libquadmath 1 %global build_libquadmath 1
%else %else
%global build_libquadmath 0 %global build_libquadmath 0
@ -38,7 +38,7 @@
%else %else
%global build_libubsan 0 %global build_libubsan 0
%endif %endif
%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 %{mips} %ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 %{mips} riscv64
%global build_libatomic 1 %global build_libatomic 1
%else %else
%global build_libatomic 0 %global build_libatomic 0
@ -59,24 +59,24 @@
Summary: Various compilers (C, C++, Objective-C, ...) Summary: Various compilers (C, C++, Objective-C, ...)
Name: gcc Name: gcc
Version: %{gcc_version} Version: %{gcc_version}
Release: %{DATE}.21 Release: %{DATE}.1
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD
URL: https://gcc.gnu.org URL: https://gcc.gnu.org
Source0: https://ftp.gnu.org/gnu/gcc/gcc-9.3.0/gcc-9.3.0.tar.xz Source0: https://ftp.gnu.org/gnu/gcc/gcc-10.3.0/gcc-10.3.0.tar.xz
%global isl_version 0.16.1 %global isl_version 0.16.1
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: binutils >= 2.31 BuildRequires: binutils >= 2.31
BuildRequires: glibc-headers BuildRequires: glibc-headers
BuildRequires: libtool, zlib-devel, texinfo, flex, bison BuildRequires: libtool, zlib-devel, texinfo, flex, bison
BuildRequires: gmp-devel >= 4.1.2-8, mpfr-devel >= 2.2.1, libmpc-devel >= 0.8.1 BuildRequires: gmp-devel >= 4.1.2-8, mpfr-devel >= 3.1.0, libmpc-devel >= 0.8.1
BuildRequires: gcc, gcc-c++ BuildRequires: gcc, gcc-c++, make
%if %{build_go} %if %{build_go}
BuildRequires: hostname, procps BuildRequires: hostname, procps
%endif %endif
BuildRequires: gdb BuildRequires: gdb
BuildRequires: glibc-devel >= 2.16 BuildRequires: glibc-devel >= 2.17
%ifarch %{multilib_64_archs} sparcv9 ppc %ifarch %{multilib_64_archs} sparcv9 ppc
BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so
%endif %endif
@ -102,7 +102,7 @@ BuildRequires: graphviz, dblatex, texlive-collection-latex, docbook5-style-xsl
Requires: cpp = %{version}-%{release} Requires: cpp = %{version}-%{release}
Requires: binutils >= 2.31 Requires: binutils >= 2.31
Conflicts: gdb < 5.1-2 Conflicts: gdb < 5.1-2
Requires: glibc-devel >= 2.16 Requires: glibc-devel >= 2.17
Requires: libgcc >= %{version}-%{release} Requires: libgcc >= %{version}-%{release}
Requires: libgomp = %{version}-%{release} Requires: libgomp = %{version}-%{release}
%if !%{build_ada} %if !%{build_ada}
@ -113,136 +113,14 @@ AutoReq: true
Provides: bundled(libiberty) Provides: bundled(libiberty)
Provides: gcc(major) = %{gcc_major} Provides: gcc(major) = %{gcc_major}
Patch0: enable-aarch64-libquadmath.patch
Patch1: generate-csel.patch
Patch2: delete-incorrect-smw.patch
Patch3: remove-array-index-inliner-hint.patch
Patch4: ivopts-1.patch
Patch5: ivopts-2.patch
Patch6: dont-generate-IF_THEN_ELSE.patch
Patch7: fix-cost-of-plus.patch
Patch8: div-opti.patch
Patch9: fix-SYMBOL_TINY_GOT-handling-for-ILP32.patch
Patch10: fix-ICE-during-pass-ccp.patch
Patch11: loop-split.patch
Patch12: loop-finite.patch
Patch13: loop-finite-bugfix.patch
Patch14: fix-regno-out-of-range.patch
Patch15: fix-ICE-in-vectorizable-load.patch
Patch16: address-calculation-optimization-within-loop.patch
Patch17: skip-debug-insns-when-computing-inline-costs.patch
Patch18: ipa-const-prop.patch
Patch19: ipa-const-prop-self-recursion-bugfix.patch
Patch20: ipa-const-prop-null-point-check-bugfix.patch
Patch21: change-gcc-BASE-VER.patch
Patch22: add-option-fallow-store-data-races.patch
Patch23: tighten-range-for-generating-csel.patch
Patch24: generate-csel-for-arrayref.patch
Patch25: vectorization-enhancement.patch
Patch26: ipa-struct-reorg.patch
Patch27: ipa-struct-reorg-bugfix.patch
Patch28: enable-simd-math.patch
Patch29: complete-struct-reorg.patch
Patch30: reductions-slp-enhancement.patch
Patch31: cse-in-vectorization.patch
Patch32: PR92303-Try-to-simplify-memory-subreg.patch
Patch33: Fix-PR94185.patch
Patch34: testsuite-Fix-pr94185.patch
Patch35: fix-ICE-in-vect_stmt_to_vectorize.patch
Patch36: add-checks-to-avoid-spoiling-if-conversion.patch
Patch37: fix-ICE-in-vect_create_epilog_for_reduction.patch
Patch38: fix-ICE-in-compute_live_loop_exits.patch
Patch39: fix-ICE-in-store_constructor.patch
Patch40: fix-ICE-in-verify_ssa.patch
Patch41: fix-ICE-in-reload.patch
Patch42: fix-ICE-in-declare-return-variable.patch
Patch43: simplify-removing-subregs.patch
Patch44: fix-ICE-in-vec.patch
Patch45: fix-ICE-in-gimple_op.patch
Patch46: fix-ICE-in-exact_div.patch
Patch47: fix-ICE-statement-uses-released-SSA-name.patch
Patch48: fix-ICE-in-vect_get_vec_def_for_stmt_copy.patch
Patch49: fix-ICE-in-vect_create_epilog_for_reduction_2.patch
Patch50: fix-ICE-in-vect_slp_analyze_node_operations.patch
Patch51: fix-ICE-in-vect_create_epilog_for_reduction_3.patch
Patch52: fix-ICE-avoid-issueing-loads-in-SM-when-possible.patch
Patch53: fix-ICE-in-vect_transform_stmt.patch
Patch54: fix-ICE-in-copy_reference_ops_from_ref.patch
Patch55: fix-ICE-in-vectorizable_condition.patch
Patch56: reduction-chain-slp-option.patch
Patch57: fix-ICE-in-model_update_limit_points_in_group.patch
Patch58: fix-do-not-build-op.patch
Patch59: fix-wrong-vectorizer-code.patch
Patch60: fix-load-eliding-in-SM.patch
Patch61: fix-SSA-update-for-vectorizer-epilogue.patch
Patch62: fix-ICE-when-vectorizing-nested-cycles.patch
Patch63: fix-avoid-bogus-uninit-warning-with-store-motion.patch
Patch64: avoid-cycling-on-vertain-subreg-reloads.patch
Patch65: fix-ICE-in-verify_target_availability.patch
Patch66: fix-ICE-vect_slp_analyze_node_operations.patch
Patch67: fix-ICE-in-extract_constrain_insn.patch
Patch68: fix-ICE-during-GIMPLE-pass-dse.patch
Patch69: ipa-const-prop-buffer-overflow-bugfix.patch
Patch70: fix-ICE-in-eliminate_stmt.patch
Patch71: fix-make-ifcvt-clean-up-dead-comparisons.patch
Patch72: fix-an-ICE-in-vect_recog_mask_conversion_pattern.patch
Patch73: fix-ICE-in-vect_update_misalignment_for_peel.patch
Patch74: redundant-loop-elimination.patch
Patch75: bf16-and-matrix-characteristic.patch
Patch76: medium-code-mode.patch
Patch77: tree-optimization-96920-another-ICE-when-vectorizing.patch
Patch78: reduction-paths-with-unhandled-live-stmt.patch
Patch79: aarch64-Fix-ash-lr-lshr-mode-3-expanders.patch
Patch80: tree-optimization-97812-fix-range-query-in-VRP-asser.patch
Patch81: aarch64-Fix-bf16-and-matrix-g++-gfortran.patch
Patch82: IRA-Handle-fully-tied-destinations.patch
Patch83: fix-ICE-in-pass-vect.patch
Patch84: SLP-VECT-Add-check-to-fix-96837.patch
Patch85: adjust-vector-cost-and-move-EXTRACT_LAST_REDUCTION-costing.patch
Patch86: fix-issue499-add-nop-convert.patch
Patch87: aarch64-fix-sve-acle-error.patch
Patch88: fix-ICE-IPA-compare-VRP-types.patch
Patch89: vectorizable-comparison-Swap-operands-only-once.patch
Patch90: sccvn-Improve-handling-of-load-masked-with-integer.patch
Patch91: speed-up-DDG-analysis-and-fix-bootstrap-compare-debug.patch
Patch92: x86-Fix-bf16-and-matrix.patch
Patch93: Fix-up-push_partial_def-little-endian-bitfield.patch
Patch94: modulo-sched-Carefully-process-loop-counter-initiali.patch
Patch95: fix-ICE-in-affine-combination.patch
Patch96: aarch64-Fix-mismatched-SVE-predicate-modes.patch
Patch97: Fix-EXTRACT_LAST_REDUCTION-segfault.patch
Patch98: fix-PR-92351-When-peeling-for-alignment.patch
Patch99: fix-addlosymdi-ICE-in-pass-reload.patch
Patch100: store-merging-Consider-also-overlapping-stores-earlier.patch
Patch101: AArch64-Fix-constraints-for-CPY-M.patch
Patch102: Fix-zero-masking-for-vcvtps2ph.patch
Patch103: re-PR-target-91124-gcc.target-i386-avx512vl-vpshldvd.patch
Patch104: fix-avx512vl-vcvttpd2dq-2-fail.patch
Patch105: fix-issue604-ldist-dependency-fixup.patch
Patch106: Apply-maximum-nunits-for-BB-SLP.patch
Patch107: Fix-interaction-between-aka-changes-and-DR1558.patch
Patch108: fix-range-set-by-vectorization-on-niter-IVs.patch
Patch109: optabs-Dont-use-scalar-conversions-for-vectors.patch
Patch110: add-fp-model-options.patch
Patch111: fix-CTOR-vectorization.patch
Patch112: PR92429-do-not-fold-when-updating.patch
Patch113: Handle-POLY_INT_CSTs-in-declare_return_value.patch
Patch114: Handle-POLY_INT_CST-in-copy_reference_ops_from_ref.patch
Patch115: fix-strncpy-inline-warning.patch
Patch116: fix-ICE-in-vect.patch
Patch118: Fix-type-mismatch-in-SLPed-constructors.patch
Patch119: add-check-for-pressure-in-sche1.patch
Patch120: revert-moutline-atomics.patch
Patch121: fix-ICE-in-eliminate-stmt.patch
Patch122: revise-type-before-build-MULT.patch
Patch123: Simplify-X-C1-C2.patch
%global gcc_target_platform %{_arch}-linux-gnu %global gcc_target_platform %{_arch}-linux-gnu
%if %{build_go} %if %{build_go}
# Avoid stripping these libraries and binaries. # Avoid stripping these libraries and binaries.
%global __os_install_post \ %global __os_install_post \
chmod 644 %{buildroot}%{_prefix}/%{_lib}/libgo.so.14.* \ chmod 644 %{buildroot}%{_prefix}/%{_lib}/libgo.so.16.* \
chmod 644 %{buildroot}%{_prefix}/bin/go.gcc \ chmod 644 %{buildroot}%{_prefix}/bin/go.gcc \
chmod 644 %{buildroot}%{_prefix}/bin/gofmt.gcc \ chmod 644 %{buildroot}%{_prefix}/bin/gofmt.gcc \
chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo \ chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo \
@ -250,7 +128,7 @@ chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/test2json \ chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/test2json \
chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/vet \ chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/vet \
%__os_install_post \ %__os_install_post \
chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgo.so.14.* \ chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgo.so.16.* \
chmod 755 %{buildroot}%{_prefix}/bin/go.gcc \ chmod 755 %{buildroot}%{_prefix}/bin/go.gcc \
chmod 755 %{buildroot}%{_prefix}/bin/gofmt.gcc \ chmod 755 %{buildroot}%{_prefix}/bin/gofmt.gcc \
chmod 755 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo \ chmod 755 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo \
@ -261,11 +139,11 @@ chmod 755 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
%endif %endif
%description %description
The gcc package contains the GNU Compiler Collection version 9. The gcc package contains the GNU Compiler Collection version 10.
You'll need this package in order to compile C code. You'll need this package in order to compile C code.
%package -n libgcc %package -n libgcc
Summary: GCC version 9 shared support library Summary: GCC version 10 shared support library
Autoreq: false Autoreq: false
%if !%{build_ada} %if !%{build_ada}
Obsoletes: libgnat < %{version}-%{release} Obsoletes: libgnat < %{version}-%{release}
@ -666,7 +544,7 @@ This package contains static Go libraries.
%package plugin-devel %package plugin-devel
Summary: Support for compiling GCC plugins Summary: Support for compiling GCC plugins
Requires: gcc = %{version}-%{release} Requires: gcc = %{version}-%{release}
Requires: gmp-devel >= 4.1.2-8, mpfr-devel >= 2.2.1, libmpc-devel >= 0.8.1 Requires: gmp-devel >= 4.1.2-8, mpfr-devel >= 3.1.0, libmpc-devel >= 0.8.1
%description plugin-devel %description plugin-devel
This package contains header files and other support files This package contains header files and other support files
@ -674,132 +552,9 @@ for compiling GCC plugins. The GCC plugin ABI is currently
not stable, so plugins must be rebuilt any time GCC is updated. not stable, so plugins must be rebuilt any time GCC is updated.
%prep %prep
%setup -q -n gcc-9.3.0 %setup -q -n gcc-10.3.0
/bin/pwd /bin/pwd
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1
%patch41 -p1
%patch42 -p1
%patch43 -p1
%patch44 -p1
%patch45 -p1
%patch46 -p1
%patch47 -p1
%patch48 -p1
%patch49 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
%patch53 -p1
%patch54 -p1
%patch55 -p1
%patch56 -p1
%patch57 -p1
%patch58 -p1
%patch59 -p1
%patch60 -p1
%patch61 -p1
%patch62 -p1
%patch63 -p1
%patch64 -p1
%patch65 -p1
%patch66 -p1
%patch67 -p1
%patch68 -p1
%patch69 -p1
%patch70 -p1
%patch71 -p1
%patch72 -p1
%patch73 -p1
%patch74 -p1
%patch75 -p1
%patch76 -p1
%patch77 -p1
%patch78 -p1
%patch79 -p1
%patch80 -p1
%patch81 -p1
%patch82 -p1
%patch83 -p1
%patch84 -p1
%patch85 -p1
%patch86 -p1
%patch87 -p1
%patch88 -p1
%patch89 -p1
%patch90 -p1
%patch91 -p1
%patch92 -p1
%patch93 -p1
%patch94 -p1
%patch95 -p1
%patch96 -p1
%patch97 -p1
%patch98 -p1
%patch99 -p1
%patch100 -p1
%patch101 -p1
%patch102 -p1
%patch103 -p1
%patch104 -p1
%patch105 -p1
%patch106 -p1
%patch107 -p1
%patch108 -p1
%patch109 -p1
%patch110 -p1
%patch111 -p1
%patch112 -p1
%patch113 -p1
%patch114 -p1
%patch115 -p1
%patch116 -p1
%patch118 -p1
%patch119 -p1
%patch120 -p1
%patch121 -p1
%patch122 -p1
%patch123 -p1
%build %build
@ -808,7 +563,8 @@ export CONFIG_SITE=NONE
CC=gcc CC=gcc
CXX=g++ CXX=g++
OPT_FLAGS=`echo %{optflags}|sed -e 's/-m64//g;s/-m32//g;s/-m31//g'` OPT_FLAGS=`echo %{optflags}|sed -e 's/-flto=auto//g;s/-flto//g;s/-ffat-lto-objects//g'`
OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-m64//g;s/-m32//g;s/-m31//g'`
OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mfpmath=sse/-mfpmath=sse -msse2/g'` OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mfpmath=sse/-mfpmath=sse -msse2/g'`
OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/ -pipe / /g'` OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/ -pipe / /g'`
OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-Werror=format-security/ /g'` OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-Werror=format-security/ /g'`
@ -825,7 +581,7 @@ OPT_FLAGS=`echo "$OPT_FLAGS" | sed -e 's/[[:blank:]]\+/ /g'`
case "$OPT_FLAGS" in case "$OPT_FLAGS" in
*-fasynchronous-unwind-tables*) *-fasynchronous-unwind-tables*)
sed -i -e 's/-fno-exceptions /-fno-exceptions -fno-asynchronous-unwind-tables /' \ sed -i -e 's/-fno-exceptions /-fno-exceptions -fno-asynchronous-unwind-tables /' \
gcc/Makefile.in libgcc/Makefile.in
;; ;;
esac esac
@ -877,6 +633,9 @@ CC="$CC" CFLAGS="$OPT_FLAGS" \
%ifarch aarch64 %ifarch aarch64
--with-multilib-list=lp64 --with-multilib-list=lp64
%endif %endif
%ifarch riscv64
--with-arch=rv64gc --with-abi=lp64d --with-multilib-list=lp64d
%endif
%ifarch sparc sparcv9 sparc64 %ifarch sparc sparcv9 sparc64
make -j32 BOOT_CFLAGS="$OPT_FLAGS" bootstrap make -j32 BOOT_CFLAGS="$OPT_FLAGS" bootstrap
@ -954,6 +713,20 @@ find rpm.doc -name \*ChangeLog\* | xargs bzip2 -9
%install %install
rm -rf %{buildroot} rm -rf %{buildroot}
mkdir -p %{buildroot}
# RISC-V ABI wants to install everything in /lib64/lp64d or /usr/lib64/lp64d.
# Make these be symlinks to /lib64 or /usr/lib64 respectively. See:
# https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/DRHT5YTPK4WWVGL3GIN5BF2IKX2ODHZ3/
%ifarch riscv64
for d in %{buildroot}%{_libdir} %{buildroot}/%{_lib} \
%{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib} \
%{buildroot}%{_prefix}/include/c++/%{gcc_major}/%{gcc_target_platform}/%{_lib}; do
mkdir -p $d
(cd $d && ln -sf . lp64d)
done
%endif
cd obj-%{gcc_target_platform} cd obj-%{gcc_target_platform}
@ -1083,7 +856,7 @@ mkdir -p %{buildroot}/%{_lib}
mv -f %{buildroot}%{_prefix}/%{_lib}/libgcc_s.so.1 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1 mv -f %{buildroot}%{_prefix}/%{_lib}/libgcc_s.so.1 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1
chmod 755 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1 chmod 755 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1
ln -sf libgcc_s-%{gcc_major}-%{DATE}.so.1 %{buildroot}/%{_lib}/libgcc_s.so.1 ln -sf libgcc_s-%{gcc_major}-%{DATE}.so.1 %{buildroot}/%{_lib}/libgcc_s.so.1
%ifarch %{ix86} x86_64 ppc ppc64 ppc64p7 ppc64le %{arm} %ifarch %{ix86} x86_64 ppc ppc64 ppc64p7 ppc64le %{arm} aarch64 riscv64
rm -f $FULLPATH/libgcc_s.so rm -f $FULLPATH/libgcc_s.so
echo '/* GNU ld script echo '/* GNU ld script
Use the shared library, but some functions are only in Use the shared library, but some functions are only in
@ -1152,14 +925,14 @@ ln -sf ../../../libstdc++.so.6.*[0-9] libstdc++.so
ln -sf ../../../libgfortran.so.5.* libgfortran.so ln -sf ../../../libgfortran.so.5.* libgfortran.so
ln -sf ../../../libgomp.so.1.* libgomp.so ln -sf ../../../libgomp.so.1.* libgomp.so
%if %{build_go} %if %{build_go}
ln -sf ../../../libgo.so.14.* libgo.so ln -sf ../../../libgo.so.16.* libgo.so
%endif %endif
%if %{build_libquadmath} %if %{build_libquadmath}
ln -sf ../../../libquadmath.so.0.* libquadmath.so ln -sf ../../../libquadmath.so.0.* libquadmath.so
%endif %endif
%if %{build_d} %if %{build_d}
ln -sf ../../../libgdruntime.so.76.* libgdruntime.so ln -sf ../../../libgdruntime.so.1.* libgdruntime.so
ln -sf ../../../libgphobos.so.76.* libgphobos.so ln -sf ../../../libgphobos.so.1.* libgphobos.so
%endif %endif
%if %{build_libitm} %if %{build_libitm}
ln -sf ../../../libitm.so.1.* libitm.so ln -sf ../../../libitm.so.1.* libitm.so
@ -1168,7 +941,7 @@ ln -sf ../../../libitm.so.1.* libitm.so
ln -sf ../../../libatomic.so.1.* libatomic.so ln -sf ../../../libatomic.so.1.* libatomic.so
%endif %endif
%if %{build_libasan} %if %{build_libasan}
ln -sf ../../../libasan.so.5.* libasan.so ln -sf ../../../libasan.so.6.* libasan.so
mv ../../../libasan_preinit.o libasan_preinit.o mv ../../../libasan_preinit.o libasan_preinit.o
%endif %endif
%if %{build_libubsan} %if %{build_libubsan}
@ -1182,14 +955,14 @@ ln -sf ../../../../%{_lib}/libstdc++.so.6.*[0-9] libstdc++.so
ln -sf ../../../../%{_lib}/libgfortran.so.5.* libgfortran.so ln -sf ../../../../%{_lib}/libgfortran.so.5.* libgfortran.so
ln -sf ../../../../%{_lib}/libgomp.so.1.* libgomp.so ln -sf ../../../../%{_lib}/libgomp.so.1.* libgomp.so
%if %{build_go} %if %{build_go}
ln -sf ../../../../%{_lib}/libgo.so.14.* libgo.so ln -sf ../../../../%{_lib}/libgo.so.16.* libgo.so
%endif %endif
%if %{build_libquadmath} %if %{build_libquadmath}
ln -sf ../../../../%{_lib}/libquadmath.so.0.* libquadmath.so ln -sf ../../../../%{_lib}/libquadmath.so.0.* libquadmath.so
%endif %endif
%if %{build_d} %if %{build_d}
ln -sf ../../../../%{_lib}/libgdruntime.so.76.* libgdruntime.so ln -sf ../../../../%{_lib}/libgdruntime.so.1.* libgdruntime.so
ln -sf ../../../../%{_lib}/libgphobos.so.76.* libgphobos.so ln -sf ../../../../%{_lib}/libgphobos.so.1.* libgphobos.so
%endif %endif
%if %{build_libitm} %if %{build_libitm}
ln -sf ../../../../%{_lib}/libitm.so.1.* libitm.so ln -sf ../../../../%{_lib}/libitm.so.1.* libitm.so
@ -1198,7 +971,7 @@ ln -sf ../../../../%{_lib}/libitm.so.1.* libitm.so
ln -sf ../../../../%{_lib}/libatomic.so.1.* libatomic.so ln -sf ../../../../%{_lib}/libatomic.so.1.* libatomic.so
%endif %endif
%if %{build_libasan} %if %{build_libasan}
ln -sf ../../../../%{_lib}/libasan.so.5.* libasan.so ln -sf ../../../../%{_lib}/libasan.so.6.* libasan.so
mv ../../../../%{_lib}/libasan_preinit.o libasan_preinit.o mv ../../../../%{_lib}/libasan_preinit.o libasan_preinit.o
%endif %endif
%if %{build_libubsan} %if %{build_libubsan}
@ -1302,8 +1075,8 @@ ln -sf ../`echo ../../../../lib/libgfortran.so.5.* | sed s~/lib/~/lib64/~` 64/li
ln -sf ../`echo ../../../../lib/libgomp.so.1.* | sed s~/lib/~/lib64/~` 64/libgomp.so ln -sf ../`echo ../../../../lib/libgomp.so.1.* | sed s~/lib/~/lib64/~` 64/libgomp.so
%if %{build_go} %if %{build_go}
rm -f libgo.so rm -f libgo.so
echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libgo.so.14.* | sed 's,^.*libg,libg,'`' )' > libgo.so echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libgo.so.16.* | sed 's,^.*libg,libg,'`' )' > libgo.so
echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libgo.so.14.* | sed 's,^.*libg,libg,'`' )' > 64/libgo.so echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libgo.so.16.* | sed 's,^.*libg,libg,'`' )' > 64/libgo.so
%endif %endif
%if %{build_libquadmath} %if %{build_libquadmath}
rm -f libquadmath.so rm -f libquadmath.so
@ -1312,10 +1085,10 @@ echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libquadmath.so.0.* | sed '
%endif %endif
%if %{build_d} %if %{build_d}
rm -f libgdruntime.so libgphobos.so rm -f libgdruntime.so libgphobos.so
echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libgdruntime.so.76.* | sed 's,^.*libg,libg,'`' )' > libgdruntime.so echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libgdruntime.so.1.* | sed 's,^.*libg,libg,'`' )' > libgdruntime.so
echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libgdruntime.so.76.* | sed 's,^.*libg,libg,'`' )' > 64/libgdruntime.so echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libgdruntime.so.1.* | sed 's,^.*libg,libg,'`' )' > 64/libgdruntime.so
echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libgphobos.so.76.* | sed 's,^.*libg,libg,'`' )' > libgphobos.so echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libgphobos.so.1.* | sed 's,^.*libg,libg,'`' )' > libgphobos.so
echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libgphobos.so.76.* | sed 's,^.*libg,libg,'`' )' > 64/libgphobos.so echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libgphobos.so.1.* | sed 's,^.*libg,libg,'`' )' > 64/libgphobos.so
%endif %endif
%if %{build_libitm} %if %{build_libitm}
rm -f libitm.so rm -f libitm.so
@ -1329,8 +1102,8 @@ echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libatomic.so.1.* | sed 's,
%endif %endif
%if %{build_libasan} %if %{build_libasan}
rm -f libasan.so rm -f libasan.so
echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libasan.so.5.* | sed 's,^.*liba,liba,'`' )' > libasan.so echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libasan.so.6.* | sed 's,^.*liba,liba,'`' )' > libasan.so
echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libasan.so.5.* | sed 's,^.*liba,liba,'`' )' > 64/libasan.so echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libasan.so.6.* | sed 's,^.*liba,liba,'`' )' > 64/libasan.so
mv ../../../../lib64/libasan_preinit.o 64/libasan_preinit.o mv ../../../../lib64/libasan_preinit.o 64/libasan_preinit.o
%endif %endif
%if %{build_libubsan} %if %{build_libubsan}
@ -1401,8 +1174,8 @@ ln -sf ../`echo ../../../../lib64/libgfortran.so.5.* | sed s~/../lib64/~/~` 32/l
ln -sf ../`echo ../../../../lib64/libgomp.so.1.* | sed s~/../lib64/~/~` 32/libgomp.so ln -sf ../`echo ../../../../lib64/libgomp.so.1.* | sed s~/../lib64/~/~` 32/libgomp.so
%if %{build_go} %if %{build_go}
rm -f libgo.so rm -f libgo.so
echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgo.so.14.* | sed 's,^.*libg,libg,'`' )' > libgo.so echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgo.so.16.* | sed 's,^.*libg,libg,'`' )' > libgo.so
echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgo.so.14.* | sed 's,^.*libg,libg,'`' )' > 32/libgo.so echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgo.so.16.* | sed 's,^.*libg,libg,'`' )' > 32/libgo.so
%endif %endif
%if %{build_libquadmath} %if %{build_libquadmath}
rm -f libquadmath.so rm -f libquadmath.so
@ -1411,10 +1184,10 @@ echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libquadmath.so.0.* | sed '
%endif %endif
%if %{build_d} %if %{build_d}
rm -f libgdruntime.so libgphobos.so rm -f libgdruntime.so libgphobos.so
echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgdruntime.so.76.* | sed 's,^.*libg,libg,'`' )' > libgdruntime.so echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgdruntime.so.1.* | sed 's,^.*libg,libg,'`' )' > libgdruntime.so
echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgdruntime.so.76.* | sed 's,^.*libg,libg,'`' )' > 32/libgdruntime.so echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgdruntime.so.1.* | sed 's,^.*libg,libg,'`' )' > 32/libgdruntime.so
echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgphobos.so.76.* | sed 's,^.*libg,libg,'`' )' > libgphobos.so echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgphobos.so.1.* | sed 's,^.*libg,libg,'`' )' > libgphobos.so
echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgphobos.so.76.* | sed 's,^.*libg,libg,'`' )' > 32/libgphobos.so echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgphobos.so.1.* | sed 's,^.*libg,libg,'`' )' > 32/libgphobos.so
%endif %endif
%if %{build_libitm} %if %{build_libitm}
rm -f libitm.so rm -f libitm.so
@ -1428,8 +1201,8 @@ echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libatomic.so.1.* | sed 's,
%endif %endif
%if %{build_libasan} %if %{build_libasan}
rm -f libasan.so rm -f libasan.so
echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libasan.so.5.* | sed 's,^.*liba,liba,'`' )' > libasan.so echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libasan.so.6.* | sed 's,^.*liba,liba,'`' )' > libasan.so
echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libasan.so.5.* | sed 's,^.*liba,liba,'`' )' > 32/libasan.so echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libasan.so.6.* | sed 's,^.*liba,liba,'`' )' > 32/libasan.so
mv ../../../../lib/libasan_preinit.o 32/libasan_preinit.o mv ../../../../lib/libasan_preinit.o 32/libasan_preinit.o
%endif %endif
%if %{build_libubsan} %if %{build_libubsan}
@ -1566,8 +1339,8 @@ chmod 755 %{buildroot}%{_prefix}/%{_lib}/libcc1.so.0.*
chmod 755 %{buildroot}%{_prefix}/%{_lib}/libquadmath.so.0.* chmod 755 %{buildroot}%{_prefix}/%{_lib}/libquadmath.so.0.*
%endif %endif
%if %{build_d} %if %{build_d}
chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgdruntime.so.76.* chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgdruntime.so.1.*
chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgphobos.so.76.* chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgphobos.so.1.*
%endif %endif
%if %{build_libitm} %if %{build_libitm}
chmod 755 %{buildroot}%{_prefix}/%{_lib}/libitm.so.1.* chmod 755 %{buildroot}%{_prefix}/%{_lib}/libitm.so.1.*
@ -1576,7 +1349,7 @@ chmod 755 %{buildroot}%{_prefix}/%{_lib}/libitm.so.1.*
chmod 755 %{buildroot}%{_prefix}/%{_lib}/libatomic.so.1.* chmod 755 %{buildroot}%{_prefix}/%{_lib}/libatomic.so.1.*
%endif %endif
%if %{build_libasan} %if %{build_libasan}
chmod 755 %{buildroot}%{_prefix}/%{_lib}/libasan.so.5.* chmod 755 %{buildroot}%{_prefix}/%{_lib}/libasan.so.6.*
%endif %endif
%if %{build_libubsan} %if %{build_libubsan}
chmod 755 %{buildroot}%{_prefix}/%{_lib}/libubsan.so.1.* chmod 755 %{buildroot}%{_prefix}/%{_lib}/libubsan.so.1.*
@ -1589,7 +1362,7 @@ chmod 755 %{buildroot}%{_prefix}/%{_lib}/liblsan.so.0.*
%endif %endif
%if %{build_go} %if %{build_go}
# Avoid stripping these libraries and binaries. # Avoid stripping these libraries and binaries.
chmod 644 %{buildroot}%{_prefix}/%{_lib}/libgo.so.14.* chmod 644 %{buildroot}%{_prefix}/%{_lib}/libgo.so.16.*
chmod 644 %{buildroot}%{_prefix}/bin/go.gcc chmod 644 %{buildroot}%{_prefix}/bin/go.gcc
chmod 644 %{buildroot}%{_prefix}/bin/gofmt.gcc chmod 644 %{buildroot}%{_prefix}/bin/gofmt.gcc
chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo
@ -1781,6 +1554,7 @@ end
%{_prefix}/bin/gcc-ar %{_prefix}/bin/gcc-ar
%{_prefix}/bin/gcc-nm %{_prefix}/bin/gcc-nm
%{_prefix}/bin/gcc-ranlib %{_prefix}/bin/gcc-ranlib
%{_prefix}/bin/lto-dump
%ifarch ppc %ifarch ppc
%{_prefix}/bin/%{_target_platform}-gcc %{_prefix}/bin/%{_target_platform}-gcc
%endif %endif
@ -1796,6 +1570,7 @@ end
%{_mandir}/man1/gcov.1* %{_mandir}/man1/gcov.1*
%{_mandir}/man1/gcov-tool.1* %{_mandir}/man1/gcov-tool.1*
%{_mandir}/man1/gcov-dump.1* %{_mandir}/man1/gcov-dump.1*
%{_mandir}/man1/lto-dump.1*
%{_infodir}/gcc* %{_infodir}/gcc*
%dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc
%dir %{_prefix}/lib/gcc/%{gcc_target_platform} %dir %{_prefix}/lib/gcc/%{gcc_target_platform}
@ -1820,13 +1595,13 @@ end
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/unwind.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/unwind.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/omp.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/omp.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/openacc.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/openacc.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/acc_prof.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdint.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdint.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdint-gcc.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdint-gcc.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdalign.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdalign.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdnoreturn.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdnoreturn.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdatomic.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdatomic.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/gcov.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/gcov.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/simdmath.h
%ifarch %{ix86} x86_64 %ifarch %{ix86} x86_64
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mmintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mmintrin.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xmmintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xmmintrin.h
@ -1906,6 +1681,11 @@ end
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/movdirintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/movdirintrin.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/waitpkgintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/waitpkgintrin.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cldemoteintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cldemoteintrin.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512bf16vlintrin.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512bf16intrin.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/enqcmdintrin.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vp2intersectintrin.h
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vp2intersectvlintrin.h
%endif %endif
%ifarch ia64 %ifarch ia64
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/ia64intrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/ia64intrin.h
@ -2079,7 +1859,7 @@ end
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/liblsan_preinit.o %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/liblsan_preinit.o
%endif %endif
%{_prefix}/libexec/getconf/default %{_prefix}/libexec/getconf/default
%doc gcc/README* rpm.doc/changelogs/gcc/ChangeLog* %doc gcc/README* rpm.doc/changelogs/gcc/ChangeLog*
%{!?_licensedir:%global license %%doc} %{!?_licensedir:%global license %%doc}
%license gcc/COPYING* COPYING.RUNTIME %license gcc/COPYING* COPYING.RUNTIME
@ -2141,6 +1921,10 @@ end
%dir %{_datadir}/gdb/auto-load %dir %{_datadir}/gdb/auto-load
%dir %{_datadir}/gdb/auto-load/%{_prefix} %dir %{_datadir}/gdb/auto-load/%{_prefix}
%dir %{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/ %dir %{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/
# Package symlink to keep compatibility
%ifarch riscv64
%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/lp64d
%endif
%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/libstdc*gdb.py* %{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/libstdc*gdb.py*
%dir %{_prefix}/share/gcc-%{gcc_major} %dir %{_prefix}/share/gcc-%{gcc_major}
%dir %{_prefix}/share/gcc-%{gcc_major}/python %dir %{_prefix}/share/gcc-%{gcc_major}/python
@ -2254,7 +2038,6 @@ end
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_arithmetic.mod %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_arithmetic.mod
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_exceptions.mod %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_exceptions.mod
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_features.mod %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_features.mod
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/simdmath_f.h
%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/f951 %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/f951
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgfortran.spec %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgfortran.spec
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libcaf_single.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libcaf_single.a
@ -2336,8 +2119,8 @@ end
%doc rpm.doc/gdc/* %doc rpm.doc/gdc/*
%files -n libgphobos %files -n libgphobos
%{_prefix}/%{_lib}/libgdruntime.so.76* %{_prefix}/%{_lib}/libgdruntime.so.1*
%{_prefix}/%{_lib}/libgphobos.so.76* %{_prefix}/%{_lib}/libgphobos.so.1*
%doc rpm.doc/libphobos/* %doc rpm.doc/libphobos/*
%files -n libgphobos-static %files -n libgphobos-static
@ -2375,16 +2158,19 @@ end
%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64 %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/adainclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/adainclude
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/adalib %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/adalib
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/ada_target_properties
%endif %endif
%ifarch %{multilib_64_archs} %ifarch %{multilib_64_archs}
%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32 %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/adainclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/adainclude
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/adalib %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/adalib
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/ada_target_properties
%endif %endif
%ifarch sparcv9 sparc64 ppc ppc64 ppc64p7 %ifarch sparcv9 sparc64 ppc ppc64 ppc64p7
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adainclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adainclude
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib
%endif %endif
%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/ada_target_properties
%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/gnat1 %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/gnat1
%doc rpm.doc/changelogs/gcc/ada/ChangeLog* %doc rpm.doc/changelogs/gcc/ada/ChangeLog*
@ -2539,7 +2325,7 @@ end
%if %{build_libasan} %if %{build_libasan}
%files -n libasan %files -n libasan
%{_prefix}/%{_lib}/libasan.so.5* %{_prefix}/%{_lib}/libasan.so.6*
%files -n libasan-static %files -n libasan-static
%dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc
@ -2659,7 +2445,7 @@ end
%doc rpm.doc/go/* %doc rpm.doc/go/*
%files -n libgo %files -n libgo
%attr(755,root,root) %{_prefix}/%{_lib}/libgo.so.14* %attr(755,root,root) %{_prefix}/%{_lib}/libgo.so.16*
%doc rpm.doc/libgo/* %doc rpm.doc/libgo/*
%files -n libgo-devel %files -n libgo-devel
@ -2732,210 +2518,8 @@ end
%doc rpm.doc/changelogs/libcc1/ChangeLog* %doc rpm.doc/changelogs/libcc1/ChangeLog*
%changelog %changelog
* Mon Jun 28 2021 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20210628.21 * Tue Jul 27 2021 eastb233 <xiezhiheng@huawei.com> - 10.3.0-20210727.1
- complete-struct-reorg.patch: Revert modification - Type:Init
* Fri May 28 2021 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20210528.20
- gcc.spec: Disable bootstrap to reduce building time
* Wed Apr 28 2021 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20210428.19
- add-fp-model-options.patch: New file
- enable-simd-math.patch: Enable simd math library in C and Fortran
- fix-CTOR-vectorization.patch: New file
- fix-range-set-by-vectorization-on-niter-IVs.patch: New file
- medium-code-mode.patch: Fix bugs when used with fpic
- optabs-Dont-use-scalar-conversions-for-vectors.patch: New file
- PR92429-do-not-fold-when-updating.patch: New file
- redundant-loop-elimination.patch: Fix some programming specifications
- fix-ICE-in-vect.patch: New file
- Fix-type-mismatch-in-SLPed-constructors.patch: New file
- add-check-for-pressure-in-sche1.patch: New file
- revert-moutline-atomics.patch: New file
- fix-ICE-in-eliminate-stmt.patch: New file
- revise-type-before-build-MULT.patch: New file
- Simplify-X-C1-C2.patch: New file
- gcc.spec: Add new patches
* Wed Apr 21 2021 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20210204.18
- Type:bugfix
- ID:NA - ID:NA
- SUG:NA - SUG:NA
- DESC:NA - DESC:Init GCC 10.3.0 repository
* Mon Mar 15 2021 tianwei <tianwei12@huawei.com> - 9.3.1-20210204.17
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:add SP and FS for x86
* Thu Feb 04 2021 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20210204.16
- Handle-POLY_INT_CSTs-in-declare_return_value.patch: New file
- Handle-POLY_INT_CST-in-copy_reference_ops_from_ref.patch: New file
- fix-strncpy-inline-warning.patch: New file
* Fri Jan 15 2021 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20210115.15
- Fix-interaction-between-aka-changes-and-DR1558.patch: New file
* Mon Jan 04 2021 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20210104.14
- gcc.spec: Pack arm_bf16.h and arm_sve.h in aarch64 port
* Tue Dec 29 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20201229.13
- avoid-cycling-on-vertain-subreg-reloads.patch: Add patch source comment
- change-gcc-BASE-VER.patch: Likewise
- dont-generate-IF_THEN_ELSE.patch: Likewise
- fix-ICE-in-compute_live_loop_exits.patch: Likewise
- fix-ICE-in-eliminate_stmt.patch: Likewise
- fix-ICE-in-vect_create_epilog_for_reduction.patch: Likewise
- fix-ICE-in-vect_stmt_to_vectorize.patch: Likewise
- fix-ICE-in-verify_ssa.patch: Likewise
- fix-ICE-when-vectorizing-nested-cycles.patch: Likewise
- fix-cost-of-plus.patch: Likewise
- ipa-const-prop-self-recursion-bugfix.patch: Likewise
- simplify-removing-subregs.patch: Likewise
- medium-code-mode.patch: Bugfix
- fix-when-peeling-for-alignment.patch: Move to ...
- fix-PR-92351-When-peeling-for-alignment.patch: ... this
- AArch64-Fix-constraints-for-CPY-M.patch: New file
- Apply-maximum-nunits-for-BB-SLP.patch: New file
- Fix-EXTRACT_LAST_REDUCTION-segfault.patch: New file
- Fix-up-push_partial_def-little-endian-bitfield.patch: New file
- Fix-zero-masking-for-vcvtps2ph.patch: New file
- IRA-Handle-fully-tied-destinations.patch: New file
- SLP-VECT-Add-check-to-fix-96837.patch: New file
- aarch64-Fix-ash-lr-lshr-mode-3-expanders.patch: New file
- aarch64-Fix-bf16-and-matrix-g++-gfortran.patch: New file
- aarch64-Fix-mismatched-SVE-predicate-modes.patch: New file
- aarch64-fix-sve-acle-error.patch: New file
- adjust-vector-cost-and-move-EXTRACT_LAST_REDUCTION-costing.patch: New file
- bf16-and-matrix-characteristic.patch: New file
- fix-ICE-IPA-compare-VRP-types.patch: New file
- fix-ICE-in-affine-combination.patch: New file
- fix-ICE-in-pass-vect.patch: New file
- fix-ICE-in-vect_update_misalignment_for_peel.patch: New file
- fix-addlosymdi-ICE-in-pass-reload.patch: New file
- fix-an-ICE-in-vect_recog_mask_conversion_pattern.patch: New file
- fix-avx512vl-vcvttpd2dq-2-fail.patch: New file
- fix-issue499-add-nop-convert.patch: New file
- fix-issue604-ldist-dependency-fixup.patch: New file
- modulo-sched-Carefully-process-loop-counter-initiali.patch: New file
- re-PR-target-91124-gcc.target-i386-avx512vl-vpshldvd.patch: New file
- reduction-paths-with-unhandled-live-stmt.patch: New file
- redundant-loop-elimination.patch: New file
- sccvn-Improve-handling-of-load-masked-with-integer.patch: New file
- speed-up-DDG-analysis-and-fix-bootstrap-compare-debug.patch: New file
- store-merging-Consider-also-overlapping-stores-earlier.patch: New file
- tree-optimization-96920-another-ICE-when-vectorizing.patch: New file
- tree-optimization-97812-fix-range-query-in-VRP-asser.patch: New file
- vectorizable-comparison-Swap-operands-only-once.patch: New file
- x86-Fix-bf16-and-matrix.patch: New file
- gcc.spec: Add uploaded patch
* Tue Sep 22 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200922.12
- fix-when-peeling-for-alignment.patch: New file
* Tue Sep 22 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200922.11
- gcc.spec: Delete pkgversion
* Mon Sep 21 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200921.10
- complete-struct-reorg.patch: Fix secure coding
- ipa-struct-reorg-bugfix.patch: Likewise
- simplify-removing-subregs.patch: Likewise
- fix-ICE-in-eliminate_stmt.patch: New file
- fix-make-ifcvt-clean-up-dead-comparisons.patch: New file
- ipa-const-prop-buffer-overflow-bugfix.patch: New file
- gcc.spec: Add pkgversion, pack libquadmath library on aarch64
* Thu Sep 15 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200915.9
- avoid-cycling-on-vertain-subreg-reloads.patch: New file
- fix-ICE-in-verify_target_availability.patch: New file
- fix-ICE-in-extract_constrain_insn.patch: New file
- fix-ICE-vect_slp_analyze_node_operations.patch: New file
- ipa-const-prop-null-point-check-bugfix.patch: New file
* Thu Sep 15 2020 huanghaitao <huanghaitao@huawei.com> - 9.3.1-20200911.8
- revert patches to fix build errors
* Fri Sep 11 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200911.7
- avoid-cycling-on-vertain-subreg-reloads.patch: New file
- fix-ICE-in-verify_target_availability.patch: New file
- fix-ICE-in-extract_constrain_insn.patch: New file
- fix-ICE-vect_slp_analyze_node_operations.patch: New file
- ipa-const-prop-null-point-check-bugfix.patch: New file
* Fri Sep 11 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200911.6
- fix-ICE-during-GIMPLE-pass-dse.patch: Add test case
* Wed Sep 09 2020 jdkboy <guoge1@huawei.com> - 9.3.1-20200909.5
- add backport-fix-ICE-during-GIMPLE-pass-dse.patch
* Sat Sep 05 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200905.4
- fix-avoid-bogus-uninit-warning-with-store-motion.patch: New file
* Mon Aug 28 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200828.4
- Add add-checks-to-avoid-spoiling-if-conversion.patch
- Add add-option-fallow-store-data-races.patch
- Add complete-struct-reorg.patch
- Add cse-in-vectorization.patch
- Add enable-simd-math.patch
- Add fix-ICE-avoid-issueing-loads-in-SM-when-possible.patch
- Add fix-ICE-in-compute_live_loop_exits.patch
- Add fix-ICE-in-copy_reference_ops_from_ref.patch
- Add fix-ICE-in-declare-return-variable.patch
- Add fix-ICE-in-exact_div.patch
- Add fix-ICE-in-gimple_op.patch
- Add fix-ICE-in-model_update_limit_points_in_group.patch
- Add fix-ICE-in-reload.patch
- Add fix-ICE-in-store_constructor.patch
- Add fix-ICE-in-vec.patch
- Add fix-ICE-in-vect_create_epilog_for_reduction.patch
- Add fix-ICE-in-vect_create_epilog_for_reduction_2.patch
- Add fix-ICE-in-vect_create_epilog_for_reduction_3.patch
- Add fix-ICE-in-vect_get_vec_def_for_stmt_copy.patch
- Add fix-ICE-in-vect_slp_analyze_node_operations.patch
- Add fix-ICE-in-vect_stmt_to_vectorize.patch
- Add fix-ICE-in-vect_transform_stmt.patch
- Add fix-ICE-in-vectorizable_condition.patch
- Add fix-ICE-in-verify_ssa.patch
- Add fix-ICE-statement-uses-released-SSA-name.patch
- Add fix-ICE-when-vectorizing-nested-cycles.patch
- Add fix-SSA-update-for-vectorizer-epilogue.patch
- Add fix-do-not-build-op.patch
- Add fix-load-eliding-in-SM.patch
- Add fix-wrong-vectorizer-code.patch
- Add generate-csel-for-arrayref.patch
- Add ipa-const-prop-self-recursion-bugfix.patch
- Add ipa-const-prop.patch
- Add ipa-struct-reorg-bugfix.patch
- Add ipa-struct-reorg.patch
- Add medium-code-mode.patch
- Add reduction-chain-slp-option.patch
- Add reductions-slp-enhancement.patch
- Add simplify-removing-subregs.patch
- Add tighten-range-for-generating-csel.patch
- Add vectorization-enhancement.patch
* Mon Jun 29 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200629.3
- gcc.spec: Change release version
* Mon Jun 29 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200312.3
- PR92303-Try-to-simplify-memory-subreg.patch: New file, fix ICE
- Fix-PR94185.patch: Likewise
- testsuite-Fix-pr94185.patch: Likewise
- gcc.spec: Add new patch
* Fri May 22 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200312.2
- gcc.spec: Modify Release to %{release}.2
* Wed May 20 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200312.h1
- address-calculation-optimization-within-loop.patch: Modify testsuite
- generate-csel.patch: Modify testsuite
- change-gcc-BASE-VER.patch: New file, change GCC base version
- gcc.spec: Add new Patch, change GCC version to 9.3.1
* Tue Apr 28 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.0-20200312.h1
- Type:modify
- Desc:modify patch name and gcc.spec
* Sun Apr 26 2020 jdkboy <guoge1@huawei.com> - 9.3.0-20200312.h1
- Type:init
- Desc:Init gcc 9.3.0

View File

@ -1,218 +0,0 @@
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c 2020-05-26 21:03:43.132721856 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c 2020-05-19 20:12:32.655794652 +0800
@@ -9,4 +9,4 @@ unsigned test(unsigned k, unsigned b) {
return a[0]+a[1];
}
-/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c 2020-05-26 21:03:43.132721856 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c 2020-05-19 20:12:32.667794652 +0800
@@ -11,4 +11,4 @@ unsigned test(unsigned k, unsigned b) {
return a[0]+a[1];
}
-/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c 2020-05-26 21:03:43.132721856 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c 2020-05-19 20:12:32.667794652 +0800
@@ -13,4 +13,4 @@ int test(int b, int k) {
return a.data[0] + a.data[1];
}
-/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
--- a/gcc/tree-ssa-phiopt.c 2020-05-26 21:03:43.132721856 +0800
+++ b/gcc/tree-ssa-phiopt.c 2020-05-26 21:02:02.872006469 +0800
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.
#include "params.h"
#include "case-cfn-macros.h"
#include "tree-eh.h"
+#include "inchash.h"
static unsigned int tree_ssa_phiopt_worker (bool, bool, bool);
static bool two_value_replacement (basic_block, basic_block, edge, gphi *,
@@ -1984,6 +1985,18 @@ struct name_to_bb
basic_block bb;
};
+/* A hash-table of ARRAY_REF with a base of VAR_DECL and an offset of
+ SSA_NAME, and in which basic block it was seen, which would constitute
+ a no-trap region for same accessed. */
+struct array_ref_to_bb
+{
+ unsigned int ssa_name_ver;
+ unsigned int phase;
+ HOST_WIDE_INT size;
+ tree var_decl;
+ basic_block bb;
+};
+
/* Hashtable helpers. */
struct ssa_names_hasher : free_ptr_hash <name_to_bb>
@@ -1992,6 +2005,12 @@ struct ssa_names_hasher : free_ptr_hash
static inline bool equal (const name_to_bb *, const name_to_bb *);
};
+struct array_refs_hasher : free_ptr_hash <array_ref_to_bb>
+{
+ static inline hashval_t hash (const array_ref_to_bb *);
+ static inline bool equal (const array_ref_to_bb *, const array_ref_to_bb *);
+};
+
/* Used for quick clearing of the hash-table when we see calls.
Hash entries with phase < nt_call_phase are invalid. */
static unsigned int nt_call_phase;
@@ -2005,6 +2024,16 @@ ssa_names_hasher::hash (const name_to_bb
^ (n->offset << 6) ^ (n->size << 3);
}
+inline hashval_t
+array_refs_hasher::hash (const array_ref_to_bb *n)
+{
+ inchash::hash hstate (0);
+ hstate.add_int (n->ssa_name_ver);
+ hstate.add_hwi (n->size);
+ hstate.add_ptr (n->var_decl);
+ return hstate.end ();
+}
+
/* The equality function of *P1 and *P2. */
inline bool
@@ -2016,11 +2045,21 @@ ssa_names_hasher::equal (const name_to_b
&& n1->size == n2->size;
}
+inline bool
+array_refs_hasher::equal (const array_ref_to_bb *n1, const array_ref_to_bb *n2)
+{
+ return n1->ssa_name_ver == n2->ssa_name_ver
+ && n1->size == n2->size
+ && n1->var_decl == n2->var_decl;
+}
+
class nontrapping_dom_walker : public dom_walker
{
public:
nontrapping_dom_walker (cdi_direction direction, hash_set<tree> *ps)
- : dom_walker (direction), m_nontrapping (ps), m_seen_ssa_names (128) {}
+ : dom_walker (direction), m_nontrapping (ps),
+ m_seen_ssa_names (128), m_seen_array_refs (128)
+ {}
virtual edge before_dom_children (basic_block);
virtual void after_dom_children (basic_block);
@@ -2028,16 +2067,18 @@ public:
private:
/* We see the expression EXP in basic block BB. If it's an interesting
- expression (an MEM_REF through an SSA_NAME) possibly insert the
- expression into the set NONTRAP or the hash table of seen expressions.
- STORE is true if this expression is on the LHS, otherwise it's on
- the RHS. */
+ expression (an MEM_REF through an SSA_NAME or an ARRAY_REF with a base
+ of VAR_DECL and an offset of SSA_NAME) possibly insert the expression
+ into the set NONTRAP or the hash table of seen expressions. STORE
+ is true if this expression is on the LHS, otherwise it's on the RHS. */
void add_or_mark_expr (basic_block, tree, bool);
+ void add_or_mark_array_ref (basic_block, tree);
hash_set<tree> *m_nontrapping;
/* The hash table for remembering what we've seen. */
hash_table<ssa_names_hasher> m_seen_ssa_names;
+ hash_table<array_refs_hasher> m_seen_array_refs;
};
/* Called by walk_dominator_tree, when entering the block BB. */
@@ -2071,7 +2112,9 @@ nontrapping_dom_walker::before_dom_child
else if (gimple_assign_single_p (stmt) && !gimple_has_volatile_ops (stmt))
{
add_or_mark_expr (bb, gimple_assign_lhs (stmt), true);
+ add_or_mark_array_ref (bb, gimple_assign_lhs (stmt));
add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), false);
+ add_or_mark_array_ref (bb, gimple_assign_rhs1 (stmt));
}
}
return NULL;
@@ -2148,6 +2191,74 @@ nontrapping_dom_walker::add_or_mark_expr
}
}
}
+}
+
+/* We see the expression EXP in basic block BB. If it's an interesting
+ expression (an ARRAY_REF with a base of VAR_DECL and an offset of
+ SSA_NAME) possibly insert the expression into the set NONTRAP or the
+ hash table of seen expressions. */
+void
+nontrapping_dom_walker::add_or_mark_array_ref (basic_block bb, tree exp)
+{
+ if (TREE_CODE (exp) == ARRAY_REF
+ && TREE_CODE (TREE_OPERAND (exp, 1)) == SSA_NAME
+ && int_size_in_bytes (TREE_TYPE (exp)) > 0)
+ {
+ HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
+ tree base = get_base_address (exp);
+ /* if BASE is a local variable without address-taken, which can't be
+ read-only, a dominating load can constitute a no-trap region for
+ a store as well. */
+ if (TREE_CODE (base) == VAR_DECL
+ && auto_var_p (base) && !TREE_ADDRESSABLE (base))
+ {
+ struct array_ref_to_bb array_map;
+ basic_block found_array_bb = 0;
+
+ /* Try to find the last seen ARRAY_REF with the same base and
+ offset, which can trap. */
+ array_map.ssa_name_ver = SSA_NAME_VERSION (TREE_OPERAND (exp, 1));
+ array_map.phase = 0;
+ array_map.bb = 0;
+ array_map.size = size;
+ array_map.var_decl = base;
+
+ array_ref_to_bb **slot
+ = m_seen_array_refs.find_slot (&array_map, INSERT);
+ struct array_ref_to_bb *a2bb = *slot;
+ if (a2bb != NULL && a2bb->phase >= nt_call_phase)
+ {
+ found_array_bb = a2bb->bb;
+ }
+
+ /* If we've found a trapping MEM_REF, _and_ it dominates EXP
+ (it's in a basic block on the path from us to the dominator root)
+ then we can't trap. */
+ if (found_array_bb && (((size_t)found_array_bb->aux) & 1) == 1)
+ {
+ m_nontrapping->add (exp);
+ }
+ else
+ {
+ /* EXP might trap, so insert it into the hash table. */
+ if (a2bb != NULL)
+ {
+ a2bb->phase = nt_call_phase;
+ a2bb->bb = bb;
+ }
+ else
+ {
+ a2bb = XNEW (struct array_ref_to_bb);
+ a2bb->ssa_name_ver = SSA_NAME_VERSION (TREE_OPERAND (exp, 1));
+ a2bb->phase = nt_call_phase;
+ a2bb->bb = bb;
+ a2bb->size = size;
+ a2bb->var_decl = base;
+ *slot = a2bb;
+ }
+ }
+ }
+ }
}
/* This is the entry point of gathering non trapping memory accesses.

View File

@ -1,187 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-re-PR-tree-optimization-89430-A-missing-ifcvt-optimi.patch
b9ef6a2e04bfd01329902781818ef80c52cd8b97
diff -uprN a/gcc/testsuite/gcc.dg/graphite/scop-21.c b/gcc/testsuite/gcc.dg/graphite/scop-21.c
--- a/gcc/testsuite/gcc.dg/graphite/scop-21.c
+++ b/gcc/testsuite/gcc.dg/graphite/scop-21.c
@@ -30,5 +30,4 @@ int test ()
return a[20];
}
-/* XFAILed by the fix for PR86865. */
-/* { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite" } } */
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+unsigned test(unsigned k, unsigned b) {
+ unsigned a[2];
+ if (b < a[k]) {
+ a[k] = b;
+ }
+ return a[0]+a[1];
+}
+
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+int c;
+unsigned test(unsigned k, unsigned b) {
+ unsigned a[2];
+ a[k] = c;
+ if (b < a[k]) {
+ a[k] = b;
+ }
+ return a[0]+a[1];
+}
+
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+unsigned a[2];
+unsigned test(unsigned k, unsigned b) {
+ if (b < a[k]) {
+ a[k] = b;
+ }
+ return a[0]+a[1];
+}
+
+/* { dg-final { scan-tree-dump-not "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+int *p;
+unsigned test(unsigned k, unsigned b) {
+ unsigned a[2];
+ p = a;
+ if (b < a[k]) {
+ a[k] = b;
+ }
+ return a[0]+a[1];
+}
+
+/* { dg-final { scan-tree-dump-not "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+int test(int b, int k) {
+ struct {
+ int data[2];
+ } a;
+
+ if (b < a.data[k]) {
+ a.data[k] = b;
+ }
+
+ return a.data[0] + a.data[1];
+}
+
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+int test(int b, int k) {
+ typedef struct {
+ int x;
+ } SS;
+ struct {
+ SS data[2];
+ } a;
+
+ if (b < a.data[k].x) {
+ a.data[k].x = b;
+ }
+
+ return a.data[0].x + a.data[1].x;
+}
+
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -2196,7 +2196,8 @@ get_non_trapping (void)
We check that MIDDLE_BB contains only one store, that that store
doesn't trap (not via NOTRAP, but via checking if an access to the same
- memory location dominates us) and that the store has a "simple" RHS. */
+ memory location dominates us, or the store is to a local addressable
+ object) and that the store has a "simple" RHS. */
static bool
cond_store_replacement (basic_block middle_bb, basic_block join_bb,
@@ -2218,8 +2219,9 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
locus = gimple_location (assign);
lhs = gimple_assign_lhs (assign);
rhs = gimple_assign_rhs1 (assign);
- if (TREE_CODE (lhs) != MEM_REF
- || TREE_CODE (TREE_OPERAND (lhs, 0)) != SSA_NAME
+ if ((TREE_CODE (lhs) != MEM_REF
+ && TREE_CODE (lhs) != ARRAY_REF
+ && TREE_CODE (lhs) != COMPONENT_REF)
|| !is_gimple_reg_type (TREE_TYPE (lhs)))
return false;
@@ -2227,7 +2229,13 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
TREE_THIS_NOTRAP here, but in that case we also could move stores,
whose value is not available readily, which we want to avoid. */
if (!nontrap->contains (lhs))
- return false;
+ {
+ /* If LHS is a local variable without address-taken, we could
+ always safely move down the store. */
+ tree base = get_base_address (lhs);
+ if (!auto_var_p (base) || TREE_ADDRESSABLE (base))
+ return false;
+ }
/* Now we've checked the constraints, so do the transformation:
1) Remove the single store. */
@@ -2280,6 +2288,14 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
else
gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nConditional store replacement happened!");
+ fprintf (dump_file, "\nReplaced the store with a load.");
+ fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n");
+ print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS);
+ }
+
return true;
}

View File

@ -1,119 +0,0 @@
This patch is to solve issue409, which merge following 3 commits with some style fix
commit 9505acd8501e6c79bc4fa9ed9f1ee174462601d1
Author: Richard Biener <rguenther@suse.de>
Date: Wed Jul 17 09:35:04 2019 +0000
re PR tree-optimization/91180 (wrong code at -O and above with __builtin_memset())
2019-07-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/91180
* tree-ssa-sccvn.c (vn_reference_lookup_3): Fix offset
computation for memset partial defs.
* gcc.dg/torture/pr91180.c: New testcase.
From-SVN: r273548
commit 6b68f00d4c2b375dad66bd6e72c01c309b4085c5
Author: Richard Biener <rguenther@suse.de>
Date: Fri Jul 19 16:19:39 2019 +0000
re PR tree-optimization/91211 (wrong code with __builtin_memset() and __builtin_memcpy() at -O1 and above)
2019-07-19 Richard Biener <rguenther@suse.de>
PR tree-optimization/91211
* tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): Fix
memset encoding size.
* gcc.dg/torture/pr91211.c: New testcase.
From-SVN: r273605
commit 599331c858294dec6ac94400e63d275c4836607f
Author: Richard Biener <rguenther@suse.de>
Date: Thu Jul 25 06:57:46 2019 +0000
re PR tree-optimization/91236 (ICE in walk_non_aliased_vuses at gcc/tree-ssa-alias.c:3395 on aarch64)
2019-07-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/91236
* tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): Fix
size of CONSTRUCTOR write. Fix buffer size we pass to
native_encode_expr.
From-SVN: r273787
diff -Nurp a/gcc/testsuite/gcc.dg/torture/pr91180.c b/gcc/testsuite/gcc.dg/torture/pr91180.c
--- a/gcc/testsuite/gcc.dg/torture/pr91180.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/torture/pr91180.c 2020-09-15 20:52:58.796000000 +0800
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+
+int
+main ()
+{
+#if __SIZEOF_INT__ == 4
+ unsigned x = 0xffffffff;
+ __builtin_memset (1 + (char *) &x, 0, 2);
+ if (x != 0xff0000ff)
+ __builtin_abort ();
+#endif
+ return 0;
+}
diff -Nurp a/gcc/testsuite/gcc.dg/torture/pr91211.c b/gcc/testsuite/gcc.dg/torture/pr91211.c
--- a/gcc/testsuite/gcc.dg/torture/pr91211.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/torture/pr91211.c 2020-09-15 20:52:43.932000000 +0800
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+
+typedef __UINT32_TYPE__ u32;
+
+int
+main (void)
+{
+ u32 b = 0x027C5902;
+ u32 a = 0;
+ __builtin_memset (1 + (char *) &b, 0, 2);
+ __builtin_memcpy (&a, 2 + (char *) &b, 2);
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ if (a != 0x00000200)
+#else
+ if (a != 0x00020000)
+#endif
+ __builtin_abort();
+ return 0;
+}
diff -Nurp a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
--- a/gcc/tree-ssa-sccvn.c 2020-09-14 16:44:05.476000000 +0800
+++ b/gcc/tree-ssa-sccvn.c 2020-09-16 09:29:22.520000000 +0800
@@ -1840,12 +1840,15 @@ vn_walk_cb_data::push_partial_def (const
if (TREE_CODE (pd.rhs) == CONSTRUCTOR)
/* Empty CONSTRUCTOR. */
memset (buffer + MAX (0, pd.offset),
- 0, MIN ((HOST_WIDE_INT)sizeof (buffer), pd.size));
+ 0, MIN ((HOST_WIDE_INT)sizeof (buffer)
+ - MAX (0, pd.offset),
+ pd.size + MIN (0, pd.offset)));
else
{
len = native_encode_expr (pd.rhs,
buffer + MAX (0, pd.offset),
- sizeof (buffer - MAX (0, pd.offset)),
+ sizeof (buffer)
+ - MAX (0, pd.offset),
MAX (0, -pd.offset));
if (len <= 0
|| len < (pd.size - MAX (0, -pd.offset)))
@@ -2461,7 +2464,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree
{
pd_data pd;
pd.rhs = build_constructor (NULL_TREE, NULL);
- pd.offset = offset2i - offseti;
+ pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
pd.size = leni;
return data->push_partial_def (pd, vuse, maxsizei);
}

View File

@ -1,97 +0,0 @@
commit 3c4fa8a8562d3788bb763ca5c8fb1563b8d4eb1a
Author: Martin Jambor <jamborm@gcc.gnu.org>
Date: Wed Nov 13 15:12:58 2019 +0100
Add a few missing checks that IPA_NODE_REF is not NULL (PR 92454)
2019-11-13 Jan Hubicka <hubicka@ucw.cz>
Martin Jambor <mjambor@suse.cz>
PR ipa/92454
* ipa-cp.c (spread_undeadness): Check that IPA_NODE_REF exists.
(identify_dead_nodes): Likewise.
testsuite/
* g++.dg/ipa/pr92454.C: New test.
From-SVN: r278142
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 54b9724998a..207d7c88bbd 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -4979,7 +4979,7 @@ spread_undeadness (struct cgraph_node *node)
callee = cs->callee->function_symbol (NULL);
info = IPA_NODE_REF (callee);
- if (info->node_dead)
+ if (info && info->node_dead)
{
info->node_dead = 0;
spread_undeadness (callee);
@@ -5017,18 +5017,19 @@ identify_dead_nodes (struct cgraph_node *node)
struct cgraph_node *v;
for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
if (v->local.local
+ && IPA_NODE_REF (v)
&& !v->call_for_symbol_thunks_and_aliases
(has_undead_caller_from_outside_scc_p, NULL, true))
IPA_NODE_REF (v)->node_dead = 1;
for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
- if (!IPA_NODE_REF (v)->node_dead)
+ if (IPA_NODE_REF (v) && !IPA_NODE_REF (v)->node_dead)
spread_undeadness (v);
if (dump_file && (dump_flags & TDF_DETAILS))
{
for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
- if (IPA_NODE_REF (v)->node_dead)
+ if (IPA_NODE_REF (v) && IPA_NODE_REF (v)->node_dead)
fprintf (dump_file, " Marking node as dead: %s.\n", v->dump_name ());
}
}
diff --git a/gcc/testsuite/g++.dg/ipa/pr92454.C b/gcc/testsuite/g++.dg/ipa/pr92454.C
new file mode 100644
index 00000000000..de67c66aed0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr92454.C
@@ -0,0 +1,38 @@
+/* Originally PR ipa/91969, options adjusted for PR ipa/92454 */
+/* { dg-options "-O3 --param ipa-cp-eval-threshold=1" } */
+
+enum by
+{
+};
+class A
+{
+public:
+ class B
+ {
+ public:
+ virtual void m_fn2 (by) = 0;
+ };
+ virtual int m_fn1 ();
+ B *cf;
+};
+by a;
+class C : A, A::B
+{
+ void m_fn2 (by);
+};
+void C::m_fn2 (by) { cf->m_fn2 (a); }
+
+struct a
+{
+ virtual ~a ();
+};
+
+struct b
+{
+ virtual void d (...);
+};
+
+struct c : a, b
+{
+ void d (...) {}
+};

View File

@ -1,188 +0,0 @@
This backport contains 2 patchs from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-Find-matched-aggregate-lattice-for-self-recursive-CP.patch
709d7838e753bbb6f16e2ed88a118ed81c367040
0002-Do-not-propagate-self-dependent-value-PR-ipa-93763.patch
47772af10c00f7e1e95cd52557fc893dc602a420
diff -Nurp a/gcc/ipa-cp.c b/gcc/ipa-cp.c
--- a/gcc/ipa-cp.c 2020-05-23 16:16:58.032000000 +0800
+++ b/gcc/ipa-cp.c 2020-05-22 18:03:41.980000000 +0800
@@ -1766,8 +1766,8 @@ ipcp_lattice<valtype>::add_value (valtyp
}
/* Return true, if a ipcp_value VAL is orginated from parameter value of
- self-feeding recursive function by applying non-passthrough arithmetic
- transformation. */
+ self-feeding recursive function via some kind of pass-through jump
+ function. */
static bool
self_recursively_generated_p (ipcp_value<tree> *val)
@@ -1778,19 +1778,36 @@ self_recursively_generated_p (ipcp_value
{
cgraph_edge *cs = src->cs;
- if (!src->val || cs->caller != cs->callee->function_symbol ()
- || src->val == val)
+ if (!src->val || cs->caller != cs->callee->function_symbol ())
return false;
+ if (src->val == val)
+ continue;
+
if (!info)
info = IPA_NODE_REF (cs->caller);
class ipcp_param_lattices *plats = ipa_get_parm_lattices (info,
src->index);
- ipcp_lattice<tree> *src_lat = src->offset == -1 ? &plats->itself
- : plats->aggs;
+ ipcp_lattice<tree> *src_lat;
ipcp_value<tree> *src_val;
+ if (src->offset == -1)
+ src_lat = &plats->itself;
+ else
+ {
+ struct ipcp_agg_lattice *src_aglat;
+
+ for (src_aglat = plats->aggs; src_aglat; src_aglat = src_aglat->next)
+ if (src_aglat->offset == src->offset)
+ break;
+
+ if (!src_aglat)
+ return false;
+
+ src_lat = src_aglat;
+ }
+
for (src_val = src_lat->values; src_val; src_val = src_val->next)
if (src_val == val)
break;
@@ -1887,6 +1904,8 @@ propagate_vals_across_arith_jfunc (cgrap
val_seeds.safe_push (src_val);
}
+ gcc_assert ((int) val_seeds.length ()
+ <= PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE));
/* Recursively generate lattice values with a limited count. */
FOR_EACH_VEC_ELT (val_seeds, i, src_val)
{
diff -Nurp a/gcc/testsuite/gcc.dg/ipa/ipa-clone-3.c b/gcc/testsuite/gcc.dg/ipa/ipa-clone-3.c
--- a/gcc/testsuite/gcc.dg/ipa/ipa-clone-3.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-clone-3.c 2020-05-22 17:55:24.036000000 +0800
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details -fno-early-inlining --param ipa-cp-max-recursive-depth=8 --param ipa-cp-eval-threshold=1" } */
+
+struct V {
+ int f0;
+ int f1;
+};
+
+int data[100];
+
+int fn ();
+
+int recur_fn (struct V * __restrict v)
+{
+ int i = v->f0;
+ int j = v->f1;
+ struct V t;
+
+ if (j > 100)
+ {
+ fn ();
+ return 1;
+ }
+
+ data[i] = i;
+
+ t.f0 = i - 2;
+ t.f1 = j + 1;
+
+ recur_fn (&t);
+
+ return i * j;
+}
+
+int main ()
+{
+ struct V v = {1, 3};
+
+ return recur_fn (&v);
+}
+
+/* { dg-final { scan-ipa-dump-times "Creating a specialized node of recur_fn/\[0-9\]*\\." 8 "cp" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/ipa/pr93763.c b/gcc/testsuite/gcc.dg/ipa/pr93763.c
--- a/gcc/testsuite/gcc.dg/ipa/pr93763.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/ipa/pr93763.c 2020-05-22 17:57:10.532000000 +0800
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+typedef struct a a;
+struct a {
+ a *b
+} d;
+e, k, ah, al;
+f(aa) {
+ if (aa & 1)
+ goto g;
+ f(aa | 2);
+g:
+ h();
+}
+l() {
+ {
+ f(072);
+ i(e, d, 92);
+ }
+}
+ag() {
+ { i(e, d, 36); }
+}
+ai(a *m, a *n, unsigned aa) {
+ f(aa);
+ j(k, l, ah, 1);
+}
+j(int c, a m, int aj, int aa) {
+ int ak = aa;
+ { i(e, d, ak); }
+}
+i(int c, a *m, unsigned aa) {
+ {
+ { i(c, (*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(
+*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(
+*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*m).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b)
+.b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b)
+.b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b)
+.b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b)
+.b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b, 0);
+ }
+ }
+ int am = aa;
+ ai(ag, al, am);
+}
diff -Nurp a/gcc/testsuite/g++.dg/ipa/pr93763.C b/gcc/testsuite/g++.dg/ipa/pr93763.C
--- a/gcc/testsuite/g++.dg/ipa/pr93763.C 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/g++.dg/ipa/pr93763.C 2020-05-22 17:57:10.532000000 +0800
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+struct search_param {
+ int total;
+};
+void search_trivial(search_param error_left) {
+ search_trivial(error_left);
+ search_param error_left2{error_left};
+ error_left2.total--;
+ search_trivial(error_left2);
+}
+void search_algo_uni(search_param error_left) { search_trivial(error_left); }
+void search_algo(search_param error_left) { search_algo_uni(error_left); }
+int main() { search_algo({}); return 0; }

File diff suppressed because it is too large Load Diff

View File

@ -1,619 +0,0 @@
diff -Nurp a/gcc/fold-const.c b/gcc/fold-const.c
--- a/gcc/fold-const.c 2020-09-17 02:26:36.900000000 -0400
+++ b/gcc/fold-const.c 2020-09-17 02:27:57.368000000 -0400
@@ -7165,15 +7165,9 @@ fold_plusminus_mult_expr (location_t loc
increased the number of multiplications necessary. */
&& TREE_CODE (arg10) != INTEGER_CST)
{
- HOST_WIDE_INT tmp1 = int01 / int11;
- HOST_WIDE_INT t = exact_log2 (absu_hwi (int11));
- HOST_WIDE_INT size = tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (arg00))) * BITS_PER_UNIT;
- HOST_WIDE_INT sign_bit = HOST_WIDE_INT_1U << (size - t - 1);
- if (tmp1 & sign_bit)
- tmp1 |= HOST_WIDE_INT_M1U << (size - t);
- tree tmp2 = build_int_cst (TREE_TYPE (arg00), tmp1);
alt0 = fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg00), arg00,
- tmp2);
+ build_int_cst (TREE_TYPE (arg00),
+ int01 / int11));
alt1 = arg10;
same = maybe_same;
if (swap)
diff -Nurp a/gcc/ipa-struct-reorg/ipa-struct-reorg.c b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.c 2020-09-17 02:26:36.900000000 -0400
+++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.c 2020-09-17 02:34:04.040000000 -0400
@@ -112,6 +112,29 @@ is_va_list_type (tree type)
return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
}
+static const char *
+get_type_name (tree type)
+{
+ const char *tname = NULL;
+
+ if (type == NULL)
+ {
+ return NULL;
+ }
+
+ if (TYPE_NAME (type) != NULL)
+ {
+ if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
+ {
+ tname = IDENTIFIER_POINTER (TYPE_NAME (type));
+ }
+ else if (DECL_NAME (TYPE_NAME (type)) != NULL)
+ {
+ tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+ }
+ }
+ return tname;
+}
/* Return the inner most type for arrays and pointers of TYPE. */
@@ -463,10 +486,10 @@ srtype::analyze (void)
if (fields.length () == 2)
fields[1]->clusternum = 1;
- /* REMOVEME: FIXME: this is here for testing more testcases. */
+ /* Otherwise we do nothing. */
if (fields.length () >= 3)
{
- fields[1]->clusternum = 1;
+ return;
}
}
@@ -875,6 +898,7 @@ private:
void analyze_types (void);
void clear_visited (void);
bool create_new_types (void);
+ void restore_field_type (void);
void create_new_decls (void);
srdecl *find_decl (tree);
void create_new_functions (void);
@@ -1096,6 +1120,11 @@ ipa_struct_reorg::record_type (tree type
{
tree t = TREE_TYPE (field);
process_union (t);
+ if (TREE_CODE (inner_type (t)) == UNION_TYPE
+ || TREE_CODE (inner_type (t)) == QUAL_UNION_TYPE)
+ {
+ type1->mark_escape (escape_union, NULL);
+ }
if (isvolatile_type (t))
type1->mark_escape (escape_volatile, NULL);
escape_type e = escape_type_volatile_array_or_ptrptr (t);
@@ -2818,6 +2847,49 @@ ipa_struct_reorg::analyze_types (void)
}
}
+/* When struct A has a struct B member, B's type info
+ is not stored in
+ TYPE_FIELDS (TREE_TYPE (TYPE_FIELDS (typeA)))
+ Try to restore B's type information. */
+void
+ipa_struct_reorg::restore_field_type (void)
+{
+ for (unsigned i = 0; i < types.length (); i++)
+ {
+ for (unsigned j = 0; j < types[i]->fields.length (); j++)
+ {
+ srfield *field = types[i]->fields[j];
+ if (TREE_CODE (inner_type (field->fieldtype)) == RECORD_TYPE)
+ {
+ /* If field type has TYPE_FIELDS information,
+ we do not need to do this. */
+ if (TYPE_FIELDS (field->type->type) != NULL)
+ {
+ continue;
+ }
+ for (unsigned k = 0; k < types.length (); k++)
+ {
+ if (i == k)
+ {
+ continue;
+ }
+ const char *type1 = get_type_name (field->type->type);
+ const char *type2 = get_type_name (types[k]->type);
+ if (type1 == NULL || type2 == NULL)
+ {
+ continue;
+ }
+ if (type1 == type2
+ && TYPE_FIELDS (types[k]->type))
+ {
+ field->type = types[k];
+ }
+ }
+ }
+ }
+ }
+}
+
/* Create all new types we want to create. */
bool
@@ -3669,7 +3741,7 @@ ipa_struct_reorg::rewrite_functions (voi
{
unsigned retval = 0;
-
+ restore_field_type ();
/* Create new types, if we did not create any new types,
then don't rewrite any accesses. */
if (!create_new_types ())
diff -Nurp a/gcc/testsuite/gcc.c-torture/compile/20170404-1.c b/gcc/testsuite/gcc.c-torture/compile/20170404-1.c
--- a/gcc/testsuite/gcc.c-torture/compile/20170404-1.c 2020-09-17 02:26:36.904000000 -0400
+++ b/gcc/testsuite/gcc.c-torture/compile/20170404-1.c 1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-struct a
-{
- int t, t1;
-};
-
-static struct a *b;
-
-void *xmalloc(int);
-
-
-void f(void)
-{
- b = xmalloc (sizeof(*b));
-}
-
-int g(void)
-{
- return b->t;
-}
diff -Nurp a/gcc/testsuite/gcc.c-torture/compile/nested-3.c b/gcc/testsuite/gcc.c-torture/compile/nested-3.c
--- a/gcc/testsuite/gcc.c-torture/compile/nested-3.c 2020-09-17 02:26:36.904000000 -0400
+++ b/gcc/testsuite/gcc.c-torture/compile/nested-3.c 2020-09-17 02:27:57.372000000 -0400
@@ -1,4 +1,3 @@
-/* This used to crash Struct reorg. */
struct a
{
int t;
diff -Nurp a/gcc/testsuite/gcc.c-torture/compile/struct-reorg-1.c b/gcc/testsuite/gcc.c-torture/compile/struct-reorg-1.c
--- a/gcc/testsuite/gcc.c-torture/compile/struct-reorg-1.c 2020-09-17 02:26:36.904000000 -0400
+++ b/gcc/testsuite/gcc.c-torture/compile/struct-reorg-1.c 1969-12-31 19:00:00.000000000 -0500
@@ -1,18 +0,0 @@
-#include <stdlib.h>
-typedef struct {
- long laststart_offset;
- unsigned regnum;
-} compile_stack_elt_t;
-typedef struct {
- compile_stack_elt_t *stack;
- unsigned size;
-} compile_stack_type;
-void f (const char *p, const char *pend, int c)
-{
- compile_stack_type compile_stack;
- while (p != pend)
- if (c)
- compile_stack.stack = realloc (compile_stack.stack,
- (compile_stack.size << 1)
- * sizeof (compile_stack_elt_t));
-}
diff -Nurp a/gcc/testsuite/gcc.dg/pr33136-4.c b/gcc/testsuite/gcc.dg/pr33136-4.c
--- a/gcc/testsuite/gcc.dg/pr33136-4.c 2020-09-17 02:26:36.904000000 -0400
+++ b/gcc/testsuite/gcc.dg/pr33136-4.c 1969-12-31 19:00:00.000000000 -0500
@@ -1,59 +0,0 @@
-/* PR tree-optimization/33136 */
-/* { dg-do run } */
-/* { dg-options "-O2" } */
-
-extern void abort (void);
-
-struct S
-{
- int b;
- int *c;
-};
-static int d, e;
-
-static struct S s;
-
-static int *
-__attribute__((noinline, const))
-foo (void)
-{
- return &s.b;
-}
-
-int *
-__attribute__((noinline))
-bar (int **f)
-{
- s.c = &d;
- *f = &e;
- /* As nothing ever takes the address of any int * field in struct S,
- the write to *f can't alias with the s.c field. */
- return s.c;
-}
-
-int
-__attribute__((noinline))
-baz (int *x)
-{
- s.b = 1;
- *x = 4;
- /* Function foo takes address of an int field in struct S,
- so *x can alias with the s.b field (and it does in this testcase). */
- return s.b;
-}
-
-int
-__attribute__((noinline))
-t (void)
-{
- int *f = (int *) 0;
- return 10 * (bar (&f) != &d) + baz (foo ());
-}
-
-int
-main (void)
-{
- if (t () != 4)
- abort ();
- return 0;
-}
diff -Nurp a/gcc/testsuite/gcc.dg/struct/struct_reorg-1.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-1.c
--- a/gcc/testsuite/gcc.dg/struct/struct_reorg-1.c 1969-12-31 19:00:00.000000000 -0500
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-1.c 2020-09-17 02:27:57.372000000 -0400
@@ -0,0 +1,24 @@
+// { dg-do compile }
+// { dg-options "-O3 -flto-partition=one -fipa-struct-reorg -fdump-ipa-all" }
+
+struct a
+{
+ int t, t1;
+};
+
+static struct a *b;
+
+void *xmalloc(int);
+
+
+void f(void)
+{
+ b = xmalloc (sizeof(*b));
+}
+
+int g(void)
+{
+ return b->t;
+}
+
+/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/struct_reorg-2.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-2.c
--- a/gcc/testsuite/gcc.dg/struct/struct_reorg-2.c 1969-12-31 19:00:00.000000000 -0500
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-2.c 2020-09-17 02:27:57.372000000 -0400
@@ -0,0 +1,29 @@
+// { dg-do run }
+
+#include <assert.h>
+
+struct a
+{
+ int t;
+ int t1;
+};
+
+__attribute__((noinline)) int f(int i, int j)
+{
+ struct a *t;
+ struct a t1 = {i, j};
+ t = &t1;
+ auto int g(void) __attribute__((noinline));
+ int g(void)
+ {
+ return t->t + t->t1;
+ }
+ return g();
+}
+
+int main()
+{
+ assert (f(1, 2) == 3);
+}
+
+/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/struct_reorg-3.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-3.c
--- a/gcc/testsuite/gcc.dg/struct/struct_reorg-3.c 1969-12-31 19:00:00.000000000 -0500
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-3.c 2020-09-17 02:27:57.372000000 -0400
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-O3 -flto-partition=one -fipa-struct-reorg -fdump-ipa-all" }
+
+#include <stdlib.h>
+typedef struct {
+ long laststart_offset;
+ unsigned regnum;
+} compile_stack_elt_t;
+typedef struct {
+ compile_stack_elt_t *stack;
+ unsigned size;
+} compile_stack_type;
+void f (const char *p, const char *pend, int c)
+{
+ compile_stack_type compile_stack;
+ while (p != pend)
+ if (c)
+ compile_stack.stack = realloc (compile_stack.stack,
+ (compile_stack.size << 1)
+ * sizeof (compile_stack_elt_t));
+}
+
+/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/struct_reorg-4.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-4.c
--- a/gcc/testsuite/gcc.dg/struct/struct_reorg-4.c 1969-12-31 19:00:00.000000000 -0500
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-4.c 2020-09-17 02:27:57.372000000 -0400
@@ -0,0 +1,59 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+struct S
+{
+ int b;
+ int *c;
+};
+static int d, e;
+
+static struct S s;
+
+static int *
+__attribute__((noinline, const))
+foo (void)
+{
+ return &s.b;
+}
+
+int *
+__attribute__((noinline))
+bar (int **f)
+{
+ s.c = &d;
+ *f = &e;
+ /* As nothing ever takes the address of any int * field in struct S,
+ the write to *f can't alias with the s.c field. */
+ return s.c;
+}
+
+int
+__attribute__((noinline))
+baz (int *x)
+{
+ s.b = 1;
+ *x = 4;
+ /* Function foo takes address of an int field in struct S,
+ so *x can alias with the s.b field (and it does in this testcase). */
+ return s.b;
+}
+
+int
+__attribute__((noinline))
+t (void)
+{
+ int *f = (int *) 0;
+ return 10 * (bar (&f) != &d) + baz (foo ());
+}
+
+int
+main (void)
+{
+ if (t () != 4)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/struct-reorg.exp b/gcc/testsuite/gcc.dg/struct/struct-reorg.exp
--- a/gcc/testsuite/gcc.dg/struct/struct-reorg.exp 2020-09-17 02:26:36.904000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/struct-reorg.exp 2020-09-17 02:27:57.372000000 -0400
@@ -1,5 +1,4 @@
-# Copyright (C) 2007, 2008, 2009, 2010
-# Free Software Foundation, Inc.
+# Copyright (C) 1997-2019 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
@@ -12,12 +11,9 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING3. If not see
+# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
-# Test the functionality of programs compiled with profile-directed structure
-# rearrangement using -fprofile-generate followed by -fprofile-use.
-
load_lib gcc-dg.exp
load_lib target-supports.exp
@@ -26,62 +22,14 @@ dg-init
torture-init
set STRUCT_REORG_TORTURE_OPTIONS [list \
- { -O1 } \
- { -O1 -g } \
- { -O2 } \
- { -O2 -g } \
- { -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions } \
- { -O3 -g } \
- { -Os } ]
-
+ { -O3 } \
+ { -Ofast } ]
-set-torture-options $STRUCT_REORG_TORTURE_OPTIONS {{}} $LTO_TORTURE_OPTIONS
+set-torture-options $STRUCT_REORG_TORTURE_OPTIONS {{}}
-gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/wo_prof_*.c]] "" "-fipa-struct-reorg -fdump-ipa-all -fwhole-program"
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] \
+ "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program"
+# All done.
torture-finish
-dg-final
-
-# Some targets don't support tree profiling.
-if { ![check_profiling_available ""] } {
- return
-}
-
-# The procedures in profopt.exp need these parameters.
-set tool gcc
-set prof_ext "gcda"
-
-# Override the list defined in profopt.exp.
-set PROFOPT_OPTIONS [list {}]
-
-if $tracelevel then {
- strace $tracelevel
-}
-
-# Load support procs.
-load_lib profopt.exp
-
-# These are globals used by profopt-execute. The first is options
-# needed to generate profile data, the second is options to use the
-# profile data.
-set common "-O3 -fwhole-program"
-set profile_option [concat $common " -fprofile-generate"]
-set feedback_option [concat $common " -fprofile-use -fipa-struct-reorg -fdump-ipa-all"]
-
-foreach src [lsort [glob -nocomplain $srcdir/$subdir/w_prof_*.c]] {
- # If we're only testing specific files and this isn't one of them, skip it.
- if ![runtest_file_p $runtests $src] then {
- continue
- }
- profopt-execute $src
-}
-
-set feedback_option [concat $feedback_option " --param struct-reorg-cold-struct-ratio=30"]
-
-foreach src [lsort [glob -nocomplain $srcdir/$subdir/w_ratio_*.c]] {
- # If we're only testing specific files and this isn't one of them, skip it.
- if ![runtest_file_p $runtests $src] then {
- continue
- }
- profopt-execute $src
-}
+dg-finish
diff -Nurp a/gcc/testsuite/gcc.dg/struct/wo_prof_escape_str_init.c b/gcc/testsuite/gcc.dg/struct/wo_prof_escape_str_init.c
--- a/gcc/testsuite/gcc.dg/struct/wo_prof_escape_str_init.c 2020-09-17 02:26:36.904000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/wo_prof_escape_str_init.c 2020-09-17 02:27:57.372000000 -0400
@@ -28,4 +28,4 @@ main ()
}
/*--------------------------------------------------------------------------*/
-/* { dg-final { scan-ipa-dump "has escaped...Type is used in an array" "struct_reorg" } } */
+/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/wo_prof_mult_field_peeling.c b/gcc/testsuite/gcc.dg/struct/wo_prof_mult_field_peeling.c
--- a/gcc/testsuite/gcc.dg/struct/wo_prof_mult_field_peeling.c 2020-09-17 02:26:36.904000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/wo_prof_mult_field_peeling.c 2020-09-17 02:27:57.372000000 -0400
@@ -38,5 +38,5 @@ main ()
}
/*--------------------------------------------------------------------------*/
-/* The structure str_t is erroneously peeled into 4 structures instead of 2. */
-/* { dg-final { scan-ipa-dump "the number of new types is 2" "struct_reorg" } } */
+/* Two more fields structure is not splitted. */
+/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/w_prof_global_array.c b/gcc/testsuite/gcc.dg/struct/w_prof_global_array.c
--- a/gcc/testsuite/gcc.dg/struct/w_prof_global_array.c 2020-09-17 02:26:36.904000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_global_array.c 2020-09-17 02:27:57.372000000 -0400
@@ -26,4 +26,4 @@ main ()
}
/*--------------------------------------------------------------------------*/
-/* { dg-final-use { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */
+/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/w_prof_global_var.c b/gcc/testsuite/gcc.dg/struct/w_prof_global_var.c
--- a/gcc/testsuite/gcc.dg/struct/w_prof_global_var.c 2020-09-17 02:26:36.908000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_global_var.c 2020-09-17 02:27:57.372000000 -0400
@@ -39,4 +39,4 @@ main ()
}
/*--------------------------------------------------------------------------*/
-/* { dg-final-use { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */
+/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/w_prof_local_array.c b/gcc/testsuite/gcc.dg/struct/w_prof_local_array.c
--- a/gcc/testsuite/gcc.dg/struct/w_prof_local_array.c 2020-09-17 02:26:36.908000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_local_array.c 2020-09-17 02:27:57.372000000 -0400
@@ -34,4 +34,4 @@ main ()
}
/*--------------------------------------------------------------------------*/
-/* { dg-final-use { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */
+/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/w_prof_local_var.c b/gcc/testsuite/gcc.dg/struct/w_prof_local_var.c
--- a/gcc/testsuite/gcc.dg/struct/w_prof_local_var.c 2020-09-17 02:26:36.908000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_local_var.c 2020-09-17 02:27:57.372000000 -0400
@@ -37,4 +37,4 @@ main ()
}
/*--------------------------------------------------------------------------*/
-/* { dg-final-use { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */
+/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/w_prof_single_str_global.c b/gcc/testsuite/gcc.dg/struct/w_prof_single_str_global.c
--- a/gcc/testsuite/gcc.dg/struct/w_prof_single_str_global.c 2020-09-17 02:26:36.908000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_single_str_global.c 2020-09-17 02:27:57.372000000 -0400
@@ -28,4 +28,4 @@ main ()
}
/*--------------------------------------------------------------------------*/
-/* { dg-final-use { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */
+/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/w_prof_two_strs.c b/gcc/testsuite/gcc.dg/struct/w_prof_two_strs.c
--- a/gcc/testsuite/gcc.dg/struct/w_prof_two_strs.c 2020-09-17 02:26:36.908000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_two_strs.c 2020-09-17 02:27:57.372000000 -0400
@@ -61,4 +61,4 @@ main ()
}
/*--------------------------------------------------------------------------*/
-/* { dg-final-use { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */
+/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */
diff -Nurp a/gcc/testsuite/gcc.dg/struct/w_ratio_cold_str.c b/gcc/testsuite/gcc.dg/struct/w_ratio_cold_str.c
--- a/gcc/testsuite/gcc.dg/struct/w_ratio_cold_str.c 2020-09-17 02:26:36.908000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_ratio_cold_str.c 2020-09-17 02:27:57.372000000 -0400
@@ -40,4 +40,4 @@ main ()
/*--------------------------------------------------------------------------*/
/* Arrays are not handled. */
-/* { dg-final-use { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */
+/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */
diff -Nurp a/gcc/testsuite/g++.dg/torture/pr38355.C b/gcc/testsuite/g++.dg/torture/pr38355.C
--- a/gcc/testsuite/g++.dg/torture/pr38355.C 2020-09-17 02:26:36.908000000 -0400
+++ b/gcc/testsuite/g++.dg/torture/pr38355.C 1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-// { dg-do run }
-// { dg-options "-fwhole-program -fipa-struct-reorg" }
-template<int> struct A
-{
- char c;
- void foo(int);
- void bar(int i) { foo(i+1); }
-};
-
-template<int> struct B : virtual A<0> {};
-
-template<int T> inline void baz(B<T>& b, int i)
-{
- if (i) b.bar(0);
-}
-
-extern template class A<0>;
-extern template void baz(B<0>&, int);
-
-int main()
-{
- B<0> b;
- baz(b, 0);
- return 0;
-}

File diff suppressed because it is too large Load Diff

View File

@ -1,181 +0,0 @@
re-PR-tree-optimization-90240-ICE-in-try_improve_iv_.patch:
commit 98d8f142132ac670da2dc99cce530048343ab948
diff -urpN a/gcc/testsuite/gfortran.dg/graphite/pr90240.f b/gcc/testsuite/gfortran.dg/graphite/pr90240.f
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/graphite/pr90240.f
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-options "-O1 -floop-nest-optimize" }
+
+ PARAMETER (n=1335, N2=1335)
+ COMMON a(n,N2), b(n,N2), c(n,N2),
+ * d(n,N2),
+ 2 e(n,N2), f(n,N2),
+ * g(n,N2), h(n,N2)
+ DO 200 j=1,i
+ DO 300 k=1,l
+ a(k,j) = c(k,j)*g(k,j)*f(k+1,m)+f(k,m)+f(k,j)
+ 2 +f(k+1,j)*h(k+1,j)
+ b(k,j+1) = d(k,j+1)*g(k,m)+g(k,j+1)
+ 1 *e(k,m)+e(k,j+1)+e(k,j)+e(k+1,j)
+ 2 *h(k,j+1)-h(k,j)
+ 300 ENDDO
+ 200 ENDDO
+ END
diff -urpN a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -4557,22 +4557,25 @@ get_address_cost (struct ivopts_data *data, struct iv_use *use,
static comp_cost
get_scaled_computation_cost_at (ivopts_data *data, gimple *at, comp_cost cost)
{
- int loop_freq = data->current_loop->header->count.to_frequency (cfun);
- int bb_freq = gimple_bb (at)->count.to_frequency (cfun);
- if (loop_freq != 0)
- {
- gcc_assert (cost.scratch <= cost.cost);
- int scaled_cost
- = cost.scratch + (cost.cost - cost.scratch) * bb_freq / loop_freq;
+ if (data->speed
+ && data->current_loop->header->count.to_frequency (cfun) > 0)
+ {
+ basic_block bb = gimple_bb (at);
+ gcc_assert (cost.scratch <= cost.cost);
+ int scale_factor = (int)(intptr_t) bb->aux;
+ if (scale_factor == 1)
+ return cost;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Scaling cost based on bb prob "
- "by %2.2f: %d (scratch: %d) -> %d (%d/%d)\n",
- 1.0f * bb_freq / loop_freq, cost.cost,
- cost.scratch, scaled_cost, bb_freq, loop_freq);
+ int scaled_cost
+ = cost.scratch + (cost.cost - cost.scratch) * scale_factor;
- cost.cost = scaled_cost;
- }
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Scaling cost based on bb prob "
+ "by %2.2f: %d (scratch: %d) -> %d\n",
+ 1.0f * scale_factor, cost.cost, cost.scratch, scaled_cost);
+
+ cost.cost = scaled_cost;
+ }
return cost;
}
@@ -6678,9 +6681,8 @@ try_improve_iv_set (struct ivopts_data *data,
}
iv_ca_delta_commit (data, ivs, best_delta, true);
- gcc_assert (best_cost == iv_ca_cost (ivs));
iv_ca_delta_free (&best_delta);
- return true;
+ return best_cost == iv_ca_cost (ivs);
}
/* Attempts to find the optimal set of induction variables. We do simple
@@ -6717,6 +6719,14 @@ find_optimal_iv_set_1 (struct ivopts_data *data, bool originalp)
}
}
+ /* If the set has infinite_cost, it can't be optimal. */
+ if (iv_ca_cost (set).infinite_cost_p ())
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "Overflow to infinite cost in try_improve_iv_set.\n");
+ iv_ca_free (&set);
+ }
return set;
}
@@ -7522,6 +7532,49 @@ loop_body_includes_call (basic_block *body, unsigned num_nodes)
return false;
}
+/* Determine cost scaling factor for basic blocks in loop. */
+#define COST_SCALING_FACTOR_BOUND (20)
+
+static void
+determine_scaling_factor (struct ivopts_data *data, basic_block *body)
+{
+ int lfreq = data->current_loop->header->count.to_frequency (cfun);
+ if (!data->speed || lfreq <= 0)
+ return;
+
+ int max_freq = lfreq;
+ for (unsigned i = 0; i < data->current_loop->num_nodes; i++)
+ {
+ body[i]->aux = (void *)(intptr_t) 1;
+ if (max_freq < body[i]->count.to_frequency (cfun))
+ max_freq = body[i]->count.to_frequency (cfun);
+ }
+ if (max_freq > lfreq)
+ {
+ int divisor, factor;
+ /* Check if scaling factor itself needs to be scaled by the bound. This
+ is to avoid overflow when scaling cost according to profile info. */
+ if (max_freq / lfreq > COST_SCALING_FACTOR_BOUND)
+ {
+ divisor = max_freq;
+ factor = COST_SCALING_FACTOR_BOUND;
+ }
+ else
+ {
+ divisor = lfreq;
+ factor = 1;
+ }
+ for (unsigned i = 0; i < data->current_loop->num_nodes; i++)
+ {
+ int bfreq = body[i]->count.to_frequency (cfun);
+ if (bfreq <= lfreq)
+ continue;
+
+ body[i]->aux = (void*)(intptr_t) (factor * bfreq / divisor);
+ }
+ }
+}
+
/* Optimizes the LOOP. Returns true if anything changed. */
static bool
@@ -7560,7 +7613,6 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop,
body = get_loop_body (loop);
data->body_includes_call = loop_body_includes_call (body, loop->num_nodes);
renumber_gimple_stmt_uids_in_blocks (body, loop->num_nodes);
- free (body);
data->loop_single_exit_p = exit != NULL && loop_only_exit_p (loop, exit);
@@ -7574,6 +7626,9 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop,
if (data->vgroups.length () > MAX_CONSIDERED_GROUPS)
goto finish;
+ /* Determine cost scaling factor for basic blocks in loop. */
+ determine_scaling_factor (data, body);
+
/* Finds candidates for the induction variables (item 2). */
find_iv_candidates (data);
@@ -7584,6 +7639,9 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop,
/* Find the optimal set of induction variables (item 3, part 2). */
iv_ca = find_optimal_iv_set (data);
+ /* Cleanup basic block aux field. */
+ for (unsigned i = 0; i < data->current_loop->num_nodes; i++)
+ body[i]->aux = NULL;
if (!iv_ca)
goto finish;
changed = true;
@@ -7599,6 +7657,7 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop,
remove_unused_ivs (data, toremove);
finish:
+ free (body);
free_loop_data (data);
return changed;

View File

@ -1,410 +0,0 @@
re-PR-tree-optimization-90078-ICE-with-deep-template.patch:
commit 8363a2f1f7c47d7b3d1760ce631a6824e91c0d80
diff -urpN a/gcc/testsuite/g++.dg/tree-ssa/pr90078.C b/gcc/testsuite/g++.dg/tree-ssa/pr90078.C
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr90078.C
@@ -0,0 +1,199 @@
+// { dg-do compile }
+// { dg-options "-std=c++14 -O2 -ftemplate-depth=1000000" }
+
+template <class T, int Dim0, int Dim1, int Dim2> struct Tensor3;
+template <class A, class T, int Dim0, int Dim1, int Dim2, char i, char j,
+ char k>
+struct Tensor3_Expr;
+
+template <class T, int Dim0, int Dim1, int Dim2, int Dim3> struct Tensor4;
+template <class A, class T, int Dim0, int Dim1, int Dim2, int Dim3, char i,
+ char j, char k, char l>
+struct Tensor4_Expr;
+
+template <char i, int Dim> struct Index
+{};
+template <const int N> struct Number
+{
+ Number(){};
+ operator int() const { return N; }
+};
+
+template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2>
+struct Tensor3
+{
+ T data[Tensor_Dim0][Tensor_Dim1][Tensor_Dim2];
+
+ T operator()(const int N1, const int N2, const int N3) const
+ {
+ return data[N1][N2][N3];
+ }
+
+ template <char i, char j, char k, int Dim0, int Dim1, int Dim2>
+ Tensor3_Expr<const Tensor3<T, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2>, T,
+ Dim0, Dim1, Dim2, i, j, k>
+ operator()(const Index<i, Dim0>, const Index<j, Dim1>,
+ const Index<k, Dim2>) const
+ {
+ return Tensor3_Expr<const Tensor3<T, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2>,
+ T, Dim0, Dim1, Dim2, i, j, k>(*this);
+ }
+};
+
+template <class A, class T, int Dim0, int Dim1, int Dim2, char i, char j,
+ char k>
+struct Tensor3_Expr
+{
+ A iter;
+
+ Tensor3_Expr(const A &a) : iter(a) {}
+ T operator()(const int N1, const int N2, const int N3) const
+ {
+ return iter(N1, N2, N3);
+ }
+};
+
+template <class A, class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2,
+ int Dim0, int Dim1, int Dim2, char i, char j, char k>
+struct Tensor3_Expr<Tensor3<A, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2>, T, Dim0,
+ Dim1, Dim2, i, j, k>
+{
+ Tensor3<A, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2> &iter;
+
+ Tensor3_Expr(Tensor3<A, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2> &a) : iter(a)
+ {}
+ T operator()(const int N1, const int N2, const int N3) const
+ {
+ return iter(N1, N2, N3);
+ }
+};
+
+template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim23,
+ int Dim4, int Dim5, char i, char j, char k, char l, char m>
+struct Tensor3_times_Tensor3_21
+{
+ Tensor3_Expr<A, T, Dim0, Dim1, Dim23, i, j, k> iterA;
+ Tensor3_Expr<B, U, Dim23, Dim4, Dim5, k, l, m> iterB;
+
+ template <int CurrentDim>
+ T eval(const int N1, const int N2, const int N3, const int N4,
+ const Number<CurrentDim> &) const
+ {
+ return iterA(N1, N2, CurrentDim - 1) * iterB(CurrentDim - 1, N3, N4)
+ + eval(N1, N2, N3, N4, Number<CurrentDim - 1>());
+ }
+ T eval(const int N1, const int N2, const int N3, const int N4,
+ const Number<1> &) const
+ {
+ return iterA(N1, N2, 0) * iterB(0, N3, N4);
+ }
+
+ Tensor3_times_Tensor3_21(
+ const Tensor3_Expr<A, T, Dim0, Dim1, Dim23, i, j, k> &a,
+ const Tensor3_Expr<B, U, Dim23, Dim4, Dim5, k, l, m> &b)
+ : iterA(a), iterB(b)
+ {}
+ T operator()(const int &N1, const int &N2, const int &N3,
+ const int &N4) const
+ {
+ return eval(N1, N2, N3, N4, Number<Dim23>());
+ }
+};
+
+template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim23,
+ int Dim4, int Dim5, char i, char j, char k, char l, char m>
+Tensor4_Expr<Tensor3_times_Tensor3_21<A, B, T, U, Dim0, Dim1, Dim23, Dim4,
+ Dim5, i, j, k, l, m>,
+ T, Dim0, Dim1, Dim4, Dim5, i, j, l, m>
+operator*(const Tensor3_Expr<A, T, Dim0, Dim1, Dim23, i, j, k> &a,
+ const Tensor3_Expr<B, U, Dim23, Dim4, Dim5, k, l, m> &b)
+{
+ using TensorExpr = Tensor3_times_Tensor3_21<A, B, T, U, Dim0, Dim1, Dim23,
+ Dim4, Dim5, i, j, k, l, m>;
+ return Tensor4_Expr<TensorExpr, T, Dim0, Dim1, Dim4, Dim5, i, j, l, m>(
+ TensorExpr(a, b));
+};
+
+template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2,
+ int Tensor_Dim3>
+struct Tensor4
+{
+ T data[Tensor_Dim0][Tensor_Dim1][Tensor_Dim2][Tensor_Dim3];
+
+ Tensor4() {}
+ T &operator()(const int N1, const int N2, const int N3, const int N4)
+ {
+ return data[N1][N2][N3][N4];
+ }
+
+ template <char i, char j, char k, char l, int Dim0, int Dim1, int Dim2,
+ int Dim3>
+ Tensor4_Expr<Tensor4<T, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>,
+ T, Dim0, Dim1, Dim2, Dim3, i, j, k, l>
+ operator()(const Index<i, Dim0>, const Index<j, Dim1>, const Index<k, Dim2>,
+ const Index<l, Dim3>)
+ {
+ return Tensor4_Expr<
+ Tensor4<T, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>, T, Dim0,
+ Dim1, Dim2, Dim3, i, j, k, l>(*this);
+ };
+};
+
+template <class A, class T, int Dim0, int Dim1, int Dim2, int Dim3, char i,
+ char j, char k, char l>
+struct Tensor4_Expr
+{
+ A iter;
+
+ Tensor4_Expr(const A &a) : iter(a) {}
+ T operator()(const int N1, const int N2, const int N3, const int N4) const
+ {
+ return iter(N1, N2, N3, N4);
+ }
+};
+
+template <class A, class T, int Dim0, int Dim1, int Dim2, int Dim3, char i,
+ char j, char k, char l>
+struct Tensor4_Expr<Tensor4<A, Dim0, Dim1, Dim2, Dim3>, T, Dim0, Dim1, Dim2,
+ Dim3, i, j, k, l>
+{
+ Tensor4<A, Dim0, Dim1, Dim2, Dim3> &iter;
+
+ Tensor4_Expr(Tensor4<A, Dim0, Dim1, Dim2, Dim3> &a) : iter(a) {}
+ T operator()(const int N1, const int N2, const int N3, const int N4) const
+ {
+ return iter(N1, N2, N3, N4);
+ }
+
+ template <class B, class U, int Dim1_0, int Dim1_1, int Dim1_2, int Dim1_3,
+ char i_1, char j_1, char k_1, char l_1>
+ auto &operator=(const Tensor4_Expr<B, U, Dim1_0, Dim1_1, Dim1_2, Dim1_3, i_1,
+ j_1, k_1, l_1> &rhs)
+ {
+ for(int ii = 0; ii < Dim0; ++ii)
+ for(int jj = 0; jj < Dim1; ++jj)
+ for(int kk = 0; kk < Dim2; ++kk)
+ for(int ll = 0; ll < Dim3; ++ll)
+ {
+ iter(ii, jj, kk, ll) = rhs(ii, jj, kk, ll);
+ }
+ return *this;
+ }
+};
+
+int main()
+{
+ Tensor3<float, 100, 100, 1000> t1;
+ Tensor3<float, 1000, 100, 100> t2;
+
+ Index<'l', 100> l;
+ Index<'m', 100> m;
+ Index<'k', 1000> k;
+ Index<'n', 100> n;
+ Index<'o', 100> o;
+
+ Tensor4<float, 100, 100, 100, 100> res;
+ res(l, m, n, o) = t1(l, m, k) * t2(k, n, o);
+ return 0;
+}
+
diff -urpN a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -114,7 +114,7 @@ along with GCC; see the file COPYING3. If not see
interface between the GIMPLE and RTL worlds. */
/* The infinite cost. */
-#define INFTY 10000000
+#define INFTY 1000000000
/* Returns the expected number of loop iterations for LOOP.
The average trip count is computed from profile data if it
@@ -180,7 +180,7 @@ struct comp_cost
comp_cost (): cost (0), complexity (0), scratch (0)
{}
- comp_cost (int cost, unsigned complexity, int scratch = 0)
+ comp_cost (int64_t cost, unsigned complexity, int64_t scratch = 0)
: cost (cost), complexity (complexity), scratch (scratch)
{}
@@ -220,16 +220,16 @@ struct comp_cost
/* Returns true if COST1 is smaller or equal than COST2. */
friend bool operator<= (comp_cost cost1, comp_cost cost2);
- int cost; /* The runtime cost. */
+ int64_t cost; /* The runtime cost. */
unsigned complexity; /* The estimate of the complexity of the code for
the computation (in no concrete units --
complexity field should be larger for more
complex expressions and addressing modes). */
- int scratch; /* Scratch used during cost computation. */
+ int64_t scratch; /* Scratch used during cost computation. */
};
static const comp_cost no_cost;
-static const comp_cost infinite_cost (INFTY, INFTY, INFTY);
+static const comp_cost infinite_cost (INFTY, 0, INFTY);
bool
comp_cost::infinite_cost_p ()
@@ -243,6 +243,7 @@ operator+ (comp_cost cost1, comp_cost cost2)
if (cost1.infinite_cost_p () || cost2.infinite_cost_p ())
return infinite_cost;
+ gcc_assert (cost1.cost + cost2.cost < infinite_cost.cost);
cost1.cost += cost2.cost;
cost1.complexity += cost2.complexity;
@@ -256,6 +257,7 @@ operator- (comp_cost cost1, comp_cost cost2)
return infinite_cost;
gcc_assert (!cost2.infinite_cost_p ());
+ gcc_assert (cost1.cost - cost2.cost < infinite_cost.cost);
cost1.cost -= cost2.cost;
cost1.complexity -= cost2.complexity;
@@ -276,6 +278,7 @@ comp_cost::operator+= (HOST_WIDE_INT c)
if (infinite_cost_p ())
return *this;
+ gcc_assert (this->cost + c < infinite_cost.cost);
this->cost += c;
return *this;
@@ -287,6 +290,7 @@ comp_cost::operator-= (HOST_WIDE_INT c)
if (infinite_cost_p ())
return *this;
+ gcc_assert (this->cost - c < infinite_cost.cost);
this->cost -= c;
return *this;
@@ -295,6 +299,7 @@ comp_cost::operator-= (HOST_WIDE_INT c)
comp_cost
comp_cost::operator/= (HOST_WIDE_INT c)
{
+ gcc_assert (c != 0);
if (infinite_cost_p ())
return *this;
@@ -309,6 +314,7 @@ comp_cost::operator*= (HOST_WIDE_INT c)
if (infinite_cost_p ())
return *this;
+ gcc_assert (this->cost * c < infinite_cost.cost);
this->cost *= c;
return *this;
@@ -638,7 +644,7 @@ struct iv_ca
comp_cost cand_use_cost;
/* Total cost of candidates. */
- unsigned cand_cost;
+ int64_t cand_cost;
/* Number of times each invariant variable is used. */
unsigned *n_inv_var_uses;
@@ -4025,16 +4031,16 @@ get_computation_at (struct loop *loop, gimple *at,
if we're optimizing for speed, amortize it over the per-iteration cost.
If ROUND_UP_P is true, the result is round up rather than to zero when
optimizing for speed. */
-static unsigned
-adjust_setup_cost (struct ivopts_data *data, unsigned cost,
+static int64_t
+adjust_setup_cost (struct ivopts_data *data, int64_t cost,
bool round_up_p = false)
{
if (cost == INFTY)
return cost;
else if (optimize_loop_for_speed_p (data->current_loop))
{
- HOST_WIDE_INT niters = avg_loop_niter (data->current_loop);
- return ((HOST_WIDE_INT) cost + (round_up_p ? niters - 1 : 0)) / niters;
+ int64_t niters = (int64_t) avg_loop_niter (data->current_loop);
+ return (cost + (round_up_p ? niters - 1 : 0)) / niters;
}
else
return cost;
@@ -4305,7 +4311,7 @@ enum ainc_type
struct ainc_cost_data
{
- unsigned costs[AINC_NONE];
+ int64_t costs[AINC_NONE];
};
static comp_cost
@@ -4566,12 +4572,12 @@ get_scaled_computation_cost_at (ivopts_data *data, gimple *at, comp_cost cost)
if (scale_factor == 1)
return cost;
- int scaled_cost
+ int64_t scaled_cost
= cost.scratch + (cost.cost - cost.scratch) * scale_factor;
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Scaling cost based on bb prob "
- "by %2.2f: %d (scratch: %d) -> %d\n",
+ fprintf (dump_file, "Scaling cost based on bb prob by %2.2f: "
+ "%" PRId64 " (scratch: %" PRId64 ") -> %" PRId64 "\n",
1.0f * scale_factor, cost.cost, cost.scratch, scaled_cost);
cost.cost = scaled_cost;
@@ -5539,7 +5545,7 @@ determine_group_iv_costs (struct ivopts_data *data)
|| group->cost_map[j].cost.infinite_cost_p ())
continue;
- fprintf (dump_file, " %d\t%d\t%d\t",
+ fprintf (dump_file, " %d\t%" PRId64 "\t%d\t",
group->cost_map[j].cand->id,
group->cost_map[j].cost.cost,
group->cost_map[j].cost.complexity);
@@ -5569,7 +5575,7 @@ static void
determine_iv_cost (struct ivopts_data *data, struct iv_cand *cand)
{
comp_cost cost_base;
- unsigned cost, cost_step;
+ int64_t cost, cost_step;
tree base;
gcc_assert (cand->iv != NULL);
@@ -6139,11 +6145,11 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs)
unsigned i;
comp_cost cost = iv_ca_cost (ivs);
- fprintf (file, " cost: %d (complexity %d)\n", cost.cost,
+ fprintf (file, " cost: %" PRId64 " (complexity %d)\n", cost.cost,
cost.complexity);
- fprintf (file, " cand_cost: %d\n cand_group_cost: %d (complexity %d)\n",
- ivs->cand_cost, ivs->cand_use_cost.cost,
- ivs->cand_use_cost.complexity);
+ fprintf (file, " cand_cost: %" PRId64 "\n cand_group_cost: "
+ "%" PRId64 " (complexity %d)\n", ivs->cand_cost,
+ ivs->cand_use_cost.cost, ivs->cand_use_cost.complexity);
bitmap_print (file, ivs->cands, " candidates: ","\n");
for (i = 0; i < ivs->upto; i++)
@@ -6151,9 +6157,9 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs)
struct iv_group *group = data->vgroups[i];
struct cost_pair *cp = iv_ca_cand_for_group (ivs, group);
if (cp)
- fprintf (file, " group:%d --> iv_cand:%d, cost=(%d,%d)\n",
- group->id, cp->cand->id, cp->cost.cost,
- cp->cost.complexity);
+ fprintf (file, " group:%d --> iv_cand:%d, cost=("
+ "%" PRId64 ",%d)\n", group->id, cp->cand->id,
+ cp->cost.cost, cp->cost.complexity);
else
fprintf (file, " group:%d --> ??\n", group->id);
}
@@ -6751,9 +6757,9 @@ find_optimal_iv_set (struct ivopts_data *data)
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, "Original cost %d (complexity %d)\n\n",
+ fprintf (dump_file, "Original cost %" PRId64 " (complexity %d)\n\n",
origcost.cost, origcost.complexity);
- fprintf (dump_file, "Final cost %d (complexity %d)\n\n",
+ fprintf (dump_file, "Final cost %" PRId64 " (complexity %d)\n\n",
cost.cost, cost.complexity);
}

View File

@ -1,166 +0,0 @@
This backport contains 1 patch from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
0001-c-94392-only-enable-ffinite-loops-for-C.patch
75efe9cb1f8938a713ce540dc3b27bc2afcd3fae
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 6b6c754ad86..58ba0948e79 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -989,6 +989,10 @@ c_common_post_options (const char **pfilename)
if (!global_options_set.x_flag_new_ttp)
flag_new_ttp = (cxx_dialect >= cxx17);
+ /* C++11 guarantees forward progress. */
+ if (!global_options_set.x_flag_finite_loops)
+ flag_finite_loops = (optimize >= 2 && cxx_dialect >= cxx11);
+
if (cxx_dialect >= cxx11)
{
/* If we're allowing C++0x constructs, don't warn about C++98
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 1c49a8b8c2d..18b404e292f 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -226,6 +226,10 @@ public:
/* True if the loop is part of an oacc kernels region. */
unsigned in_oacc_kernels_region : 1;
+ /* True if the loop is known to be finite. This is a localized
+ flag_finite_loops or similar pragmas state. */
+ unsigned finite_p : 1;
+
/* The number of times to unroll the loop. 0 means no information given,
just do what we always do. A value of 1 means do not unroll the loop.
A value of USHRT_MAX means unroll with no specific unrolling factor.
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index c9375565f62..50c7267ec49 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -1023,6 +1023,7 @@ copy_loop_info (class loop *loop, class loop *target)
target->dont_vectorize = loop->dont_vectorize;
target->force_vectorize = loop->force_vectorize;
target->in_oacc_kernels_region = loop->in_oacc_kernels_region;
+ target->finite_p = loop->finite_p;
target->unroll = loop->unroll;
target->owned_clique = loop->owned_clique;
}
diff --git a/gcc/common.opt b/gcc/common.opt
index 4368910cb54..bb2ea4c905d 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1490,7 +1490,7 @@ Common Report Var(flag_finite_math_only) Optimization SetByCombined
Assume no NaNs or infinities are generated.
ffinite-loops
-Common Report Var(flag_finite_loops) Optimization
+Common Report Var(flag_finite_loops) Optimization Init(0)
Assume that loops with an exit will terminate and not loop indefinitely.
ffixed-
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e9e1683e9a8..e3e652ff6c1 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -10432,7 +10432,8 @@ Assume that a loop with an exit will eventually take the exit and not loop
indefinitely. This allows the compiler to remove loops that otherwise have
no side-effects, not considering eventual endless looping as such.
-This option is enabled by default at @option{-O2}.
+This option is enabled by default at @option{-O2} for C++ with -std=c++11
+or higher.
@item -ftree-dominator-opts
@opindex ftree-dominator-opts
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 9566e5ee102..244f5b8aa5c 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -821,6 +821,7 @@ input_cfg (class lto_input_block *ib, class data_in *data_in,
loop->owned_clique = streamer_read_hwi (ib);
loop->dont_vectorize = streamer_read_hwi (ib);
loop->force_vectorize = streamer_read_hwi (ib);
+ loop->finite_p = streamer_read_hwi (ib);
loop->simduid = stream_read_tree (ib, data_in);
place_new_loop (fn, loop);
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index a219c1d0dd1..52ef94718db 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -1950,6 +1950,7 @@ output_cfg (struct output_block *ob, struct function *fn)
streamer_write_hwi (ob, loop->owned_clique);
streamer_write_hwi (ob, loop->dont_vectorize);
streamer_write_hwi (ob, loop->force_vectorize);
+ streamer_write_hwi (ob, loop->finite_p);
stream_write_tree (ob, loop->simduid, true);
}
diff --git a/gcc/opts.c b/gcc/opts.c
index 5dc7d65dedd..d4df8627bf7 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -478,7 +478,6 @@ static const struct default_options default_options_table[] =
{ OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
- { OPT_LEVELS_2_PLUS, OPT_ffinite_loops, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },
diff --git a/gcc/testsuite/gcc.dg/torture/pr94392.c b/gcc/testsuite/gcc.dg/torture/pr94392.c
new file mode 100644
index 00000000000..373f18ce983
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr94392.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-skip-if "finite loops" { *-*-* } { "-ffinite-loops" } } */
+/* { dg-skip-if "LTO optimizes the test" { *-*-* } { "-flto" } } */
+/* { dg-additional-options "-fdump-tree-optimized" } */
+
+int a, b;
+
+int
+main()
+{
+ while (1)
+ {
+ /* Try really hard. */
+ if (a != b)
+ return 1;
+ }
+ return 0;
+}
+
+/* ISO C does not guarantee forward progress like C++ does so we
+ cannot assume the loop is finite and optimize it to return 1. */
+/* { dg-final { scan-tree-dump "if" "optimized" } } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index f7b817d94e6..e99fb9ff5d1 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -324,6 +324,9 @@ replace_loop_annotate (void)
/* Then look into the latch, if any. */
if (loop->latch)
replace_loop_annotate_in_block (loop->latch, loop);
+
+ /* Push the global flag_finite_loops state down to individual loops. */
+ loop->finite_p = flag_finite_loops;
}
/* Remove IFN_ANNOTATE. Safeguard for the case loop->latch == NULL. */
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 6e6df0bfdb8..7d61ef080eb 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -2834,7 +2834,7 @@ finite_loop_p (class loop *loop)
return true;
}
- if (flag_finite_loops)
+ if (loop->finite_p)
{
unsigned i;
vec<edge> exits = get_loop_exit_edges (loop);

Some files were not shown because too many files have changed in this diff Show More