!21 Add several enhancement patches

Merge pull request !21 from jdkboy/master
This commit is contained in:
openeuler-ci-bot 2020-08-31 09:11:03 +08:00 committed by Gitee
commit 4c95d1996f
58 changed files with 44250 additions and 37 deletions

View File

@ -0,0 +1,86 @@
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

@ -0,0 +1,298 @@
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,3 +1,9 @@
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 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 --- 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 +++ b/gcc/testsuite/gcc.dg/pr94269.c 2020-04-17 17:04:50.608000000 +0800
@ -56,8 +62,8 @@ diff -Nurp a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
&type2, &mult_rhs2)) &type2, &mult_rhs2))
return false; 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 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 --- 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 +++ 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 @@ -17,7 +17,6 @@ f (TYPE *x, TYPE *y, unsigned short n, l
/* { dg-final { scan-assembler {\tstr\tw[0-9]+} } } */ /* { dg-final { scan-assembler {\tstr\tw[0-9]+} } } */
/* Should multiply by (VF-1)*4 rather than (257-1)*4. */ /* Should multiply by (VF-1)*4 rather than (257-1)*4. */

View File

@ -1,17 +1,19 @@
diff -uprN a/gcc/BASE-VER b/gcc/BASE-VER diff -Nurp a/gcc/BASE-VER b/gcc/BASE-VER
--- a/gcc/BASE-VER 2020-03-31 09:51:52.000000000 +0800 --- a/gcc/BASE-VER 2020-08-19 10:47:14.100000000 +0800
+++ b/gcc/BASE-VER 2020-05-14 16:45:36.416688565 +0800 +++ b/gcc/BASE-VER 2020-08-19 10:32:30.380000000 +0800
@@ -1 +1 @@ @@ -1 +1 @@
-9.3.0 -9.3.0
+9.3.1 +9.3.1
diff -uprN a/gcc/ChangeLog b/gcc/ChangeLog diff -Nurp a/gcc/Makefile.in b/gcc/Makefile.in
--- a/gcc/ChangeLog 2020-03-31 09:51:30.000000000 +0800 --- a/gcc/Makefile.in 2020-08-19 10:32:45.528000000 +0800
+++ b/gcc/ChangeLog 2020-05-14 16:45:36.420688565 +0800 +++ b/gcc/Makefile.in 2020-08-19 10:34:24.968000000 +0800
@@ -1,3 +1,7 @@ @@ -885,8 +885,7 @@ PATCHLEVEL_c := \
+2020-03-12 openEuler # significant - do not remove it.
+ BASEVER_s := "\"$(BASEVER_c)\""
+ * BASE-VER: Set to 9.3.1. DEVPHASE_s := "\"$(if $(DEVPHASE_c), ($(DEVPHASE_c)))\""
+ -DATESTAMP_s := \
2020-03-12 Release Manager - "\"$(if $(DEVPHASE_c)$(filter-out 0,$(PATCHLEVEL_c)), $(DATESTAMP_c))\""
+DATESTAMP_s := "\"\""
PKGVERSION_s:= "\"@PKGVERSION@\""
BUGURL_s := "\"@REPORT_BUGS_TO@\""
* GCC 9.3.0 released.

1814
complete-struct-reorg.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
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,3 +1,9 @@
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 diff -uprN a/gcc/testsuite/gcc.dg/pr91195.c b/gcc/testsuite/gcc.dg/pr91195.c
new file mode 100644 new file mode 100644
--- /dev/null --- /dev/null

34
enable-simd-math.patch Normal file
View File

@ -0,0 +1,34 @@
diff -Nurp a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
--- a/gcc/config/aarch64/aarch64.c 2020-07-06 17:20:30.368000000 +0800
+++ b/gcc/config/aarch64/aarch64.c 2020-07-06 20:02:39.480000000 +0800
@@ -18860,8 +18860,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 2020-07-06 17:20:30.364000000 +0800
+++ b/gcc/config/aarch64/aarch64.opt 2020-07-06 20:02:39.480000000 +0800
@@ -186,6 +186,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

View File

@ -0,0 +1,123 @@
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,3 +1,9 @@
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 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 --- 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 +++ b/gcc/testsuite/gcc.dg/pr94574.c 2020-04-15 21:08:48.972000000 +0000

View File

@ -0,0 +1,76 @@
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

@ -0,0 +1,70 @@
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

@ -0,0 +1,31 @@
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

@ -0,0 +1,54 @@
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

@ -0,0 +1,65 @@
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

@ -0,0 +1,248 @@
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

369
fix-ICE-in-reload.patch Normal file
View File

@ -0,0 +1,369 @@
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

@ -0,0 +1,356 @@
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);

93
fix-ICE-in-vec.patch Normal file
View File

@ -0,0 +1,93 @@
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");

View File

@ -0,0 +1,81 @@
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

@ -0,0 +1,33 @@
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

@ -0,0 +1,87 @@
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

@ -0,0 +1,54 @@
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

@ -0,0 +1,381 @@
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

@ -0,0 +1,41 @@
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

@ -0,0 +1,96 @@
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,3 +1,9 @@
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 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 --- 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 +++ b/gcc/testsuite/gcc.target/aarch64/pr94398.c 2020-04-17 17:15:58.176000000 +0800

View File

@ -0,0 +1,18 @@
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

@ -0,0 +1,41 @@
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

@ -0,0 +1,109 @@
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

@ -0,0 +1,145 @@
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

@ -0,0 +1,47 @@
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,3 +1,9 @@
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 diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index b0cbb6e2d55..58d38f74bde 100644 index b0cbb6e2d55..58d38f74bde 100644
--- a/gcc/config/aarch64/aarch64.c --- a/gcc/config/aarch64/aarch64.c

View File

@ -1,3 +1,6 @@
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 diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 56a4a47db73..71d44de1d0a 100644 index 56a4a47db73..71d44de1d0a 100644
--- a/gcc/config/aarch64/aarch64.c --- a/gcc/config/aarch64/aarch64.c

