aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-11-23 11:28:31 +0100
committerMartin Liska <mliska@suse.cz>2021-11-23 11:28:31 +0100
commite6cf319354390ac1720646654f50d72dde3fa618 (patch)
treebca470dd5247aa7c9cb7eebba8e56de892ee58fa /gcc
parent44a06feaf84111c298bb906b4906b54073fc61d5 (diff)
parentd3f22853d18195b6ef4c9e26298befa55402eb4a (diff)
downloadgcc-e6cf319354390ac1720646654f50d72dde3fa618.zip
gcc-e6cf319354390ac1720646654f50d72dde3fa618.tar.gz
gcc-e6cf319354390ac1720646654f50d72dde3fa618.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog36
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/c/c-typeck.c1
-rw-r--r--gcc/config/rs6000/altivec.md46
-rw-r--r--gcc/cp/ChangeLog24
-rw-r--r--gcc/cp/optimize.c1
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/semantics.c1
-rw-r--r--gcc/cp/typeck.c26
-rw-r--r--gcc/doc/invoke.texi8
-rw-r--r--gcc/gimple-fold.c22
-rw-r--r--gcc/gimple-loop-jam.c4
-rw-r--r--gcc/gimple-ssa-store-merging.c9
-rw-r--r--gcc/gimplify.c85
-rw-r--r--gcc/match.pd14
-rw-r--r--gcc/testsuite/ChangeLog46
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr102431.c16
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pragma-3.c20
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pragma-4.c20
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pragma-5.c20
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr65327.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C4
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/ptrtomem3.C14
-rw-r--r--gcc/testsuite/g++.dg/gomp/pr102431.C13
-rw-r--r--gcc/testsuite/g++.dg/template/crash106.C4
-rw-r--r--gcc/testsuite/g++.dg/torture/pr103361.C18
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr102216-1.C21
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr102216-2.C45
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/modref-dse-4.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/modref-dse-5.c5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr102232.c52
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr103345.c53
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96779-disabled.c84
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96779.c79
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr98953.c14
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec_reve_1.c17
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec_reve_2.c29
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr102431.f9010
-rw-r--r--gcc/tree-data-ref.c2
-rw-r--r--gcc/tree-inline.c8
-rw-r--r--gcc/tree-inline.h3
-rw-r--r--gcc/tree-ssa-dse.c173
44 files changed, 942 insertions, 133 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1e94c54..b70adbd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,39 @@
+2021-11-22 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR tree-optimization/98953
+ PR tree-optimization/103345
+ * gimple-ssa-store-merging.c (find_bswap_or_nop_1): Handle
+ BIT_XOR_EXPR and PLUS_EXPR the same as BIT_IOR_EXPR.
+ (pass_optimize_bswap::execute): Likewise.
+
+2021-11-22 Martin Liska <mliska@suse.cz>
+
+ * doc/invoke.texi: Remove duplicate documentation for 3 params.
+
+2021-11-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/103351
+ * tree-ssa-dce.c (sort_phi_args): Sort after e->dest_idx as
+ second key.
+
+2021-11-22 liuhongt <hongtao.liu@intel.com>
+
+ PR target/103275
+ * config/i386/constraints.md (Bk): New
+ define_memory_constraint.
+ * config/i386/i386-protos.h (ix86_gpr_tls_address_pattern_p):
+ Declare.
+ * config/i386/i386.c (ix86_gpr_tls_address_pattern_p): New
+ function.
+ * config/i386/i386.md (*movsi_internal): Don't allow
+ mask/sse/mmx move in TLS code sequences.
+ (*movdi_internal): Ditto.
+
+2021-11-22 Kewen Lin <linkw@linux.ibm.com>
+
+ * config/xtensa/xtensa.md (movdi_internal, movdf_internal): Fix split
+ condition.
+
2021-11-21 Jakub Jelinek <jakub@redhat.com>
PR c++/101180
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 7e15177..e45f2d0 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20211122
+20211123
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 50d7010..b71358e 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -13848,7 +13848,6 @@ c_clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
id.transform_call_graph_edges = CB_CGE_DUPLICATE;
id.transform_new_cfg = true;
id.transform_return_to_modify = false;
- id.transform_lang_insert_block = NULL;
id.eh_lp_nr = 0;
walk_tree (&stmt, copy_tree_body_r, &id, NULL);
return stmt;
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index a057218..ef43211 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -3984,12 +3984,43 @@
DONE;
})
+;; Vector reverse elements for V16QI V8HI V4SI V4SF
(define_expand "altivec_vreve<mode>2"
- [(set (match_operand:VEC_A 0 "register_operand" "=v")
- (unspec:VEC_A [(match_operand:VEC_A 1 "register_operand" "v")]
+ [(set (match_operand:VEC_K 0 "register_operand" "=v")
+ (unspec:VEC_K [(match_operand:VEC_K 1 "register_operand" "v")]
UNSPEC_VREVEV))]
"TARGET_ALTIVEC"
{
+ if (TARGET_P9_VECTOR)
+ {
+ if (<MODE>mode == V16QImode)
+ emit_insn (gen_p9_xxbrq_v16qi (operands[0], operands[1]));
+ else if (<MODE>mode == V8HImode)
+ {
+ rtx subreg1 = simplify_gen_subreg (V1TImode, operands[1],
+ <MODE>mode, 0);
+ rtx temp = gen_reg_rtx (V1TImode);
+ emit_insn (gen_p9_xxbrq_v1ti (temp, subreg1));
+ rtx subreg2 = simplify_gen_subreg (<MODE>mode, temp,
+ V1TImode, 0);
+ emit_insn (gen_p9_xxbrh_v8hi (operands[0], subreg2));
+ }
+ else /* V4SI and V4SF. */
+ {
+ rtx subreg1 = simplify_gen_subreg (V1TImode, operands[1],
+ <MODE>mode, 0);
+ rtx temp = gen_reg_rtx (V1TImode);
+ emit_insn (gen_p9_xxbrq_v1ti (temp, subreg1));
+ rtx subreg2 = simplify_gen_subreg (<MODE>mode, temp,
+ V1TImode, 0);
+ if (<MODE>mode == V4SImode)
+ emit_insn (gen_p9_xxbrw_v4si (operands[0], subreg2));
+ else
+ emit_insn (gen_p9_xxbrw_v4sf (operands[0], subreg2));
+ }
+ DONE;
+ }
+
int i, j, size, num_elements;
rtvec v = rtvec_alloc (16);
rtx mask = gen_reg_rtx (V16QImode);
@@ -4008,6 +4039,17 @@
DONE;
})
+;; Vector reverse elements for V2DI V2DF
+(define_expand "altivec_vreve<mode>2"
+ [(set (match_operand:VEC_64 0 "register_operand" "=v")
+ (unspec:VEC_64 [(match_operand:VEC_64 1 "register_operand" "v")]
+ UNSPEC_VREVEV))]
+ "TARGET_ALTIVEC"
+{
+ emit_insn (gen_xxswapd_<mode> (operands[0], operands[1]));
+ DONE;
+})
+
;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL,
;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
(define_insn "altivec_lvlx"
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 205416f..836ab86 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,27 @@
+2021-11-22 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_x_unary_op): Set address location.
+ (convert_member_func_to_ptr): Handle location wrapper.
+ * pt.c (convert_nontype_argument): Likewise.
+
+2021-11-22 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (check_return_expr): Only strip location wrapper during
+ NRV handling.
+
+2021-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/101731
+ * parser.c (cp_parser_late_parsing_oacc_routine): Set
+ parser->oacc_routine->fndecl_seen here, rather than ...
+ (cp_finalize_oacc_routine): ... here. Don't error if
+ parser->oacc_routine->fndecl_seen is set for FUNCTION_DECLs.
+
+2021-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/103349
+ * constexpr.c (potential_constant_expression_1): Punt on OMP_MASKED.
+
2021-11-19 Jakub Jelinek <jakub@redhat.com>
PR c++/101180
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 22ed7d3..e6fd27f 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -103,7 +103,6 @@ clone_body (tree clone, tree fn, void *arg_map)
id.transform_call_graph_edges = CB_CGE_DUPLICATE;
id.transform_new_cfg = true;
id.transform_return_to_modify = false;
- id.transform_lang_insert_block = NULL;
/* We're not inside any EH region. */
id.eh_lp_nr = 0;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c73e035..288625e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7267,6 +7267,8 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
const bool val_dep_p = value_dependent_expression_p (expr);
if (val_dep_p)
expr = canonicalize_expr_argument (expr, complain);
+ else
+ STRIP_ANY_LOCATION_WRAPPER (expr);
/* 14.3.2/5: The null pointer{,-to-member} conversion is applied
to a non-type argument of "nullptr". */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index d962b29..79b8162 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -6066,7 +6066,6 @@ clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
id.transform_call_graph_edges = CB_CGE_DUPLICATE;
id.transform_new_cfg = true;
id.transform_return_to_modify = false;
- id.transform_lang_insert_block = NULL;
id.eh_lp_nr = 0;
walk_tree (&stmt, copy_tree_body_r, &id, NULL);
return stmt;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 58919aa..84dcb6f 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6492,6 +6492,11 @@ build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
}
exp = cp_build_addr_expr_strict (xarg, complain);
+
+ if (TREE_CODE (exp) == PTRMEM_CST)
+ exp = maybe_wrap_with_location (exp, loc);
+ else
+ protected_set_expr_location (exp, loc);
}
if (processing_template_decl && exp != error_mark_node)
@@ -8179,10 +8184,14 @@ convert_member_func_to_ptr (tree type, tree expr, tsubst_flags_t complain)
if (!(complain & tf_warning_or_error))
return error_mark_node;
+ location_t loc = cp_expr_loc_or_input_loc (expr);
+
if (pedantic || warn_pmf2ptr)
- pedwarn (input_location, pedantic ? OPT_Wpedantic : OPT_Wpmf_conversions,
+ pedwarn (loc, pedantic ? OPT_Wpedantic : OPT_Wpmf_conversions,
"converting from %qH to %qI", intype, type);
+ STRIP_ANY_LOCATION_WRAPPER (expr);
+
if (TREE_CODE (intype) == METHOD_TYPE)
expr = build_addr_func (expr, complain);
else if (TREE_CODE (expr) == PTRMEM_CST)
@@ -8197,7 +8206,9 @@ convert_member_func_to_ptr (tree type, tree expr, tsubst_flags_t complain)
if (expr == error_mark_node)
return error_mark_node;
- return build_nop (type, expr);
+ expr = build_nop (type, expr);
+ SET_EXPR_LOCATION (expr, loc);
+ return expr;
}
/* Build a NOP_EXPR to TYPE, but mark it as a reinterpret_cast so that
@@ -10545,19 +10556,20 @@ check_return_expr (tree retval, bool *no_warning)
this restriction, anyway. (jason 2000-11-19)
See finish_function and finalize_nrv for the rest of this optimization. */
+ tree bare_retval = NULL_TREE;
if (retval)
{
retval = maybe_undo_parenthesized_ref (retval);
- STRIP_ANY_LOCATION_WRAPPER (retval);
+ bare_retval = tree_strip_any_location_wrapper (retval);
}
- bool named_return_value_okay_p = can_do_nrvo_p (retval, functype);
+ bool named_return_value_okay_p = can_do_nrvo_p (bare_retval, functype);
if (fn_returns_value_p && flag_elide_constructors)
{
if (named_return_value_okay_p
&& (current_function_return_value == NULL_TREE
- || current_function_return_value == retval))
- current_function_return_value = retval;
+ || current_function_return_value == bare_retval))
+ current_function_return_value = bare_retval;
else
current_function_return_value = error_mark_node;
}
@@ -10571,7 +10583,7 @@ check_return_expr (tree retval, bool *no_warning)
maybe_warn_pessimizing_move (retval, functype);
/* Do any required conversions. */
- if (retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
+ if (bare_retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
/* No conversions are required. */
;
else
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 34484f6..97b6c99 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -14754,14 +14754,6 @@ Maximum number of arrays per scop.
@item max-vartrack-reverse-op-size
Max. size of loc list for which reverse ops should be added.
-@item tracer-dynamic-coverage-feedback
-The percentage of function, weighted by execution frequency,
-that must be covered by trace formation.
-Used when profile feedback is available.
-
-@item max-inline-recursive-depth-auto
-The maximum depth of recursive inlining for non-inline functions.
-
@item fsm-scale-path-stmts
Scale factor to apply to the number of statements in a threading path
when comparing to the number of (scaled) blocks.
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index ad9703e..73f090b 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -6061,6 +6061,28 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
if (REFERENCE_CLASS_P (*lhs)
&& maybe_canonicalize_mem_ref_addr (lhs))
changed = true;
+ /* Canonicalize &MEM[ssa_n, CST] to ssa_n p+ CST.
+ This cannot be done in maybe_canonicalize_mem_ref_addr
+ as the gimple now has two operands rather than one.
+ The same reason why this can't be done in
+ maybe_canonicalize_mem_ref_addr is the same reason why
+ this can't be done inplace. */
+ if (!inplace && TREE_CODE (*rhs) == ADDR_EXPR)
+ {
+ tree inner = TREE_OPERAND (*rhs, 0);
+ if (TREE_CODE (inner) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (inner, 0)) == SSA_NAME
+ && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
+ {
+ tree ptr = TREE_OPERAND (inner, 0);
+ tree addon = TREE_OPERAND (inner, 1);
+ addon = fold_convert (sizetype, addon);
+ gimple_assign_set_rhs_with_ops (gsi, POINTER_PLUS_EXPR,
+ ptr, addon);
+ changed = true;
+ stmt = gsi_stmt (*gsi);
+ }
+ }
}
else
{
diff --git a/gcc/gimple-loop-jam.c b/gcc/gimple-loop-jam.c
index 666f740..933a4e0 100644
--- a/gcc/gimple-loop-jam.c
+++ b/gcc/gimple-loop-jam.c
@@ -402,10 +402,10 @@ adjust_unroll_factor (class loop *inner, struct data_dependence_relation *ddr,
a >= N, or b > 0, or b is zero and a > 0. Otherwise the unroll
factor needs to be limited so that the first condition holds.
That may limit the factor down to zero in the worst case. */
- int dist = dist_v[0];
+ lambda_int dist = dist_v[0];
if (dist < 0)
gcc_unreachable ();
- else if ((unsigned)dist >= *unroll)
+ else if (dist >= (lambda_int)*unroll)
;
else if (lambda_vector_zerop (dist_v + 1, DDR_NB_LOOPS (ddr) - 1))
{
diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c
index 4efa200..1740c9e 100644
--- a/gcc/gimple-ssa-store-merging.c
+++ b/gcc/gimple-ssa-store-merging.c
@@ -742,10 +742,7 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit)
struct symbolic_number n1, n2;
gimple *source_stmt, *source_stmt2;
- if (code != BIT_IOR_EXPR)
- return NULL;
-
- if (TREE_CODE (rhs2) != SSA_NAME)
+ if (!rhs2 || TREE_CODE (rhs2) != SSA_NAME)
return NULL;
rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
@@ -753,6 +750,8 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit)
switch (code)
{
case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case PLUS_EXPR:
source_stmt1 = find_bswap_or_nop_1 (rhs1_stmt, &n1, limit - 1);
if (!source_stmt1)
@@ -1495,6 +1494,8 @@ pass_optimize_bswap::execute (function *fun)
continue;
/* Fall through. */
case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case PLUS_EXPR:
break;
case CONSTRUCTOR:
{
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 467b135..816cdaf 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -13128,21 +13128,15 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
/* Helper for gimplify_omp_loop, called through walk_tree. */
static tree
-replace_reduction_placeholders (tree *tp, int *walk_subtrees, void *data)
+note_no_context_vars (tree *tp, int *, void *data)
{
- if (DECL_P (*tp))
+ if (VAR_P (*tp)
+ && DECL_CONTEXT (*tp) == NULL_TREE
+ && !is_global_var (*tp))
{
- tree *d = (tree *) data;
- if (*tp == OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[0]))
- {
- *tp = OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[1]);
- *walk_subtrees = 0;
- }
- else if (*tp == OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[0]))
- {
- *tp = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[1]);
- *walk_subtrees = 0;
- }
+ vec<tree> *d = (vec<tree> *) data;
+ d->safe_push (*tp);
+ DECL_CONTEXT (*tp) = current_function_decl;
}
return NULL_TREE;
}
@@ -13312,7 +13306,8 @@ gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
{
if (pass == 2)
{
- tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+ tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
+ make_node (BLOCK));
append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
*expr_p = make_node (OMP_PARALLEL);
TREE_TYPE (*expr_p) = void_type_node;
@@ -13379,25 +13374,63 @@ gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
*pc = copy_node (c);
OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
- OMP_CLAUSE_REDUCTION_INIT (*pc)
- = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
- OMP_CLAUSE_REDUCTION_MERGE (*pc)
- = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
{
+ auto_vec<tree> no_context_vars;
+ int walk_subtrees = 0;
+ note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
+ &walk_subtrees, &no_context_vars);
+ if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
+ note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
+ walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
+ note_no_context_vars,
+ &no_context_vars);
+ walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
+ note_no_context_vars,
+ &no_context_vars);
+
OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
= copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
= copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
- tree nc = *pc;
- tree data[2] = { c, nc };
- walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (nc),
- replace_reduction_placeholders,
- data);
- walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (nc),
- replace_reduction_placeholders,
- data);
+
+ hash_map<tree, tree> decl_map;
+ decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
+ decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
+ OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
+ if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
+ decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
+ OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
+
+ copy_body_data id;
+ memset (&id, 0, sizeof (id));
+ id.src_fn = current_function_decl;
+ id.dst_fn = current_function_decl;
+ id.src_cfun = cfun;
+ id.decl_map = &decl_map;
+ id.copy_decl = copy_decl_no_change;
+ id.transform_call_graph_edges = CB_CGE_DUPLICATE;
+ id.transform_new_cfg = true;
+ id.transform_return_to_modify = false;
+ id.eh_lp_nr = 0;
+ walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
+ &id, NULL);
+ walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
+ &id, NULL);
+
+ for (tree d : no_context_vars)
+ {
+ DECL_CONTEXT (d) = NULL_TREE;
+ DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
+ }
+ }
+ else
+ {
+ OMP_CLAUSE_REDUCTION_INIT (*pc)
+ = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
+ OMP_CLAUSE_REDUCTION_MERGE (*pc)
+ = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
}
pc = &OMP_CLAUSE_CHAIN (*pc);
break;
diff --git a/gcc/match.pd b/gcc/match.pd
index f059b47..886f807 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -242,6 +242,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(mult @0 integer_zerop@1)
@1)
+/* -x == x -> x == 0 */
+(for cmp (eq ne)
+ (simplify
+ (cmp:c @0 (negate @0))
+ (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && !TYPE_OVERFLOW_WRAPS (TREE_TYPE(@0)))
+ (cmp @0 { build_zero_cst (TREE_TYPE(@0)); }))))
+
/* Maybe fold x * 0 to 0. The expressions aren't the same
when x is NaN, since x * 0 is also NaN. Nor are they the
same in modes with signed zeros, since multiplying a
@@ -643,6 +651,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
(convert (trunc_mod @0 @1))))
+/* x * (1 + y / x) - y -> x - y % x */
+(simplify
+ (minus (mult:cs @0 (plus:s (trunc_div:s @1 @0) integer_onep)) @1)
+ (if (INTEGRAL_TYPE_P (type))
+ (minus @0 (trunc_mod @1 @0))))
+
/* Optimize TRUNC_MOD_EXPR by a power of two into a BIT_AND_EXPR,
i.e. "X % C" into "X & (C - 1)", if X and C are positive.
Also optimize A % (C << N) where C is a power of 2,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9872619..cdf542e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,49 @@
+2021-11-22 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/template/crash106.C: Adjust.
+ * g++.dg/diagnostic/ptrtomem3.C: New test.
+
+2021-11-22 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/pr65327.C: Adjust location.
+ * g++.dg/cpp23/constexpr-nonlit4.C: Likewise.
+ * g++.dg/cpp23/constexpr-nonlit5.C: Likewise.
+ * g++.dg/cpp2a/constexpr-init1.C: Likewise.
+
+2021-11-22 Jakub Jelinek <jakub@redhat.com>
+ Tobias Burnus <tobias@codesourcery.com>
+
+ PR preprocessor/103165
+ * c-c++-common/gomp/pragma-3.c: New test.
+ * c-c++-common/gomp/pragma-4.c: New test.
+ * c-c++-common/gomp/pragma-5.c: New test.
+
+2021-11-22 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR tree-optimization/98953
+ PR tree-optimization/103345
+ * gcc.dg/tree-ssa/pr98953.c: New test case.
+ * gcc.dg/tree-ssa/pr103345.c: New test case.
+
+2021-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/101731
+ * c-c++-common/goacc/routine-6.c: New test.
+
+2021-11-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/103351
+ * g++.dg/torture/pr103351.C: New testcase.
+
+2021-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/103349
+ * g++.dg/gomp/masked-1.C: New test.
+
+2021-11-22 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr103275.c: New test.
+
2021-11-21 Jakub Jelinek <jakub@redhat.com>
PR c++/101180
diff --git a/gcc/testsuite/c-c++-common/gomp/pr102431.c b/gcc/testsuite/c-c++-common/gomp/pr102431.c
new file mode 100644
index 0000000..bf4f3cb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr102431.c
@@ -0,0 +1,16 @@
+/* PR middle-end/102431 */
+
+struct S { int s; } s;
+void add (struct S *, struct S *);
+void init (struct S *);
+void bar (int i, struct S *);
+#pragma omp declare reduction (+:struct S:add (&omp_out, &omp_in)) initializer (init (&omp_priv))
+
+void
+foo (void)
+{
+ int i;
+ #pragma omp loop bind(teams) reduction(+:s)
+ for (i = 0; i < 8; i++)
+ bar (i, &s);
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-3.c b/gcc/testsuite/c-c++-common/gomp/pragma-3.c
new file mode 100644
index 0000000..c1dee1b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pragma-3.c
@@ -0,0 +1,20 @@
+/* { dg-additional-options "-fdump-tree-original" } */
+/* PR preprocessor/103165 */
+
+#define inner(...) #__VA_ARGS__ ; _Pragma("omp error severity(warning) message (\"Test\") at(compilation)")
+#define outer(...) inner(__VA_ARGS__)
+
+void
+f (void)
+{
+ const char *str = outer(inner(1,2)); /* { dg-warning "'pragma omp error' encountered: Test" } */
+}
+
+#if 0
+After preprocessing, the expected result are the following three lines:
+ const char *str = "\"1,2\" ; _Pragma(\"omp error severity(warning) message (\\\"Test\\\") at(compilation)\")" ;
+#pragma omp error severity(warning) message ("Test") at(compilation)
+ ;
+#endif
+
+/* { dg-final { scan-tree-dump "const char \\* str = \\(const char \\*\\) \"\\\\\"1,2\\\\\" ; _Pragma\\(\\\\\"omp error severity\\(warning\\) message \\(\\\\\\\\\\\\\"Test\\\\\\\\\\\\\"\\) at\\(compilation\\)\\\\\"\\)\";" "original" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-4.c b/gcc/testsuite/c-c++-common/gomp/pragma-4.c
new file mode 100644
index 0000000..419c4ac
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pragma-4.c
@@ -0,0 +1,20 @@
+/* { dg-additional-options "-fdump-tree-original -save-temps" } */
+/* PR preprocessor/103165 */
+
+#define inner(...) #__VA_ARGS__ ; _Pragma("omp error severity(warning) message (\"Test\") at(compilation)")
+#define outer(...) inner(__VA_ARGS__)
+
+void
+f (void)
+{
+ const char *str = outer(inner(1,2)); /* { dg-warning "'pragma omp error' encountered: Test" } */
+}
+
+#if 0
+After preprocessing, the expected result are the following three lines:
+ const char *str = "\"1,2\" ; _Pragma(\"omp error severity(warning) message (\\\"Test\\\") at(compilation)\")" ;
+#pragma omp error severity(warning) message ("Test") at(compilation)
+ ;
+#endif
+
+/* { dg-final { scan-tree-dump "const char \\* str = \\(const char \\*\\) \"\\\\\"1,2\\\\\" ; _Pragma\\(\\\\\"omp error severity\\(warning\\) message \\(\\\\\\\\\\\\\"Test\\\\\\\\\\\\\"\\) at\\(compilation\\)\\\\\"\\)\";" "original" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-5.c b/gcc/testsuite/c-c++-common/gomp/pragma-5.c
new file mode 100644
index 0000000..af54b68
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pragma-5.c
@@ -0,0 +1,20 @@
+/* { dg-additional-options "-fdump-tree-original" } */
+/* PR preprocessor/103165 */
+
+#define inner(...) #__VA_ARGS__ ; _Pragma ( " omp error severity (warning) message (\"Test\") at(compilation)" )
+#define outer(...) inner(__VA_ARGS__)
+
+void
+f (void)
+{
+ const char *str = outer(inner(1,2)); /* { dg-warning "'pragma omp error' encountered: Test" } */
+}
+
+#if 0
+After preprocessing, the expected result are the following three lines:
+ const char *str = "\"1,2\" ; _Pragma ( \" omp error severity (warning) message (\\\"Test\\\") at(compilation)\" )" ;
+#pragma omp error severity(warning) message ("Test") at(compilation)
+ ;
+#endif
+
+/* { dg-final { scan-tree-dump "const char \\* str = \\(const char \\*\\) \"\\\\\"1,2\\\\\" ; _Pragma \\( \\\\\" omp\\\\t\\\\terror severity \\(warning\\)\\\\tmessage \\(\\\\\\\\\\\\\"Test\\\\\\\\\\\\\"\\) at\\(compilation\\)\\\\\" \\)\";" "original" } } */
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr65327.C b/gcc/testsuite/g++.dg/cpp0x/pr65327.C
index 6e888eb..e814995 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr65327.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr65327.C
@@ -14,5 +14,5 @@ foo ()
constexpr volatile int // { dg-warning "deprecated" "" { target c++2a } }
bar ()
{
- return i;
-} // { dg-error "lvalue-to-rvalue conversion of a volatile lvalue" }
+ return i; // { dg-error "lvalue-to-rvalue conversion of a volatile lvalue" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C
index e4ed2e3..bdc97a9 100644
--- a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit4.C
@@ -34,7 +34,7 @@ baz (int x)
{
static const int v = qux (); // { dg-message "'v' was not initialized with a constant expression" }
case 12:
- return v;
+ return v; // { dg-error "the value of 'v' is not usable in a constant expression" }
}
return 0;
}
@@ -46,12 +46,12 @@ corge (int x)
{
const thread_local int v = qux (); // { dg-message "'v' was not initialized with a constant expression" }
case 12:
- return v;
+ return v; // { dg-error "the value of 'v' is not usable in a constant expression" }
}
return 0;
}
constexpr int a = foo (12);
constexpr int b = bar (12);
-constexpr int c = baz (12); // { dg-error "the value of 'v' is not usable in a constant expression" }
-constexpr int d = corge (12); // { dg-error "the value of 'v' is not usable in a constant expression" }
+constexpr int c = baz (12);
+constexpr int d = corge (12);
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C
index 838f282..86d5dba 100644
--- a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit5.C
@@ -34,7 +34,7 @@ baz (int x)
{
static int v = 6; // { dg-message "int v' is not const" }
case 12:
- return v;
+ return v; // { dg-error "the value of 'v' is not usable in a constant expression" }
}
return 0;
}
@@ -46,12 +46,12 @@ corge (int x)
{
thread_local int v = 6; // { dg-message "int v' is not const" }
case 12:
- return v;
+ return v; // { dg-error "the value of 'v' is not usable in a constant expression" }
}
return 0;
}
constexpr int a = foo (12);
constexpr int b = bar (12);
-constexpr int c = baz (12); // { dg-error "the value of 'v' is not usable in a constant expression" }
-constexpr int d = corge (12); // { dg-error "the value of 'v' is not usable in a constant expression" }
+constexpr int c = baz (12);
+constexpr int d = corge (12);
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C
index 75984a2..e56ecfe 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C
@@ -73,11 +73,11 @@ fn7 (bool b)
int a; // { dg-message ".int a. is not const" }
if (b)
a = 42;
- return a;
+ return a; // { dg-error "the value of .a. is not usable" }
}
static_assert (fn7 (true) == 42);
-static_assert (fn7 (false) == 42); // { dg-error "non-constant condition|the value of .a. is not usable" }
+static_assert (fn7 (false) == 42); // { dg-error "non-constant condition" }
// { dg-message "in .constexpr. expansion of" "" { target *-*-* } .-1 }
constexpr int
diff --git a/gcc/testsuite/g++.dg/diagnostic/ptrtomem3.C b/gcc/testsuite/g++.dg/diagnostic/ptrtomem3.C
new file mode 100644
index 0000000..6096a98
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/ptrtomem3.C
@@ -0,0 +1,14 @@
+// Check that the diagnostic for a pointer-to-member expression has the caret
+// at the &.
+
+struct A
+{
+ int i;
+};
+
+void f();
+
+int main()
+{
+ return &A::i; // { dg-error "10:cannot convert" }
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr102431.C b/gcc/testsuite/g++.dg/gomp/pr102431.C
new file mode 100644
index 0000000..7db36f4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/pr102431.C
@@ -0,0 +1,13 @@
+// PR middle-end/102431
+
+struct S { S (); ~S (); S (const S &); void add (const S &); int s; } s;
+void bar (int, S &);
+#pragma omp declare reduction (+:S:omp_out.add (omp_in))
+
+void
+foo ()
+{
+ #pragma omp loop bind(teams) reduction(+:s)
+ for (int i = 0; i < 8; i++)
+ bar (i, s);
+}
diff --git a/gcc/testsuite/g++.dg/template/crash106.C b/gcc/testsuite/g++.dg/template/crash106.C
index f904bd4..35cedb5 100644
--- a/gcc/testsuite/g++.dg/template/crash106.C
+++ b/gcc/testsuite/g++.dg/template/crash106.C
@@ -7,6 +7,6 @@ struct A
template<T> void foo(); // { dg-error "type" "" { target c++17_down } }
};
-template<T N = 0.0, void (A::*)() = &A::foo<N> > struct B {}; // { dg-error "type|declared" "" { target c++17_down } }
+template<T N = 0.0, void (A::*)() = &A::foo<N> > struct B {}; // { dg-error "type|declared|could not convert" "" { target c++17_down } }
-B<> b; // { dg-error "(could not convert|no matches)" "" { target c++17_down } }
+B<> b; // { dg-message "" "" { target c++17_down } }
diff --git a/gcc/testsuite/g++.dg/torture/pr103361.C b/gcc/testsuite/g++.dg/torture/pr103361.C
new file mode 100644
index 0000000..ec1d6e1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr103361.C
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-floop-unroll-and-jam" } */
+
+char a, b;
+extern unsigned short c[];
+extern bool d[];
+const unsigned short &e(const unsigned short &f, const unsigned short &g) {
+ if (g < f)
+ return g;
+ return f;
+}
+void k() {
+ for (int h = 0; b; h += 3)
+ for (unsigned long i = 0; i < 11104842004558084287ULL;
+ i += -11104842004558084300ULL)
+ for (bool j(e(6, e(6, c[h + i]))); j < (bool)a; j = 7)
+ d[7] = 0;
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr102216-1.C b/gcc/testsuite/g++.dg/tree-ssa/pr102216-1.C
new file mode 100644
index 0000000..21f7f67
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr102216-1.C
@@ -0,0 +1,21 @@
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+void link_error ();
+void g ()
+{
+ const char **language_names;
+
+ language_names = new const char *[6];
+
+ const char **language_names_p = language_names;
+
+ language_names_p++;
+ language_names_p++;
+ language_names_p++;
+
+ if ( (language_names_p) - (language_names+3) != 0)
+ link_error();
+ delete[] language_names;
+}
+/* We should have removed the link_error on the gimple level as GCC should
+ be able to tell that language_names_p is the same as language_names+3. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" } } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr102216-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr102216-2.C
new file mode 100644
index 0000000..8d351a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr102216-2.C
@@ -0,0 +1,45 @@
+/* { dg-options "-O2 -Wall" } */
+#include <algorithm>
+
+static inline bool
+compare_cstrings (const char *str1, const char *str2)
+{
+ return str1 < str2;
+}
+
+void
+add_set_language_command ()
+{
+ static const char **language_names;
+
+ language_names = new const char *[6];
+
+ language_names[0] = "auto";
+ language_names[1] = "local";
+ language_names[2] = "unknown";
+
+ const char **language_names_p = language_names;
+ /* language_names_p == &language_names[0]. */
+ language_names_p++;
+ /* language_names_p == &language_names[1]. */
+ language_names_p++;
+ /* language_names_p == &language_names[2]. */
+ language_names_p++;
+ /* language_names_p == &language_names[3]. */
+
+ const char **sort_begin;
+
+ if (0)
+ sort_begin = &language_names[3];
+ else
+ sort_begin = language_names_p;
+
+ language_names[3] = "";
+ language_names[4] = "";
+ language_names[5] = NULL;
+
+ /* There should be no warning associated with this std::sort as
+ sort_begin != &language_names[5] and GCC should be able to figure
+ that out. */
+ std::sort (sort_begin, &language_names[5], compare_cstrings);
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-dse-4.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-dse-4.c
index 81aa7dc..19e91b0 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/modref-dse-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-dse-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-dse2-details" } */
+/* { dg-options "-O2 -fdump-tree-dse1-details" } */
struct a {int a,b,c;};
__attribute__ ((noinline))
void
@@ -23,4 +23,4 @@ set (struct a *a)
my_pleasure (a);
a->b=1;
}
-/* { dg-final { scan-tree-dump "Deleted dead store: kill_me" "dse2" } } */
+/* { dg-final { scan-tree-dump "Deleted dead store: kill_me" "dse1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-dse-5.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-dse-5.c
index ad35b70..dc2c289 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/modref-dse-5.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-dse-5.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-dse2-details" } */
+/* { dg-options "-O2 -fdump-tree-dse1-details" } */
struct a {int a,b,c;};
__attribute__ ((noinline))
void
@@ -36,8 +36,7 @@ set (struct a *a)
{
wrap (0, a);
int ret = wrap2 (0, a);
- //int ret = my_pleasure (a);
a->b=1;
return ret;
}
-/* { dg-final { scan-tree-dump "Deleted dead store: wrap" "dse2" } } */
+/* { dg-final { scan-tree-dump "Deleted dead store: wrap" "dse1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr102232.c b/gcc/testsuite/gcc.dg/tree-ssa/pr102232.c
new file mode 100644
index 0000000..62bca69
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr102232.c
@@ -0,0 +1,52 @@
+/* PR tree-optimization/102232 */
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+int __attribute__ ((noipa)) foo (int a, int b)
+{
+ return b * (1 + a / b) - a;
+}
+
+int
+main (void)
+{
+ // few randomly generated test cases
+ if (foo (71856034, 238) != 212)
+ {
+ __builtin_abort ();
+ }
+ if (foo (71856034, 10909) != 1549)
+ {
+ __builtin_abort ();
+ }
+ if (foo (20350, 1744) != 578)
+ {
+ __builtin_abort ();
+ }
+ if (foo (444813, 88563) != 86565)
+ {
+ __builtin_abort ();
+ }
+ if (foo (112237, 63004) != 13771)
+ {
+ __builtin_abort ();
+ }
+ if (foo (68268386, 787116) != 210706)
+ {
+ __builtin_abort ();
+ }
+ if (foo (-444813, 88563) != 90561)
+ {
+ __builtin_abort ();
+ }
+ if (foo (-68268386, 787116) != 1363526)
+ {
+ __builtin_abort ();
+ }
+
+ return 0;
+}
+
+/* Verify that multiplication and division has been removed. */
+/* { dg-final { scan-tree-dump-not " \\* " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " / " "optimized" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr103345.c b/gcc/testsuite/gcc.dg/tree-ssa/pr103345.c
new file mode 100644
index 0000000..94388b5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr103345.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-bswap-details" } */
+
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+
+uint32_t load_le_32_or(const uint8_t *ptr)
+{
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ return ((uint32_t)ptr[0]) |
+ ((uint32_t)ptr[1] << 8) |
+ ((uint32_t)ptr[2] << 16) |
+ ((uint32_t)ptr[3] << 24);
+#else
+ return ((uint32_t)ptr[3]) |
+ ((uint32_t)ptr[2] << 8) |
+ ((uint32_t)ptr[1] << 16) |
+ ((uint32_t)ptr[0] << 24);
+#endif
+}
+
+uint32_t load_le_32_add(const uint8_t *ptr)
+{
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ return ((uint32_t)ptr[0]) +
+ ((uint32_t)ptr[1] << 8) +
+ ((uint32_t)ptr[2] << 16) +
+ ((uint32_t)ptr[3] << 24);
+#else
+ return ((uint32_t)ptr[3]) +
+ ((uint32_t)ptr[2] << 8) +
+ ((uint32_t)ptr[1] << 16) +
+ ((uint32_t)ptr[0] << 24);
+#endif
+}
+
+uint32_t load_le_32_xor(const uint8_t *ptr)
+{
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ return ((uint32_t)ptr[0]) ^
+ ((uint32_t)ptr[1] << 8) ^
+ ((uint32_t)ptr[2] << 16) ^
+ ((uint32_t)ptr[3] << 24);
+#else
+ return ((uint32_t)ptr[0]) ^
+ ((uint32_t)ptr[1] << 8) ^
+ ((uint32_t)ptr[2] << 16) ^
+ ((uint32_t)ptr[3] << 24);
+#endif
+}
+
+/* { dg-final { scan-tree-dump-times "32 bit load in target endianness found" 3 "bswap" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96779-disabled.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96779-disabled.c
new file mode 100644
index 0000000..205133d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96779-disabled.c
@@ -0,0 +1,84 @@
+/* PR tree-optimization/96779 */
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-optimized -fwrapv" } */
+
+#include <stdbool.h>
+
+bool __attribute__ ((noipa)) f_func(int a)
+{
+ return -a == a;
+}
+
+bool __attribute__ ((noipa)) g_func(unsigned int a)
+{
+ return -a == a;
+}
+
+bool __attribute__ ((noipa)) h_func(short a)
+{
+ return -a == a;
+}
+
+bool __attribute__ ((noipa)) k_func(long a)
+{
+ return -a == a;
+}
+
+int
+main (void)
+{
+ // few randomly generated test cases
+ if (f_func (71856034))
+ {
+ __builtin_abort ();
+ }
+ if (g_func (71856034))
+ {
+ __builtin_abort ();
+ }
+ if (h_func (1744))
+ {
+ __builtin_abort ();
+ }
+ if (k_func (68268386))
+ {
+ __builtin_abort ();
+ }
+ if (f_func (-112237))
+ {
+ __builtin_abort ();
+ }
+ if (g_func (-787116))
+ {
+ __builtin_abort ();
+ }
+ if (h_func (-863))
+ {
+ __builtin_abort ();
+ }
+ if (k_func (-787116))
+ {
+ __builtin_abort ();
+ }
+ if (!f_func (0))
+ {
+ __builtin_abort ();
+ }
+ if (!g_func (0))
+ {
+ __builtin_abort ();
+ }
+ if (!h_func (0))
+ {
+ __builtin_abort ();
+ }
+ if (!k_func (0))
+ {
+ __builtin_abort ();
+ }
+
+ return 0;
+}
+
+/* Verify that we have *not* transfered "= -" pattern in any of those functions. */
+/* { dg-final { scan-tree-dump-times "= -" 4 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96779.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96779.c
new file mode 100644
index 0000000..0d46e8e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96779.c
@@ -0,0 +1,79 @@
+/* PR tree-optimization/96779 */
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+#include <stdbool.h>
+
+bool __attribute__ ((noipa)) f_func(int a)
+{
+ return -a == a;
+}
+
+bool __attribute__ ((noipa)) h_func(short a)
+{
+ return -a == a;
+}
+
+bool __attribute__ ((noipa)) k_func(long a)
+{
+ return -a == a;
+}
+
+int
+main (void)
+{
+ // few randomly generated test cases
+ if (f_func (71856034))
+ {
+ __builtin_abort ();
+ }
+ if (f_func (71856034))
+ {
+ __builtin_abort ();
+ }
+ if (h_func (1744))
+ {
+ __builtin_abort ();
+ }
+ if (k_func (68268386))
+ {
+ __builtin_abort ();
+ }
+ if (f_func (-112237))
+ {
+ __builtin_abort ();
+ }
+ if (f_func (-787116))
+ {
+ __builtin_abort ();
+ }
+ if (h_func (-863))
+ {
+ __builtin_abort ();
+ }
+ if (k_func (-787116))
+ {
+ __builtin_abort ();
+ }
+ if (!f_func (0))
+ {
+ __builtin_abort ();
+ }
+ if (!f_func (0))
+ {
+ __builtin_abort ();
+ }
+ if (!h_func (0))
+ {
+ __builtin_abort ();
+ }
+ if (!k_func (0))
+ {
+ __builtin_abort ();
+ }
+
+ return 0;
+}
+
+/* Verify that we transfered to "= -" pattern from "_2 = -_1;". */
+/* { dg-final { scan-tree-dump-not "= -" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr98953.c b/gcc/testsuite/gcc.dg/tree-ssa/pr98953.c
new file mode 100644
index 0000000..7687dc2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr98953.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-bswap-details" } */
+
+int foo(unsigned char *ptr)
+{
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ return ptr[0] + (ptr[1] << 8);
+#else
+ return ptr[1] + (ptr[0] << 8);
+#endif
+}
+
+/* { dg-final { scan-tree-dump "16 bit load in target endianness found" "bswap" } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/vec_reve_1.c b/gcc/testsuite/gcc.target/powerpc/vec_reve_1.c
new file mode 100644
index 0000000..120c318
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec_reve_1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-O2 -maltivec" } */
+
+#include <altivec.h>
+
+vector double foo1 (vector double a)
+{
+ return vec_reve (a);
+}
+
+vector long long foo2 (vector long long a)
+{
+ return vec_reve (a);
+}
+
+/* { dg-final { scan-assembler-times {\mxxpermdi\M} 2 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec_reve_2.c b/gcc/testsuite/gcc.target/powerpc/vec_reve_2.c
new file mode 100644
index 0000000..9661939
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec_reve_2.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -O2" } */
+
+#include <altivec.h>
+
+vector int foo1 (vector int a)
+{
+ return vec_reve (a);
+}
+
+vector float foo2 (vector float a)
+{
+ return vec_reve (a);
+}
+
+vector short foo3 (vector short a)
+{
+ return vec_reve (a);
+}
+
+vector char foo4 (vector char a)
+{
+ return vec_reve (a);
+}
+
+/* { dg-final { scan-assembler-times {\mxxbrq\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mxxbrw\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxxbrh\M} 1 } } */
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr102431.f90 b/gcc/testsuite/gfortran.dg/gomp/pr102431.f90
new file mode 100644
index 0000000..71efed8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr102431.f90
@@ -0,0 +1,10 @@
+! PR middle-end/102431
+
+program pr102431
+ integer :: a(2)
+ a(:) = 0
+ !$omp parallel loop reduction(+:a)
+ do i = 1, 8
+ a = a + 1
+ end do
+end
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 46f4ffe..9b6ca1a 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -388,7 +388,7 @@ print_lambda_vector (FILE * outfile, lambda_vector vector, int n)
int i;
for (i = 0; i < n; i++)
- fprintf (outfile, "%3d ", (int)vector[i]);
+ fprintf (outfile, HOST_WIDE_INT_PRINT_DEC " ", vector[i]);
fprintf (outfile, "\n");
}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 8c108d8..bc5ff0b 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -823,9 +823,6 @@ remap_block (tree *block, copy_body_data *id)
&BLOCK_NONLOCALIZED_VARS (new_block),
id);
- if (id->transform_lang_insert_block)
- id->transform_lang_insert_block (new_block);
-
/* Remember the remapped block. */
insert_decl_map (id, old_block, new_block);
}
@@ -5473,7 +5470,6 @@ optimize_inline_calls (tree fn)
id.transform_new_cfg = false;
id.transform_return_to_modify = true;
id.transform_parameter = true;
- id.transform_lang_insert_block = NULL;
id.statements_to_fold = new hash_set<gimple *>;
push_gimplify_context ();
@@ -5857,7 +5853,6 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq)
id.transform_new_cfg = false;
id.transform_return_to_modify = false;
id.transform_parameter = false;
- id.transform_lang_insert_block = NULL;
/* Walk the tree once to find local labels. */
memset (&wi, 0, sizeof (wi));
@@ -6252,7 +6247,6 @@ tree_function_versioning (tree old_decl, tree new_decl,
id.transform_new_cfg = true;
id.transform_return_to_modify = false;
id.transform_parameter = false;
- id.transform_lang_insert_block = NULL;
old_entry_block = ENTRY_BLOCK_PTR_FOR_FN
(DECL_STRUCT_FUNCTION (old_decl));
@@ -6541,7 +6535,6 @@ maybe_inline_call_in_expr (tree exp)
id.transform_new_cfg = false;
id.transform_return_to_modify = true;
id.transform_parameter = true;
- id.transform_lang_insert_block = NULL;
/* Make sure not to unshare trees behind the front-end's back
since front-end specific mechanisms may rely on sharing. */
@@ -6613,7 +6606,6 @@ copy_fn (tree fn, tree& parms, tree& result)
id.transform_new_cfg = false;
id.transform_return_to_modify = false;
id.transform_parameter = true;
- id.transform_lang_insert_block = NULL;
/* Make sure not to unshare trees behind the front-end's back
since front-end specific mechanisms may rely on sharing. */
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index ec0e82f..e9d21a4 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -133,9 +133,6 @@ struct copy_body_data
and only in that case will actually remap the type. */
bool dont_remap_vla_if_no_change;
- /* A function to be called when duplicating BLOCK nodes. */
- void (*transform_lang_insert_block) (tree);
-
/* Statements that might be possibly folded. */
hash_set<gimple *> *statements_to_fold;
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 9531d89..8717d65 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -156,57 +156,137 @@ initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write)
}
/* Given REF from the alias oracle, return TRUE if it is a valid
- memory reference for dead store elimination, false otherwise.
+ kill memory reference for dead store elimination, false otherwise.
In particular, the reference must have a known base, known maximum
size, start at a byte offset and have a size that is one or more
bytes. */
static bool
-valid_ao_ref_for_dse (ao_ref *ref)
+valid_ao_ref_kill_for_dse (ao_ref *ref)
{
return (ao_ref_base (ref)
&& known_size_p (ref->max_size)
&& maybe_ne (ref->size, 0)
&& known_eq (ref->max_size, ref->size)
- && known_ge (ref->offset, 0)
- && multiple_p (ref->offset, BITS_PER_UNIT)
- && multiple_p (ref->size, BITS_PER_UNIT));
+ && known_ge (ref->offset, 0));
+}
+
+/* Given REF from the alias oracle, return TRUE if it is a valid
+ load or store memory reference for dead store elimination, false otherwise.
+
+ Unlike for valid_ao_ref_kill_for_dse we can accept writes where max_size
+ is not same as size since we can handle conservatively the larger range. */
+
+static bool
+valid_ao_ref_for_dse (ao_ref *ref)
+{
+ return (ao_ref_base (ref)
+ && known_size_p (ref->max_size)
+ && known_ge (ref->offset, 0));
+}
+
+/* Initialize OFFSET and SIZE to a range known to contain REF
+ where the boundaries are divisible by BITS_PER_UNIT (bit still in bits).
+ Return false if this is impossible. */
+
+static bool
+get_byte_aligned_range_containing_ref (ao_ref *ref, poly_int64 *offset,
+ HOST_WIDE_INT *size)
+{
+ if (!known_size_p (ref->max_size))
+ return false;
+ *offset = aligned_lower_bound (ref->offset, BITS_PER_UNIT);
+ poly_int64 end = aligned_upper_bound (ref->offset + ref->max_size,
+ BITS_PER_UNIT);
+ return (end - *offset).is_constant (size);
+}
+
+/* Initialize OFFSET and SIZE to a range known to be contained REF
+ where the boundaries are divisible by BITS_PER_UNIT (but still in bits).
+ Return false if this is impossible. */
+
+static bool
+get_byte_aligned_range_contained_in_ref (ao_ref *ref, poly_int64 *offset,
+ HOST_WIDE_INT *size)
+{
+ if (!known_size_p (ref->size)
+ || !known_eq (ref->size, ref->max_size))
+ return false;
+ *offset = aligned_upper_bound (ref->offset, BITS_PER_UNIT);
+ poly_int64 end = aligned_lower_bound (ref->offset + ref->max_size,
+ BITS_PER_UNIT);
+ /* For bit accesses we can get -1 here, but also 0 sized kill is not
+ useful. */
+ if (!known_gt (end, *offset))
+ return false;
+ return (end - *offset).is_constant (size);
}
-/* Try to normalize COPY (an ao_ref) relative to REF. Essentially when we are
- done COPY will only refer bytes found within REF. Return true if COPY
- is known to intersect at least one byte of REF. */
+/* Compute byte range (returned iN REF_OFFSET and RET_SIZE) for access COPY
+ inside REF. If KILL is true, then COPY represent a kill and the byte range
+ needs to be fully contained in bit range given by COPY. If KILL is false
+ then the byte range returned must contain the range of COPY. */
static bool
-normalize_ref (ao_ref *copy, ao_ref *ref)
+get_byte_range (ao_ref *copy, ao_ref *ref, bool kill,
+ HOST_WIDE_INT *ret_offset, HOST_WIDE_INT *ret_size)
{
- if (!ordered_p (copy->offset, ref->offset))
+ HOST_WIDE_INT copy_size, ref_size;
+ poly_int64 copy_offset, ref_offset;
+ HOST_WIDE_INT diff;
+
+ /* First translate from bits to bytes, rounding to bigger or smaller ranges
+ as needed. Kills needs to be always rounded to smaller ranges while
+ uses and stores to larger ranges. */
+ if (kill)
+ {
+ if (!get_byte_aligned_range_contained_in_ref (copy, &copy_offset,
+ &copy_size))
+ return false;
+ }
+ else
+ {
+ if (!get_byte_aligned_range_containing_ref (copy, &copy_offset,
+ &copy_size))
+ return false;
+ }
+
+ if (!get_byte_aligned_range_containing_ref (ref, &ref_offset, &ref_size)
+ || !ordered_p (copy_offset, ref_offset))
return false;
+ /* Switch sizes from bits to bytes so we do not need to care about
+ overflows. Offset calculation needs to stay in bits until we compute
+ the difference and can switch to HOST_WIDE_INT. */
+ copy_size /= BITS_PER_UNIT;
+ ref_size /= BITS_PER_UNIT;
+
/* If COPY starts before REF, then reset the beginning of
COPY to match REF and decrease the size of COPY by the
number of bytes removed from COPY. */
- if (maybe_lt (copy->offset, ref->offset))
+ if (maybe_lt (copy_offset, ref_offset))
{
- poly_int64 diff = ref->offset - copy->offset;
- if (maybe_le (copy->size, diff))
+ if (!(ref_offset - copy_offset).is_constant (&diff)
+ || copy_size < diff / BITS_PER_UNIT)
return false;
- copy->size -= diff;
- copy->offset = ref->offset;
+ copy_size -= diff / BITS_PER_UNIT;
+ copy_offset = ref_offset;
}
- poly_int64 diff = copy->offset - ref->offset;
- if (maybe_le (ref->size, diff))
+ if (!(copy_offset - ref_offset).is_constant (&diff)
+ || ref_size <= diff / BITS_PER_UNIT)
return false;
/* If COPY extends beyond REF, chop off its size appropriately. */
- poly_int64 limit = ref->size - diff;
- if (!ordered_p (limit, copy->size))
- return false;
+ HOST_WIDE_INT limit = ref_size - diff / BITS_PER_UNIT;
- if (maybe_gt (copy->size, limit))
- copy->size = limit;
+ if (copy_size > limit)
+ copy_size = limit;
+ *ret_size = copy_size;
+ if (!(copy_offset - ref_offset).is_constant (ret_offset))
+ return false;
+ *ret_offset /= BITS_PER_UNIT;
return true;
}
@@ -214,20 +294,14 @@ normalize_ref (ao_ref *copy, ao_ref *ref)
Verify we have the same base memory address, the write
has a known size and overlaps with REF. */
static void
-clear_live_bytes_for_ref (sbitmap live_bytes, ao_ref *ref, ao_ref write)
+clear_live_bytes_for_ref (sbitmap live_bytes, ao_ref *ref, ao_ref *write)
{
HOST_WIDE_INT start, size;
- if (valid_ao_ref_for_dse (&write)
- && operand_equal_p (write.base, ref->base, OEP_ADDRESS_OF)
- && known_eq (write.size, write.max_size)
- /* normalize_ref modifies write and for that reason write is not
- passed by reference. */
- && normalize_ref (&write, ref)
- && (write.offset - ref->offset).is_constant (&start)
- && write.size.is_constant (&size))
- bitmap_clear_range (live_bytes, start / BITS_PER_UNIT,
- size / BITS_PER_UNIT);
+ if (valid_ao_ref_kill_for_dse (write)
+ && operand_equal_p (write->base, ref->base, OEP_ADDRESS_OF)
+ && get_byte_range (write, ref, true, &start, &size))
+ bitmap_clear_range (live_bytes, start, size);
}
/* Clear any bytes written by STMT from the bitmap LIVE_BYTES. The base
@@ -250,12 +324,12 @@ clear_bytes_written_by (sbitmap live_bytes, gimple *stmt, ao_ref *ref)
if (summary && !interposed)
for (auto kill : summary->kills)
if (kill.get_ao_ref (as_a <gcall *> (stmt), &write))
- clear_live_bytes_for_ref (live_bytes, ref, write);
+ clear_live_bytes_for_ref (live_bytes, ref, &write);
}
if (!initialize_ao_ref_for_dse (stmt, &write))
return;
- clear_live_bytes_for_ref (live_bytes, ref, write);
+ clear_live_bytes_for_ref (live_bytes, ref, &write);
}
/* REF is a memory write. Extract relevant information from it and
@@ -267,9 +341,11 @@ setup_live_bytes_from_ref (ao_ref *ref, sbitmap live_bytes)
{
HOST_WIDE_INT const_size;
if (valid_ao_ref_for_dse (ref)
- && ref->size.is_constant (&const_size)
- && (const_size / BITS_PER_UNIT
- <= param_dse_max_object_size))
+ && ((aligned_upper_bound (ref->offset + ref->max_size, BITS_PER_UNIT)
+ - aligned_lower_bound (ref->offset,
+ BITS_PER_UNIT)).is_constant (&const_size))
+ && (const_size / BITS_PER_UNIT <= param_dse_max_object_size)
+ && const_size > 1)
{
bitmap_clear (live_bytes);
bitmap_set_range (live_bytes, 0, const_size / BITS_PER_UNIT);
@@ -645,24 +721,21 @@ maybe_trim_partially_dead_store (ao_ref *ref, sbitmap live, gimple *stmt)
location. So callers do not see those modifications. */
static bool
-live_bytes_read (ao_ref use_ref, ao_ref *ref, sbitmap live)
+live_bytes_read (ao_ref *use_ref, ao_ref *ref, sbitmap live)
{
/* We have already verified that USE_REF and REF hit the same object.
Now verify that there's actually an overlap between USE_REF and REF. */
HOST_WIDE_INT start, size;
- if (normalize_ref (&use_ref, ref)
- && (use_ref.offset - ref->offset).is_constant (&start)
- && use_ref.size.is_constant (&size))
+ if (get_byte_range (use_ref, ref, false, &start, &size))
{
/* If USE_REF covers all of REF, then it will hit one or more
live bytes. This avoids useless iteration over the bitmap
below. */
- if (start == 0 && known_eq (size, ref->size))
+ if (start == 0 && known_eq (size * 8, ref->size))
return true;
/* Now check if any of the remaining bits in use_ref are set in LIVE. */
- return bitmap_bit_in_range_p (live, start / BITS_PER_UNIT,
- (start + size - 1) / BITS_PER_UNIT);
+ return bitmap_bit_in_range_p (live, start, (start + size - 1));
}
return true;
}
@@ -861,16 +934,18 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
{
/* Handle common cases where we can easily build an ao_ref
structure for USE_STMT and in doing so we find that the
- references hit non-live bytes and thus can be ignored. */
+ references hit non-live bytes and thus can be ignored.
+
+ TODO: We can also use modref summary to handle calls. */
if (byte_tracking_enabled
&& is_gimple_assign (use_stmt))
{
ao_ref use_ref;
ao_ref_init (&use_ref, gimple_assign_rhs1 (use_stmt));
if (valid_ao_ref_for_dse (&use_ref)
- && use_ref.base == ref->base
- && known_eq (use_ref.size, use_ref.max_size)
- && !live_bytes_read (use_ref, ref, live_bytes))
+ && operand_equal_p (use_ref.base, ref->base,
+ OEP_ADDRESS_OF)
+ && !live_bytes_read (&use_ref, ref, live_bytes))
{
/* If this is a store, remember it as we possibly
need to walk the defs uses. */