27
fix-do-not-build-op.patch Normal file
View File

@ -0,0 +1,27 @@
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

@ -0,0 +1,55 @@
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,3 +1,9 @@
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 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 --- 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 +++ b/gcc/lra-assigns.c 2020-04-17 16:29:37.125688580 +0800

View File

@ -0,0 +1,71 @@
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

170
gcc.spec
View File

@ -1,4 +1,4 @@
%global DATE 20200629 %global DATE 20200828
%global gcc_version 9.3.1 %global gcc_version 9.3.1
%global gcc_major 9.3.1 %global gcc_major 9.3.1
@ -112,27 +112,69 @@ Provides: bundled(libiberty)
Provides: gcc(major) = %{gcc_major} Provides: gcc(major) = %{gcc_major}
Patch0: enable-aarch64-libquadmath.patch Patch0: enable-aarch64-libquadmath.patch
Patch1: generate-csel.patch Patch1: medium-code-mode.patch
Patch2: delete-incorrect-smw.patch Patch2: generate-csel.patch
Patch3: remove-array-index-inliner-hint.patch Patch3: delete-incorrect-smw.patch
Patch4: ivopts-1.patch Patch4: remove-array-index-inliner-hint.patch
Patch5: ivopts-2.patch Patch5: ivopts-1.patch
Patch6: dont-generate-IF_THEN_ELSE.patch Patch6: ivopts-2.patch
Patch7: fix-cost-of-plus.patch Patch7: dont-generate-IF_THEN_ELSE.patch
Patch8: div-opti.patch Patch8: fix-cost-of-plus.patch
Patch9: fix-SYMBOL_TINY_GOT-handling-for-ILP32.patch Patch9: div-opti.patch
Patch10: fix-ICE-during-pass-ccp.patch Patch10: fix-SYMBOL_TINY_GOT-handling-for-ILP32.patch
Patch11: loop-split.patch Patch11: fix-ICE-during-pass-ccp.patch
Patch12: loop-finite.patch Patch12: loop-split.patch
Patch13: loop-finite-bugfix.patch Patch13: loop-finite.patch
Patch14: fix-regno-out-of-range.patch Patch14: loop-finite-bugfix.patch
Patch15: fix-ICE-in-vectorizable-load.patch Patch15: fix-regno-out-of-range.patch
Patch16: address-calculation-optimization-within-loop.patch Patch16: fix-ICE-in-vectorizable-load.patch
Patch17: skip-debug-insns-when-computing-inline-costs.patch Patch17: address-calculation-optimization-within-loop.patch
Patch18: change-gcc-BASE-VER.patch Patch18: skip-debug-insns-when-computing-inline-costs.patch
Patch19: PR92303-Try-to-simplify-memory-subreg.patch Patch19: ipa-const-prop.patch
Patch20: Fix-PR94185.patch Patch20: ipa-const-prop-self-recursion-bugfix.patch
Patch21: testsuite-Fix-pr94185.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
%global gcc_target_platform %{_arch}-linux-gnu %global gcc_target_platform %{_arch}-linux-gnu
@ -596,6 +638,47 @@ not stable, so plugins must be rebuilt any time GCC is updated.
%patch19 -p1 %patch19 -p1
%patch20 -p1 %patch20 -p1
%patch21 -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
%build %build
@ -2524,6 +2607,49 @@ end
%doc rpm.doc/changelogs/libcc1/ChangeLog* %doc rpm.doc/changelogs/libcc1/ChangeLog*
%changelog %changelog
* 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 * Mon Jun 29 2020 eastb233 <xiezhiheng@huawei.com> - 9.3.1-20200629.3
- gcc.spec: Change release version - gcc.spec: Change release version

View File

@ -0,0 +1,218 @@
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,3 +1,9 @@
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 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 --- a/gcc/testsuite/gcc.dg/graphite/scop-21.c
+++ b/gcc/testsuite/gcc.dg/graphite/scop-21.c +++ b/gcc/testsuite/gcc.dg/graphite/scop-21.c

View File

@ -0,0 +1,191 @@
This patch is backport from gcc-trunk. It is a combined patch from
Find matched aggregate lattice for self-recursive CP (PR ipa/93084)
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=42d73fa9d575e3c8c21e88bd7f65922e17b052f1
and
Do not propagate self-dependent value (PR ipa/93763)
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=47772af10c00f7e1e95cd52557fc893dc602a420
adapted the using of parameter to gcc9 style.
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; }

11040
ipa-const-prop.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,613 @@
diff -Nurp a/gcc/fold-const.c b/gcc/fold-const.c
--- a/gcc/fold-const.c 2020-06-16 22:27:46.116000000 -0400
+++ b/gcc/fold-const.c 2020-06-16 22:27:58.412000000 -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-06-16 22:27:46.116000000 -0400
+++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.c 2020-06-16 22:33:18.968000000 -0400
@@ -112,6 +112,23 @@ 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_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 +480,10 @@ srtype::analyze (void)
if (fields.length () == 2)
fields[1]->clusternum = 1;
- /* REMOVEME: FIXME: this is here for testing more testcases. */
+ /* FIXME: Currently Return. */
if (fields.length () >= 3)
{
- fields[1]->clusternum = 1;
+ return;
}
}
@@ -875,6 +892,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 +1114,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 +2841,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 +3735,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-06-16 22:27:46.120000000 -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-06-16 22:27:46.120000000 -0400
+++ b/gcc/testsuite/gcc.c-torture/compile/nested-3.c 2020-06-16 22:27:58.416000000 -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-06-16 22:27:46.120000000 -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-06-16 22:27:46.120000000 -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-06-16 22:27:58.436000000 -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-06-16 22:27:58.440000000 -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-06-16 22:27:58.440000000 -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-06-16 22:27:58.440000000 -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-06-16 22:27:46.120000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/struct-reorg.exp 2020-06-16 22:27:58.440000000 -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-06-16 22:27:46.120000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/wo_prof_escape_str_init.c 2020-06-16 22:27:58.440000000 -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-06-16 22:27:46.120000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/wo_prof_mult_field_peeling.c 2020-06-16 22:27:58.440000000 -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-06-16 22:27:46.120000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_global_array.c 2020-06-16 22:27:58.440000000 -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-06-16 22:27:46.120000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_global_var.c 2020-06-16 22:27:58.440000000 -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-06-16 22:27:46.124000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_local_array.c 2020-06-16 22:27:58.472000000 -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-06-16 22:27:46.124000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_local_var.c 2020-06-16 22:27:58.472000000 -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-06-16 22:27:46.124000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_single_str_global.c 2020-06-16 22:27:58.472000000 -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-06-16 22:27:46.124000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_prof_two_strs.c 2020-06-16 22:27:58.472000000 -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-06-16 22:27:46.124000000 -0400
+++ b/gcc/testsuite/gcc.dg/struct/w_ratio_cold_str.c 2020-06-16 22:27:58.472000000 -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-06-16 22:27:46.124000000 -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;
-}

5846
ipa-struct-reorg.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,6 @@
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 diff -urpN a/gcc/testsuite/gfortran.dg/graphite/pr90240.f b/gcc/testsuite/gfortran.dg/graphite/pr90240.f
new file mode 100644 new file mode 100644
--- /dev/null --- /dev/null

View File

@ -1,3 +1,6 @@
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 diff -urpN a/gcc/testsuite/g++.dg/tree-ssa/pr90078.C b/gcc/testsuite/g++.dg/tree-ssa/pr90078.C
new file mode 100644 new file mode 100644
--- /dev/null --- /dev/null

View File

@ -1,3 +1,9 @@
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 diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 6b6c754ad86..58ba0948e79 100644 index 6b6c754ad86..58ba0948e79 100644
--- a/gcc/c-family/c-opts.c --- a/gcc/c-family/c-opts.c

View File

@ -1,3 +1,9 @@
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-89713-Assume-loop-with-an-exit-.patch
c29c92c789d93848cc1c929838771bfc68cb272c
diff --git a/gcc/common.opt b/gcc/common.opt diff --git a/gcc/common.opt b/gcc/common.opt
index e1404165feb..a1544d06824 100644 index e1404165feb..a1544d06824 100644
--- a/gcc/common.opt --- a/gcc/common.opt

View File

@ -1,3 +1,9 @@
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-Loop-split-on-semi-invariant-conditional-statement.patch
095f78c62157124ad479a3f98b6995ced090b807
diff --git a/gcc/params.def b/gcc/params.def diff --git a/gcc/params.def b/gcc/params.def
index 942447d77e6..df7d1f7c5e7 100644 index 942447d77e6..df7d1f7c5e7 100644
--- a/gcc/params.def --- a/gcc/params.def

426
medium-code-mode.patch Normal file
View File

@ -0,0 +1,426 @@
diff -Nurp a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
--- a/gcc/config/aarch64/aarch64.c 2020-07-16 14:54:30.588000000 +0800
+++ b/gcc/config/aarch64/aarch64.c 2020-07-16 15:06:33.000000000 +0800
@@ -2030,6 +2030,32 @@ aarch64_load_symref_appropriately (rtx d
emit_insn (gen_add_losym (dest, tmp_reg, imm));
return;
}
+ case SYMBOL_MEDIUM_ABSOLUTE:
+ {
+ rtx tmp_reg = dest;
+ machine_mode mode = GET_MODE (dest);
+
+ gcc_assert (mode == Pmode || mode == ptr_mode);
+ if (can_create_pseudo_p ())
+ tmp_reg = gen_reg_rtx (mode);
+
+ if (mode == DImode)
+ {
+ emit_insn (
+ gen_load_symbol_medium_di (dest, tmp_reg, imm));
+ }
+ else
+ {
+ emit_insn (
+ gen_load_symbol_medium_si (dest, tmp_reg, imm));
+ }
+ if (REG_P (dest))
+ {
+ set_unique_reg_note (
+ get_last_insn (), REG_EQUIV, copy_rtx (imm));
+ }
+ return;
+ }
case SYMBOL_TINY_ABSOLUTE:
emit_insn (gen_rtx_SET (dest, imm));
@@ -2152,6 +2178,64 @@ aarch64_load_symref_appropriately (rtx d
return;
}
+ case SYMBOL_MEDIUM_GOT_4G:
+ {
+ rtx tmp_reg = dest;
+ machine_mode mode = GET_MODE (dest);
+ if (can_create_pseudo_p ())
+ {
+ tmp_reg = gen_reg_rtx (mode);
+ }
+ rtx insn;
+ rtx mem;
+ rtx s = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+
+ if (mode == DImode)
+ {
+ emit_insn (
+ gen_load_symbol_medium_di (tmp_reg, dest, s));
+ }
+ else
+ {
+ emit_insn (
+ gen_load_symbol_medium_si (tmp_reg, dest, s));
+ }
+ if (REG_P (dest))
+ {
+ set_unique_reg_note (
+ get_last_insn (), REG_EQUIV, copy_rtx (s));
+ }
+
+ if (mode == ptr_mode)
+ {
+ if (mode == DImode)
+ {
+ emit_insn (gen_get_gotoff_di (dest, imm));
+ insn = gen_ldr_got_medium_di (
+ dest, tmp_reg, dest);
+ }
+ else
+ {
+ emit_insn (gen_get_gotoff_si (dest, imm));
+ insn = gen_ldr_got_medium_si (
+ dest, tmp_reg, dest);
+ }
+ mem = XVECEXP (SET_SRC (insn), 0, 0);
+ }
+ else
+ {
+ gcc_assert (mode == Pmode);
+ emit_insn (gen_get_gotoff_di (dest, imm));
+ insn = gen_ldr_got_medium_sidi (dest, tmp_reg, dest);
+ mem = XVECEXP (XEXP (SET_SRC (insn), 0), 0, 0);
+ }
+
+ gcc_assert (GET_CODE (mem) == MEM);
+ MEM_READONLY_P (mem) = 1;
+ MEM_NOTRAP_P (mem) = 1;
+ emit_insn (insn);
+ return;
+ }
case SYMBOL_SMALL_TLSGD:
{
rtx_insn *insns;
@@ -3372,11 +3456,12 @@ aarch64_expand_mov_immediate (rtx dest,
return;
- case SYMBOL_SMALL_TLSGD:
- case SYMBOL_SMALL_TLSDESC:
+ case SYMBOL_SMALL_TLSGD:
+ case SYMBOL_SMALL_TLSDESC:
case SYMBOL_SMALL_TLSIE:
case SYMBOL_SMALL_GOT_28K:
case SYMBOL_SMALL_GOT_4G:
+ case SYMBOL_MEDIUM_GOT_4G:
case SYMBOL_TINY_GOT:
case SYMBOL_TINY_TLSIE:
if (const_offset != 0)
@@ -3395,6 +3480,7 @@ aarch64_expand_mov_immediate (rtx dest,
case SYMBOL_TLSLE24:
case SYMBOL_TLSLE32:
case SYMBOL_TLSLE48:
+ case SYMBOL_MEDIUM_ABSOLUTE:
aarch64_load_symref_appropriately (dest, imm, sty);
return;
@@ -10334,6 +10420,13 @@ cost_plus:
if (speed)
*cost += extra_cost->alu.arith;
}
+ else if (aarch64_cmodel == AARCH64_CMODEL_MEDIUM
+ || aarch64_cmodel == AARCH64_CMODEL_MEDIUM_PIC)
+ {
+ /* 4 movs adr sub add 2movs ldr. */
+ if (speed)
+ *cost += 7*extra_cost->alu.arith;
+ }
if (flag_pic)
{
@@ -10341,6 +10434,8 @@ cost_plus:
*cost += COSTS_N_INSNS (1);
if (speed)
*cost += extra_cost->ldst.load;
+ if (aarch64_cmodel == AARCH64_CMODEL_MEDIUM_PIC)
+ *cost += 2*extra_cost->alu.arith;
}
return true;
@@ -11395,6 +11490,7 @@ initialize_aarch64_tls_size (struct gcc_
if (aarch64_tls_size > 32)
aarch64_tls_size = 32;
break;
+ case AARCH64_CMODEL_MEDIUM:
case AARCH64_CMODEL_LARGE:
/* The maximum TLS size allowed under large is 16E.
FIXME: 16E should be 64bit, we only support 48bit offset now. */
@@ -12187,6 +12283,9 @@ initialize_aarch64_code_model (struct gc
aarch64_cmodel = AARCH64_CMODEL_SMALL_PIC;
#endif
break;
+ case AARCH64_CMODEL_MEDIUM:
+ aarch64_cmodel = AARCH64_CMODEL_MEDIUM_PIC;
+ break;
case AARCH64_CMODEL_LARGE:
sorry ("code model %qs with %<-f%s%>", "large",
opts->x_flag_pic > 1 ? "PIC" : "pic");
@@ -12205,6 +12304,7 @@ static void
aarch64_option_save (struct cl_target_option *ptr, struct gcc_options *opts)
{
ptr->x_aarch64_override_tune_string = opts->x_aarch64_override_tune_string;
+ ptr->x_aarch64_data_threshold = opts->x_aarch64_data_threshold;
ptr->x_aarch64_branch_protection_string
= opts->x_aarch64_branch_protection_string;
}
@@ -12220,6 +12320,7 @@ aarch64_option_restore (struct gcc_optio
opts->x_explicit_arch = ptr->x_explicit_arch;
selected_arch = aarch64_get_arch (ptr->x_explicit_arch);
opts->x_aarch64_override_tune_string = ptr->x_aarch64_override_tune_string;
+ opts->x_aarch64_data_threshold = ptr->x_aarch64_data_threshold;
opts->x_aarch64_branch_protection_string
= ptr->x_aarch64_branch_protection_string;
if (opts->x_aarch64_branch_protection_string)
@@ -13067,6 +13168,8 @@ aarch64_classify_symbol (rtx x, HOST_WID
case AARCH64_CMODEL_SMALL_SPIC:
case AARCH64_CMODEL_SMALL_PIC:
+ case AARCH64_CMODEL_MEDIUM_PIC:
+ case AARCH64_CMODEL_MEDIUM:
case AARCH64_CMODEL_SMALL:
return SYMBOL_SMALL_ABSOLUTE;
@@ -13100,6 +13203,7 @@ aarch64_classify_symbol (rtx x, HOST_WID
return SYMBOL_TINY_ABSOLUTE;
case AARCH64_CMODEL_SMALL:
+ AARCH64_SMALL_ROUTINE:
/* Same reasoning as the tiny code model, but the offset cap here is
4G. */
if ((SYMBOL_REF_WEAK (x)
@@ -13121,7 +13225,48 @@ aarch64_classify_symbol (rtx x, HOST_WID
? SYMBOL_SMALL_GOT_28K : SYMBOL_SMALL_GOT_4G);
return SYMBOL_SMALL_ABSOLUTE;
+ case AARCH64_CMODEL_MEDIUM:
+ {
+ tree decl_local = SYMBOL_REF_DECL (x);
+ if (decl_local != NULL
+ && tree_fits_uhwi_p (DECL_SIZE_UNIT (decl_local)))
+ {
+ HOST_WIDE_INT size = tree_to_uhwi (
+ DECL_SIZE_UNIT (decl_local));
+ /* If the data is smaller than the threshold, goto
+ the small code model. Else goto the large code
+ model. */
+ if (size >= HOST_WIDE_INT (aarch64_data_threshold))
+ goto AARCH64_LARGE_ROUTINE;
+ }
+ goto AARCH64_SMALL_ROUTINE;
+ }
+
+ case AARCH64_CMODEL_MEDIUM_PIC:
+ {
+ tree decl_local = SYMBOL_REF_DECL (x);
+ if (decl_local != NULL
+ && tree_fits_uhwi_p (DECL_SIZE_UNIT (decl_local)))
+ {
+ HOST_WIDE_INT size = tree_to_uhwi (
+ DECL_SIZE_UNIT (decl_local));
+ if (size < HOST_WIDE_INT (aarch64_data_threshold))
+ {
+ if (!aarch64_symbol_binds_local_p (x))
+ {
+ return SYMBOL_SMALL_GOT_4G;
+ }
+ return SYMBOL_SMALL_ABSOLUTE;
+ }
+ }
+ if (!aarch64_symbol_binds_local_p (x))
+ {
+ return SYMBOL_MEDIUM_GOT_4G;
+ }
+ return SYMBOL_MEDIUM_ABSOLUTE;
+ }
case AARCH64_CMODEL_LARGE:
+ AARCH64_LARGE_ROUTINE:
/* This is alright even in PIC code as the constant
pool reference is always PC relative and within
the same translation unit. */
@@ -15364,6 +15509,8 @@ aarch64_asm_preferred_eh_data_format (in
case AARCH64_CMODEL_SMALL:
case AARCH64_CMODEL_SMALL_PIC:
case AARCH64_CMODEL_SMALL_SPIC:
+ case AARCH64_CMODEL_MEDIUM:
+ case AARCH64_CMODEL_MEDIUM_PIC:
/* text+got+data < 4Gb. 4-byte signed relocs are sufficient
for everything. */
type = DW_EH_PE_sdata4;
@@ -18454,7 +18601,8 @@ aarch64_empty_mask_is_expensive (unsigne
bool
aarch64_use_pseudo_pic_reg (void)
{
- return aarch64_cmodel == AARCH64_CMODEL_SMALL_SPIC;
+ return aarch64_cmodel == AARCH64_CMODEL_SMALL_SPIC
+ || aarch64_cmodel == AARCH64_CMODEL_MEDIUM_PIC ;
}
/* Implement TARGET_UNSPEC_MAY_TRAP_P. */
@@ -18464,6 +18612,7 @@ aarch64_unspec_may_trap_p (const_rtx x,
{
switch (XINT (x, 1))
{
+ case UNSPEC_GOTMEDIUMPIC4G:
case UNSPEC_GOTSMALLPIC:
case UNSPEC_GOTSMALLPIC28K:
case UNSPEC_GOTTINYPIC:
diff -Nurp a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
--- a/gcc/config/aarch64/aarch64.h 2020-07-16 14:54:30.592000000 +0800
+++ b/gcc/config/aarch64/aarch64.h 2020-07-16 14:55:05.672000000 +0800
@@ -33,6 +33,10 @@
#define REGISTER_TARGET_PRAGMAS() aarch64_register_pragmas ()
+/* Default threshold 64-bit relocation data
+ with aarch64 medium memory model. */
+#define AARCH64_DEFAULT_LARGE_DATA_THRESHOLD 65536
+
/* Target machine storage layout. */
#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
diff -Nurp a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
--- a/gcc/config/aarch64/aarch64.md 2020-07-16 14:54:30.588000000 +0800
+++ b/gcc/config/aarch64/aarch64.md 2020-07-16 14:55:05.676000000 +0800
@@ -209,6 +209,11 @@
UNSPEC_RSQRTS
UNSPEC_NZCV
UNSPEC_XPACLRI
+ UNSPEC_MOV_MEDIUM_SYMBOL
+ UNSPEC_GET_LAST_PC
+ UNSPEC_GOTMEDIUMPIC4G
+ UNSPEC_GET_GOTOFF
+ UNSPEC_LOAD_SYMBOL_MEDIUM
UNSPEC_LD1_SVE
UNSPEC_ST1_SVE
UNSPEC_LD1RQ
@@ -6548,6 +6553,39 @@
[(set_attr "type" "load_4")]
)
+(define_insn "get_gotoff_<mode>"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (unspec:GPI [(match_operand 1 "aarch64_valid_symref" "S")]
+ UNSPEC_GET_GOTOFF))]
+ ""
+ "movz\\t%x0, :gotoff_g1:%A1\;movk\\t%x0, :gotoff_g0_nc:%A1"
+ [(set_attr "type" "multiple")
+ (set_attr "length" "8")]
+)
+
+(define_insn "ldr_got_medium_<mode>"
+ [(set (match_operand:PTR 0 "register_operand" "=r")
+ (unspec:PTR [(mem:PTR (lo_sum:PTR
+ (match_operand:PTR 1 "register_operand" "r")
+ (match_operand:PTR 2 "register_operand" "r")))]
+ UNSPEC_GOTMEDIUMPIC4G))]
+ ""
+ "ldr\\t%0, [%1, %2]"
+ [(set_attr "type" "load_4")]
+)
+
+(define_insn "ldr_got_medium_sidi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (unspec:SI [(mem:SI (lo_sum:DI
+ (match_operand:DI 1 "register_operand" "r")
+ (match_operand:DI 2 "register_operand" "r")))]
+ UNSPEC_GOTMEDIUMPIC4G)))]
+ "TARGET_ILP32"
+ "ldr\\t%0, [%1, %2]"
+ [(set_attr "type" "load_4")]
+)
+
(define_insn "ldr_got_small_28k_<mode>"
[(set (match_operand:PTR 0 "register_operand" "=r")
(unspec:PTR [(mem:PTR (lo_sum:PTR
@@ -6709,6 +6747,23 @@
(set_attr "length" "12")]
)
+(define_insn "load_symbol_medium_<mode>"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (unspec:GPI [(match_operand 2 "aarch64_valid_symref" "S")]
+ UNSPEC_LOAD_SYMBOL_MEDIUM))
+ (clobber (match_operand:GPI 1 "register_operand" "=r"))]
+ ""
+ "movz\\t%x0, :prel_g3:%A2\;\\
+ movk\\t%x0, :prel_g2_nc:%A2\;\\
+ movk\\t%x0, :prel_g1_nc:%A2\;\\
+ movk\\t%x0, :prel_g0_nc:%A2\;\\
+ adr\\t%x1, .\;\\
+ sub\\t%x1, %x1, 0x4\;\\
+ add\\t%x0, %x0, %x1"
+ [(set_attr "type" "multiple")
+ (set_attr "length" "28")]
+)
+
(define_expand "tlsdesc_small_<mode>"
[(unspec:PTR [(match_operand 0 "aarch64_valid_symref")] UNSPEC_TLSDESC)]
"TARGET_TLS_DESC"
diff -Nurp a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
--- a/gcc/config/aarch64/aarch64.opt 2020-07-16 14:54:30.580000000 +0800
+++ b/gcc/config/aarch64/aarch64.opt 2020-07-16 14:55:05.676000000 +0800
@@ -27,6 +27,10 @@ enum aarch64_processor explicit_tune_cor
TargetVariable
enum aarch64_arch explicit_arch = aarch64_no_arch
+;; -mlarge-data-threshold=
+TargetSave
+int x_aarch64_data_threshold
+
TargetSave
const char *x_aarch64_override_tune_string
@@ -61,8 +65,15 @@ EnumValue
Enum(cmodel) String(small) Value(AARCH64_CMODEL_SMALL)
EnumValue
+Enum(cmodel) String(medium) Value(AARCH64_CMODEL_MEDIUM)
+
+EnumValue
Enum(cmodel) String(large) Value(AARCH64_CMODEL_LARGE)
+mlarge-data-threshold=
+Target RejectNegative Joined UInteger Var(aarch64_data_threshold) Init(AARCH64_DEFAULT_LARGE_DATA_THRESHOLD)
+-mlarge-data-threshold=<number> Data greater than given threshold will be assume that it should be relocated using 64-bit relocation.
+
mbig-endian
Target Report RejectNegative Mask(BIG_END)
Assume target CPU is configured as big endian.
diff -Nurp a/gcc/config/aarch64/aarch64-opts.h b/gcc/config/aarch64/aarch64-opts.h
--- a/gcc/config/aarch64/aarch64-opts.h 2020-07-16 14:54:30.584000000 +0800
+++ b/gcc/config/aarch64/aarch64-opts.h 2020-07-16 14:55:05.676000000 +0800
@@ -66,6 +66,10 @@ enum aarch64_code_model {
/* -fpic for small memory model.
GOT size to 28KiB (4K*8-4K) or 3580 entries. */
AARCH64_CMODEL_SMALL_SPIC,
+ /* Using movk insn sequence to do 64bit PC relative relocation. */
+ AARCH64_CMODEL_MEDIUM,
+ /* Using movk insn sequence to do 64bit PC relative got relocation. */
+ AARCH64_CMODEL_MEDIUM_PIC,
/* No assumptions about addresses of code and data.
The PIC variant is not yet implemented. */
AARCH64_CMODEL_LARGE
diff -Nurp a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
--- a/gcc/config/aarch64/aarch64-protos.h 2020-07-16 14:54:30.584000000 +0800
+++ b/gcc/config/aarch64/aarch64-protos.h 2020-07-16 14:55:05.676000000 +0800
@@ -95,9 +95,11 @@
*/
enum aarch64_symbol_type
{
+ SYMBOL_MEDIUM_ABSOLUTE,
SYMBOL_SMALL_ABSOLUTE,
SYMBOL_SMALL_GOT_28K,
SYMBOL_SMALL_GOT_4G,
+ SYMBOL_MEDIUM_GOT_4G,
SYMBOL_SMALL_TLSGD,
SYMBOL_SMALL_TLSDESC,
SYMBOL_SMALL_TLSIE,

View File

@ -0,0 +1,52 @@
diff -Nurp a/gcc/common.opt b/gcc/common.opt
--- a/gcc/common.opt 2020-06-20 23:53:56.124000000 +0800
+++ b/gcc/common.opt 2020-06-22 23:02:18.808000000 +0800
@@ -2858,6 +2858,10 @@ ftree-slp-vectorize
Common Report Var(flag_tree_slp_vectorize) Optimization EnabledBy(ftree-vectorize)
Enable basic block vectorization (SLP) on trees.
+ftree-vect-analyze-slp-group
+Common Report Var(flag_tree_slp_group) Init(0)
+Disable SLP vectorization for reduction chain on tree.
+
fvect-cost-model=
Common Joined RejectNegative Enum(vect_cost_model) Var(flag_vect_cost_model) Init(VECT_COST_MODEL_DEFAULT) Optimization
-fvect-cost-model=[unlimited|dynamic|cheap] Specifies the cost model for vectorization.
diff -Nurp a/gcc/testsuite/gcc.dg/vect/vect-reduc-12.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-12.c
--- a/gcc/testsuite/gcc.dg/vect/vect-reduc-12.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-12.c 2020-06-22 23:04:08.260000000 +0800
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -funsafe-math-optimizations -fno-tree-reassoc -ftree-vect-analyze-slp-group" } */
+void f(double *a, double *res, double m) {
+ double res1, res0;
+ res1 = 0;
+ res0 = 0;
+ for (int i = 0; i < 1000; i+=8) {
+ res0 += a[i] * m;
+ res1 += a[i+1] * m;
+ res0 += a[i+2] * m;
+ res1 += a[i+3] * m;
+ res0 += a[i+4] * m;
+ res1 += a[i+5] * m;
+ res0 += a[i+6] * m;
+ res1 += a[i+7] * m;
+ }
+ res[0] += res0;
+ res[1] += res1;
+}
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */
diff -Nurp a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
--- a/gcc/tree-vect-slp.c 2020-06-21 01:07:56.516000000 +0800
+++ b/gcc/tree-vect-slp.c 2020-06-22 23:02:54.540000000 +0800
@@ -2327,8 +2327,9 @@ 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, bst_map, first_element,
+ if (flag_tree_slp_group
+ || ! vect_analyze_slp_instance (vinfo, bst_map, first_element,
max_tree_size))
{
/* Dissolve reduction chain group. */
stmt_vec_info vinfo = first_element;

View File

@ -0,0 +1,59 @@
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_analyze_slp-When-reduction-grou.patch
0214d31a48f867b9b00134cea7223d35ed7865aa
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-9.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-9.c
new file mode 100644
index 00000000000..bee642ee999
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-9.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int_mult } */
+
+int
+bar (int *x, int a, int b, int n)
+{
+ x = __builtin_assume_aligned (x, __BIGGEST_ALIGNMENT__);
+ int sum1 = 0;
+ int sum2 = 0;
+ for (int i = 0; i < n; ++i)
+ {
+ /* Reduction chain vectorization fails here because of the
+ different operations but we can still vectorize both
+ reductions as SLP reductions, saving IVs. */
+ sum1 += x[2*i] - a;
+ sum1 += x[2*i+1] * b;
+ sum2 += x[2*i] - b;
+ sum2 += x[2*i+1] * a;
+ }
+ return sum1 + sum2;
+}
+
+/* { dg-final { scan-tree-dump "Loop contains only SLP stmts" "vect" } } */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index e1061ede061..0af51197a84 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2271,14 +2271,18 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size)
{
/* Dissolve reduction chain group. */
stmt_vec_info vinfo = first_element;
+ stmt_vec_info last = NULL;
while (vinfo)
{
stmt_vec_info next = REDUC_GROUP_NEXT_ELEMENT (vinfo);
REDUC_GROUP_FIRST_ELEMENT (vinfo) = NULL;
REDUC_GROUP_NEXT_ELEMENT (vinfo) = NULL;
+ last = vinfo;
vinfo = next;
}
STMT_VINFO_DEF_TYPE (first_element) = vect_internal_def;
+ /* It can be still vectorized as part of an SLP reduction. */
+ loop_vinfo->reductions.safe_push (last);
}
}

View File

@ -1,3 +1,9 @@
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-fnsummary.c-ipa_dump_hints-Do-not-dump-array_ind.patch
a20f263ba1a76af40eb4e6734529739a2a30ed65
diff -uprN a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi diff -uprN a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
--- a/gcc/doc/invoke.texi --- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi

View File

@ -0,0 +1,117 @@
diff -Nurp a/gcc/expr.c b/gcc/expr.c
--- a/gcc/expr.c 2020-08-05 20:33:04.068000000 +0800
+++ b/gcc/expr.c 2020-08-05 20:33:21.420000000 +0800
@@ -3770,6 +3770,78 @@ emit_move_insn (rtx x, rtx y)
gcc_assert (mode != BLKmode
&& (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode));
+ /* If we have a copy that looks like one of the following patterns:
+ (set (subreg:M1 (reg:M2 ...)) (subreg:M1 (reg:M2 ...)))
+ (set (subreg:M1 (reg:M2 ...)) (mem:M1 ADDR))
+ (set (mem:M1 ADDR) (subreg:M1 (reg:M2 ...)))
+ (set (subreg:M1 (reg:M2 ...)) (constant C))
+ where mode M1 is equal in size to M2, try to detect whether the
+ mode change involves an implicit round trip through memory.
+ If so, see if we can avoid that by removing the subregs and
+ doing the move in mode M2 instead. */
+
+ rtx x_inner = NULL_RTX;
+ rtx y_inner = NULL_RTX;
+
+ #define CANDIDATE_SUBREG_P(subreg) \
+ (REG_P (SUBREG_REG (subreg)) \
+ && known_eq (GET_MODE_SIZE (GET_MODE (SUBREG_REG (subreg))), \
+ GET_MODE_SIZE (GET_MODE (subreg))) \
+ && optab_handler (mov_optab, GET_MODE (SUBREG_REG (subreg))) \
+ != CODE_FOR_nothing)
+
+ #define CANDIDATE_MEM_P(innermode, mem) \
+ (!targetm.can_change_mode_class ((innermode), GET_MODE (mem), ALL_REGS) \
+ && !push_operand ((mem), GET_MODE (mem)) \
+ /* Not a candiate if innermode requires too much alignment. */ \
+ && (MEM_ALIGN (mem) >= GET_MODE_ALIGNMENT (innermode) \
+ || targetm.slow_unaligned_access (GET_MODE (mem), \
+ MEM_ALIGN (mem)) \
+ || !targetm.slow_unaligned_access ((innermode), \
+ MEM_ALIGN (mem))))
+
+ if (SUBREG_P (x) && CANDIDATE_SUBREG_P (x))
+ x_inner = SUBREG_REG (x);
+
+ if (SUBREG_P (y) && CANDIDATE_SUBREG_P (y))
+ y_inner = SUBREG_REG (y);
+
+ if (x_inner != NULL_RTX
+ && y_inner != NULL_RTX
+ && GET_MODE (x_inner) == GET_MODE (y_inner)
+ && !targetm.can_change_mode_class (GET_MODE (x_inner), mode, ALL_REGS))
+ {
+ x = x_inner;
+ y = y_inner;
+ mode = GET_MODE (x_inner);
+ }
+ else if (x_inner != NULL_RTX
+ && MEM_P (y)
+ && CANDIDATE_MEM_P (GET_MODE (x_inner), y))
+ {
+ x = x_inner;
+ y = adjust_address (y, GET_MODE (x_inner), 0);
+ mode = GET_MODE (x_inner);
+ }
+ else if (y_inner != NULL_RTX
+ && MEM_P (x)
+ && CANDIDATE_MEM_P (GET_MODE (y_inner), x))
+ {
+ x = adjust_address (x, GET_MODE (y_inner), 0);
+ y = y_inner;
+ mode = GET_MODE (y_inner);
+ }
+ else if (x_inner != NULL_RTX
+ && CONSTANT_P (y)
+ && !targetm.can_change_mode_class (GET_MODE (x_inner),
+ mode, ALL_REGS)
+ && (y_inner = simplify_subreg (GET_MODE (x_inner), y, mode, 0)))
+ {
+ x = x_inner;
+ y = y_inner;
+ mode = GET_MODE (x_inner);
+ }
+
if (CONSTANT_P (y))
{
if (optimize
diff -Nurp a/gcc/testsuite/gcc.target/aarch64/pr95254.c b/gcc/testsuite/gcc.target/aarch64/pr95254.c
--- a/gcc/testsuite/gcc.target/aarch64/pr95254.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.target/aarch64/pr95254.c 2020-08-05 20:33:21.424000000 +0800
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-slp-vectorize -march=armv8.2-a+sve -msve-vector-bits=256" } */
+
+typedef short __attribute__((vector_size (8))) v4hi;
+
+typedef union U4HI { v4hi v; short a[4]; } u4hi;
+
+short b[4];
+
+void pass_v4hi (v4hi v)
+{
+ int i;
+ u4hi u;
+ u.v = v;
+ for (i = 0; i < 4; i++)
+ b[i] = u.a[i];
+};
+
+/* { dg-final { scan-assembler-not "ptrue" } } */
diff -Nurp a/gcc/testsuite/gcc.target/i386/pr67609.c b/gcc/testsuite/gcc.target/i386/pr67609.c
--- a/gcc/testsuite/gcc.target/i386/pr67609.c 2020-08-05 20:33:04.628000000 +0800
+++ b/gcc/testsuite/gcc.target/i386/pr67609.c 2020-08-05 20:33:21.424000000 +0800
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -msse2" } */
/* { dg-require-effective-target lp64 } */
-/* { dg-final { scan-assembler "movdqa" } } */
+/* { dg-final { scan-assembler "movq\t%xmm0" } } */
#include <emmintrin.h>
__m128d reg;

View File

@ -1,3 +1,9 @@
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-PR91176-Skip-debug-insns-when-computing-inline-costs.patch
d3ed5b56646511a52db9992f4024969bfc9a13f9
diff -uprN a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c diff -uprN a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
--- a/gcc/ipa-fnsummary.c --- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c

View File

@ -0,0 +1,132 @@
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-cselim-Don-t-assume-it-is-safe-to-cstore-replace-a-s.patch
cf39dccf9284d2fd9f9aa7050760adea110c8d88
diff -uprN a/gcc/testsuite/gcc.c-torture/execute/pr94734.c b/gcc/testsuite/gcc.c-torture/execute/pr94734.c
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr94734.c
@@ -0,0 +1,59 @@
+/* PR tree-optimization/94734 */
+
+__attribute__((noipa)) int
+foo (int n)
+{
+ int arr[16], s = 0;
+ for (int i = 0; i < n; i++)
+ {
+ if (i < 16)
+ arr[i] = i;
+ }
+ for (int i = 0; i < 16; i++)
+ s += arr[i];
+ return s;
+}
+
+__attribute__((noipa)) int
+bar (int n, int x, unsigned long y, unsigned long z)
+{
+ int arr[16], s = 0;
+ arr[4] = 42;
+ for (int i = 0; i < n; i++)
+ {
+ if (x == (i & 0x25))
+ arr[y] = i;
+ }
+ return arr[z];
+}
+
+__attribute__((noipa)) int
+baz (int n, int x, unsigned long z)
+{
+ int arr[16], s = 0;
+ arr[12] = 42;
+ for (int i = 0; i < n; i++)
+ {
+ if (x == (i & 0x25))
+ arr[7] = i;
+ }
+ return arr[z];
+}
+
+int
+main ()
+{
+ if (foo (10374) != 15 * 16 / 2)
+ __builtin_abort ();
+ if (bar (25, 0x25, (unsigned long) 0xdeadbeefbeefdeadULL, 4) != 42)
+ __builtin_abort ();
+ if (bar (25, 4, 15, 15) != 22)
+ __builtin_abort ();
+ if (baz (25, 0x25, 12) != 42)
+ __builtin_abort ();
+ if (baz (25, 4, 7) != 22)
+ __builtin_abort ();
+ if (baz (25, 4, 12) != 42)
+ __builtin_abort ();
+ return 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
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c
@@ -9,4 +9,4 @@ unsigned test(unsigned k, unsigned b) {
return a[0]+a[1];
}
-/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" { xfail *-*-* } } } */
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
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c
@@ -11,4 +11,4 @@ unsigned test(unsigned k, unsigned b) {
return a[0]+a[1];
}
-/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" { xfail *-*-* } } } */
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
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c
@@ -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" } } */
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" { xfail *-*-* } } } */
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c
@@ -16,4 +16,4 @@ int test(int b, int k) {
return a.data[0].x + a.data[1].x;
}
-/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" { xfail *-*-* } } } */
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
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "params.h"
#include "case-cfn-macros.h"
+#include "tree-eh.h"
static unsigned int tree_ssa_phiopt_worker (bool, bool, bool);
static bool two_value_replacement (basic_block, basic_block, edge, gphi *,
@@ -2237,10 +2238,13 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
whose value is not available readily, which we want to avoid. */
if (!nontrap->contains (lhs))
{
- /* If LHS is a local variable without address-taken, we could
+ /* If LHS is an access to a local variable without address-taken
+ (or when we allow data races) and known not to trap, we could
always safely move down the store. */
tree base = get_base_address (lhs);
- if (!auto_var_p (base) || TREE_ADDRESSABLE (base))
+ if (!auto_var_p (base)
+ || (TREE_ADDRESSABLE (base) && !flag_store_data_races)
+ || tree_could_trap_p (lhs))
return false;
}

File diff suppressed because it is too large Load Diff