Hi!
I've bootstrapped/regtested following patches on x86_64-linux and i686-linux
on gcc-6-branch and committed them to 6.x.
Jakub
2017-02-15 Jakub Jelinek <[email protected]>
Backported from mainline
2017-01-17 Kito Cheng <[email protected]>
Kuan-Lin Chen <[email protected]>
PR target/79079
* internal-fn.c (expand_mul_overflow): Use convert_modes instead of
gen_lowpart.
--- gcc/internal-fn.c (revision 244538)
+++ gcc/internal-fn.c (revision 244539)
@@ -1483,8 +1483,8 @@ expand_mul_overflow (location_t loc, tre
res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
NULL_RTX, uns);
- hipart = gen_lowpart (mode, hipart);
- res = gen_lowpart (mode, res);
+ hipart = convert_modes (mode, wmode, hipart, uns);
+ res = convert_modes (mode, wmode, res, uns);
if (uns)
/* For the unsigned multiplication, there was overflow if
HIPART is non-zero. */
@@ -1517,16 +1517,16 @@ expand_mul_overflow (location_t loc, tre
unsigned int hprec = GET_MODE_PRECISION (hmode);
rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
NULL_RTX, uns);
- hipart0 = gen_lowpart (hmode, hipart0);
- rtx lopart0 = gen_lowpart (hmode, op0);
+ hipart0 = convert_modes (hmode, mode, hipart0, uns);
+ rtx lopart0 = convert_modes (hmode, mode, op0, uns);
rtx signbit0 = const0_rtx;
if (!uns)
signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
NULL_RTX, 0);
rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
NULL_RTX, uns);
- hipart1 = gen_lowpart (hmode, hipart1);
- rtx lopart1 = gen_lowpart (hmode, op1);
+ hipart1 = convert_modes (hmode, mode, hipart1, uns);
+ rtx lopart1 = convert_modes (hmode, mode, op1, uns);
rtx signbit1 = const0_rtx;
if (!uns)
signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
@@ -1717,11 +1717,12 @@ expand_mul_overflow (location_t loc, tre
if (loxhi >> (bitsize / 2) == 0 (if uns). */
rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
NULL_RTX, 0);
- hipartloxhi = gen_lowpart (hmode, hipartloxhi);
+ hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
rtx signbitloxhi = const0_rtx;
if (!uns)
signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
- gen_lowpart (hmode, loxhi),
+ convert_modes (hmode, mode,
+ loxhi, 0),
hprec - 1, NULL_RTX, 0);
do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
@@ -1731,7 +1732,8 @@ expand_mul_overflow (location_t loc, tre
/* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */
rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
NULL_RTX, 1);
- tem = convert_modes (mode, hmode, gen_lowpart (hmode, lo0xlo1), 1);
+ tem = convert_modes (mode, hmode,
+ convert_modes (hmode, mode, lo0xlo1, 1), 1);
tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
1, OPTAB_DIRECT);
2017-02-15 Jakub Jelinek <[email protected]>
Backported from mainline
2017-01-31 Jakub Jelinek <[email protected]>
PR tree-optimization/79267
* value-prof.c (gimple_ic): Only drop lhs for noreturn calls
if should_remove_lhs_p is true.
* g++.dg/opt/pr79267.C: New test.
--- gcc/value-prof.c (revision 245052)
+++ gcc/value-prof.c (revision 245053)
@@ -1376,7 +1376,13 @@ gimple_ic (gcall *icall_stmt, struct cgr
gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
dflags = flags_from_decl_or_type (direct_call->decl);
if ((dflags & ECF_NORETURN) != 0)
- gimple_call_set_lhs (dcall_stmt, NULL_TREE);
+ {
+ tree lhs = gimple_call_lhs (dcall_stmt);
+ if (lhs
+ && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST
+ && !TREE_ADDRESSABLE (TREE_TYPE (lhs)))
+ gimple_call_set_lhs (dcall_stmt, NULL_TREE);
+ }
gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
/* Fix CFG. */
--- gcc/testsuite/g++.dg/opt/pr79267.C (nonexistent)
+++ gcc/testsuite/g++.dg/opt/pr79267.C (revision 245053)
@@ -0,0 +1,69 @@
+// PR tree-optimization/79267
+// { dg-do compile }
+// { dg-options "-O3" }
+
+struct A { A (int); };
+struct B
+{
+ virtual void av () = 0;
+ void aw ();
+ void h () { av (); aw (); }
+};
+template <class T> struct G : B
+{
+ T ba;
+ G (int, T) : ba (0) {}
+ void av () { ba (0); }
+};
+struct I
+{
+ B *bc;
+ template <class j, class T> I (j, T) try { G<T> (0, 0); } catch (...) {}
+ ~I () { bc->h (); }
+};
+template <class M> struct C { typedef M *i; };
+template <class M> struct J
+{
+ J ();
+ template <class O, class T> J (O, T p2) : be (0, p2) {}
+ typename C<M>::i operator-> ();
+ I be;
+};
+struct H : A { H () : A (0) {} };
+struct D { J<int> d; void q (); };
+template <typename = int> class bs;
+int z;
+
+void
+foo (int p1, int *, int)
+{
+ if (p1 == 0)
+ throw H ();
+}
+
+D bar ();
+template <typename T> struct L
+{
+ struct K { K (int); void operator() (int *) { bar ().q (); } };
+ static J<T> bp () { bq (0); }
+ template <typename br> static void bq (br) { J<T> (0, K (0)); }
+};
+struct F
+{
+ virtual J<int> x (int) { foo (0, 0, 0); J<bs<> > (L<bs<> >::bp ()); }
+};
+
+void
+baz ()
+{
+ if (z)
+ {
+ J<F> d, e;
+ d->x (0);
+ e->x (0);
+ }
+ J<F> v, i, j;
+ v->x (0);
+ i->x (0);
+ j->x (0);
+}
2017-02-15 Jakub Jelinek <[email protected]>
Backported from mainline
2017-02-02 Jakub Jelinek <[email protected]>
PR target/79197
* config/rs6000/rs6000.md (*fixuns_trunc<mode>di2_fctiduz): Rename to
...
(fixuns_trunc<mode>di2): ... this, remove previous expander. Put all
conditions on a single line.
* gcc.target/powerpc/pr79197.c: New test.
* gcc.c-torture/compile/pr79197.c: New test.
--- gcc/config/rs6000/rs6000.md (revision 245119)
+++ gcc/config/rs6000/rs6000.md (revision 245120)
@@ -5429,17 +5429,10 @@ (define_insn_and_split "fixuns_trunc<mod
[(set_attr "length" "12")
(set_attr "type" "fp")])
-(define_expand "fixuns_trunc<mode>di2"
- [(set (match_operand:DI 0 "register_operand" "")
- (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
- "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
- "")
-
-(define_insn "*fixuns_trunc<mode>di2_fctiduz"
+(define_insn "fixuns_trunc<mode>di2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
(unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
- "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
- && TARGET_FCTIDUZ"
+ "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ"
"@
fctiduz %0,%1
xscvdpuxds %x0,%x1"
--- gcc/testsuite/gcc.target/powerpc/pr79197.c (nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/pr79197.c (revision 245120)
@@ -0,0 +1,11 @@
+/* PR target/79197 */
+/* { dg-do compile } */
+/* { dg-options "-O0 -mno-popcntd" } */
+
+unsigned a;
+
+void
+foo (void)
+{
+ a = *(double *) (__UINTPTR_TYPE__) 0x400000;
+}
--- gcc/testsuite/gcc.c-torture/compile/pr79197.c (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr79197.c (revision 245120)
@@ -0,0 +1,10 @@
+/* PR target/79197 */
+
+unsigned long b;
+
+unsigned long
+foo (float *a, float *x)
+{
+ __builtin_memcpy (a, x, sizeof (float));
+ return *a;
+}
2017-02-15 Jakub Jelinek <[email protected]>
Backported from mainline
2017-02-04 Jakub Jelinek <[email protected]>
PR tree-optimization/79338
* tree-parloops.c (gather_scalar_reductions): Don't call
vect_analyze_loop_form for loop->inner before destroying loop's
loop_vinfo.
--- gcc/tree-parloops.c (revision 245182)
+++ gcc/tree-parloops.c (revision 245183)
@@ -2513,8 +2513,8 @@ gather_scalar_reductions (loop_p loop, r
{
gphi_iterator gsi;
loop_vec_info simple_loop_info;
- loop_vec_info simple_inner_loop_info = NULL;
- bool allow_double_reduc = true;
+ auto_vec<gphi *, 4> double_reduc_phis;
+ auto_vec<gimple *, 4> double_reduc_stmts;
if (!stmt_vec_info_vec.exists ())
init_stmt_vec_info_vec ();
@@ -2544,43 +2544,55 @@ gather_scalar_reductions (loop_p loop, r
if (double_reduc)
{
- if (!allow_double_reduc
- || loop->inner->inner != NULL)
+ if (loop->inner->inner != NULL)
continue;
- if (!simple_inner_loop_info)
- {
- simple_inner_loop_info = vect_analyze_loop_form (loop->inner);
- if (!simple_inner_loop_info)
- {
- allow_double_reduc = false;
- continue;
- }
- }
-
- use_operand_p use_p;
- gimple *inner_stmt;
- bool single_use_p = single_imm_use (res, &use_p, &inner_stmt);
- gcc_assert (single_use_p);
- if (gimple_code (inner_stmt) != GIMPLE_PHI)
- continue;
- gphi *inner_phi = as_a <gphi *> (inner_stmt);
- if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi),
- &iv, true))
- continue;
-
- gimple *inner_reduc_stmt
- = vect_force_simple_reduction (simple_inner_loop_info, inner_phi,
- true, &double_reduc, true);
- gcc_assert (!double_reduc);
- if (inner_reduc_stmt == NULL)
- continue;
+ double_reduc_phis.safe_push (phi);
+ double_reduc_stmts.safe_push (reduc_stmt);
+ continue;
}
build_new_reduction (reduction_list, reduc_stmt, phi);
}
destroy_loop_vec_info (simple_loop_info, true);
- destroy_loop_vec_info (simple_inner_loop_info, true);
+
+ if (!double_reduc_phis.is_empty ())
+ {
+ simple_loop_info = vect_analyze_loop_form (loop->inner);
+ if (simple_loop_info)
+ {
+ gphi *phi;
+ unsigned int i;
+
+ FOR_EACH_VEC_ELT (double_reduc_phis, i, phi)
+ {
+ affine_iv iv;
+ tree res = PHI_RESULT (phi);
+ bool double_reduc;
+
+ use_operand_p use_p;
+ gimple *inner_stmt;
+ bool single_use_p = single_imm_use (res, &use_p, &inner_stmt);
+ gcc_assert (single_use_p);
+ if (gimple_code (inner_stmt) != GIMPLE_PHI)
+ continue;
+ gphi *inner_phi = as_a <gphi *> (inner_stmt);
+ if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi),
+ &iv, true))
+ continue;
+
+ gimple *inner_reduc_stmt
+ = vect_force_simple_reduction (simple_loop_info, inner_phi,
+ true, &double_reduc, true);
+ gcc_assert (!double_reduc);
+ if (inner_reduc_stmt == NULL)
+ continue;
+
+ build_new_reduction (reduction_list, double_reduc_stmts[i], phi);
+ }
+ destroy_loop_vec_info (simple_loop_info, true);
+ }
+ }
gather_done:
/* Release the claim on gimple_uid. */
2017-02-15 Jakub Jelinek <[email protected]>
Backported from mainline
2017-02-06 Jakub Jelinek <[email protected]>
PR c++/79377
* tree.c (build_min_non_dep_op_overload): For POST{INC,DEC}REMENT_EXPR
allow one fewer than expected arguments if flag_permissive.
* g++.dg/lookup/pr79377.C: New test.
--- gcc/cp/tree.c (revision 245218)
+++ gcc/cp/tree.c (revision 245219)
@@ -2938,8 +2938,10 @@ build_min_non_dep_op_overload (enum tree
nargs = call_expr_nargs (non_dep);
expected_nargs = cp_tree_code_length (op);
- if (op == POSTINCREMENT_EXPR
- || op == POSTDECREMENT_EXPR)
+ if ((op == POSTINCREMENT_EXPR
+ || op == POSTDECREMENT_EXPR)
+ /* With -fpermissive non_dep could be operator++(). */
+ && (!flag_permissive || nargs != expected_nargs))
expected_nargs += 1;
gcc_assert (nargs == expected_nargs);
--- gcc/testsuite/g++.dg/lookup/pr79377.C (nonexistent)
+++ gcc/testsuite/g++.dg/lookup/pr79377.C (revision 245219)
@@ -0,0 +1,36 @@
+// PR c++/79377
+// { dg-do run }
+// { dg-options "-fpermissive" }
+
+struct A
+{
+ A () : a (0) {}
+ A& operator++ () { ++a; ++c; return *this; }
+ int a;
+ static int c;
+};
+
+int A::c = 0;
+
+template <typename>
+void
+foo (A& a)
+{
+ a++; // { dg-warning "trying prefix operator instead" }
+ if (A::c != 3 || a.a != 3) __builtin_abort ();
+ ++a;
+ if (A::c != 4 || a.a != 4) __builtin_abort ();
+}
+
+int
+main ()
+{
+ A a;
+ if (A::c != 0 || a.a != 0) __builtin_abort ();
+ ++a;
+ if (A::c != 1 || a.a != 1) __builtin_abort ();
+ a++; // { dg-warning "trying prefix operator instead" }
+ if (A::c != 2 || a.a != 2) __builtin_abort ();
+ foo<int> (a);
+ if (A::c != 4 || a.a != 4) __builtin_abort ();
+}
2017-02-15 Jakub Jelinek <[email protected]>
Backported from mainline
2017-02-07 Jakub Jelinek <[email protected]>
Richard Biener <[email protected]>
PR middle-end/79399
* ira-int.h (struct target_ira_int): Change x_max_struct_costs_size
type from int to size_t.
* ira-costs.c (struct_costs_size): Change type from int to size_t.
--- gcc/ira-int.h (revision 245255)
+++ gcc/ira-int.h (revision 245256)
@@ -782,7 +782,7 @@ struct target_ira_int {
/* Initialized once. It is a maximal possible size of the allocated
struct costs. */
- int x_max_struct_costs_size;
+ size_t x_max_struct_costs_size;
/* Allocated and initialized once, and used to initialize cost values
for each insn. */
--- gcc/ira-costs.c (revision 245255)
+++ gcc/ira-costs.c (revision 245256)
@@ -74,7 +74,7 @@ static struct costs *costs;
static struct costs *total_allocno_costs;
/* It is the current size of struct costs. */
-static int struct_costs_size;
+static size_t struct_costs_size;
/* Return pointer to structure containing costs of allocno or pseudo
with given NUM in array ARR. */
2017-02-15 Jakub Jelinek <[email protected]>
Backported from mainline
2017-02-09 Jakub Jelinek <[email protected]>
PR c/79431
* gimplify.c (gimplify_adjust_omp_clauses): Ignore
"omp declare target link" attribute unless is_global_var.
* omp-low.c (find_link_var_op): Likewise.
* c-parser.c (c_parser_omp_declare_target): Don't invoke
symtab_node::get on automatic variables.
* parser.c (cp_parser_oacc_declare): Formatting fix.
(cp_parser_omp_declare_target): Don't invoke symtab_node::get on
automatic variables.
* c-c++-common/gomp/pr79431.c: New test.
--- gcc/gimplify.c (revision 245301)
+++ gcc/gimplify.c (revision 245302)
@@ -8938,8 +8938,9 @@ gimplify_adjust_omp_clauses (gimple_seq
if ((ctx->region_type & ORT_TARGET) != 0
&& !(n->value & GOVD_SEEN)
&& GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
- && !lookup_attribute ("omp declare target link",
- DECL_ATTRIBUTES (decl)))
+ && (!is_global_var (decl)
+ || !lookup_attribute ("omp declare target link",
+ DECL_ATTRIBUTES (decl))))
{
remove = true;
/* For struct element mapping, if struct is never referenced
--- gcc/omp-low.c (revision 245301)
+++ gcc/omp-low.c (revision 245302)
@@ -19890,7 +19890,9 @@ find_link_var_op (tree *tp, int *walk_su
{
tree t = *tp;
- if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t)
+ if (TREE_CODE (t) == VAR_DECL
+ && DECL_HAS_VALUE_EXPR_P (t)
+ && is_global_var (t)
&& lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (t)))
{
*walk_subtrees = 0;
--- gcc/c/c-parser.c (revision 245301)
+++ gcc/c/c-parser.c (revision 245302)
@@ -16849,8 +16849,11 @@ c_parser_omp_declare_target (c_parser *p
}
if (!at1)
{
- symtab_node *node = symtab_node::get (t);
DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
+ continue;
+
+ symtab_node *node = symtab_node::get (t);
if (node != NULL)
{
node->offloadable = 1;
--- gcc/cp/parser.c (revision 245301)
+++ gcc/cp/parser.c (revision 245302)
@@ -36230,7 +36230,7 @@ cp_parser_oacc_declare (cp_parser *parse
id = get_identifier ("omp declare target");
DECL_ATTRIBUTES (decl)
- = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
+ = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
if (global_bindings_p ())
{
symtab_node *node = symtab_node::get (decl);
@@ -36770,8 +36770,11 @@ cp_parser_omp_declare_target (cp_parser
}
if (!at1)
{
- symtab_node *node = symtab_node::get (t);
DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
+ continue;
+
+ symtab_node *node = symtab_node::get (t);
if (node != NULL)
{
node->offloadable = 1;
--- gcc/testsuite/c-c++-common/gomp/pr79431.c (nonexistent)
+++ gcc/testsuite/c-c++-common/gomp/pr79431.c (revision 245302)
@@ -0,0 +1,8 @@
+/* PR c/79431 */
+
+void
+foo (void)
+{
+ int a;
+ #pragma omp declare target (a)
+}
2017-02-15 Jakub Jelinek <[email protected]>
Backported from mainline
2017-02-09 Jakub Jelinek <[email protected]>
PR c++/79429
* parser.c (cp_parser_omp_ordered): Don't check for non-pragma_stmt
non-pragma_compound context here.
(cp_parser_omp_target): Likewise.
(cp_parser_pragma): Don't call push_omp_privatization_clauses and
parsing for ordered and target omp pragmas in non-pragma_stmt
non-pragma_compound contexts.
* c-c++-common/gomp/pr79429.c: New test.
* g++.dg/gomp/pr79429.C: New test.
--- gcc/cp/parser.c (revision 245302)
+++ gcc/cp/parser.c (revision 245303)
@@ -34934,13 +34934,6 @@ cp_parser_omp_ordered (cp_parser *parser
{
location_t loc = pragma_tok->location;
- if (context != pragma_stmt && context != pragma_compound)
- {
- cp_parser_error (parser, "expected declaration specifiers");
- cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return false;
- }
-
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
@@ -35846,13 +35839,6 @@ cp_parser_omp_target (cp_parser *parser,
{
tree *pc = NULL, stmt;
- if (context != pragma_stmt && context != pragma_compound)
- {
- cp_parser_error (parser, "expected declaration specifiers");
- cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return false;
- }
-
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
@@ -38283,12 +38269,16 @@ cp_parser_pragma (cp_parser *parser, enu
return true;
case PRAGMA_OMP_ORDERED:
+ if (context != pragma_stmt && context != pragma_compound)
+ goto bad_stmt;
stmt = push_omp_privatization_clauses (false);
ret = cp_parser_omp_ordered (parser, pragma_tok, context, if_p);
pop_omp_privatization_clauses (stmt);
return ret;
case PRAGMA_OMP_TARGET:
+ if (context != pragma_stmt && context != pragma_compound)
+ goto bad_stmt;
stmt = push_omp_privatization_clauses (false);
ret = cp_parser_omp_target (parser, pragma_tok, context, if_p);
pop_omp_privatization_clauses (stmt);
--- gcc/testsuite/g++.dg/gomp/pr79429.C (nonexistent)
+++ gcc/testsuite/g++.dg/gomp/pr79429.C (revision 245303)
@@ -0,0 +1,3 @@
+// PR c++/79429
+
+#pragma omp ordered // { dg-error "expected declaration specifiers" }
--- gcc/testsuite/c-c++-common/gomp/pr79429.c (nonexistent)
+++ gcc/testsuite/c-c++-common/gomp/pr79429.c (revision 245303)
@@ -0,0 +1,3 @@
+/* PR c++/79429 */
+
+#pragma omp target /* { dg-error "expected declaration specifiers" } */
2017-02-15 Jakub Jelinek <[email protected]>
Backported from mainline
2017-02-10 Jakub Jelinek <[email protected]>
PR tree-optimization/79411
* tree-ssa-reassoc.c (is_reassociable_op): Return false if
stmt operands are SSA_NAMEs used in abnormal phis.
(can_reassociate_p): Return false if op is SSA_NAME used in abnormal
phis.
* gcc.c-torture/compile/pr79411.c: New test.
--- gcc/tree-ssa-reassoc.c (revision 245323)
+++ gcc/tree-ssa-reassoc.c (revision 245324)
@@ -605,7 +605,18 @@ is_reassociable_op (gimple *stmt, enum t
if (is_gimple_assign (stmt)
&& gimple_assign_rhs_code (stmt) == code
&& has_single_use (gimple_assign_lhs (stmt)))
- return true;
+ {
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree rhs2 = gimple_assign_rhs1 (stmt);
+ if (TREE_CODE (rhs1) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
+ return false;
+ if (rhs2
+ && TREE_CODE (rhs2) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2))
+ return false;
+ return true;
+ }
return false;
}
@@ -4989,6 +5000,8 @@ static bool
can_reassociate_p (tree op)
{
tree type = TREE_TYPE (op);
+ if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
+ return false;
if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))
|| NON_SAT_FIXED_POINT_TYPE_P (type)
|| (flag_associative_math && FLOAT_TYPE_P (type)))
--- gcc/testsuite/gcc.c-torture/compile/pr79411.c (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr79411.c (revision 245324)
@@ -0,0 +1,22 @@
+/* PR tree-optimization/79411 */
+
+typedef struct __jmp_buf_tag { char buf[1024]; } jmp_buf[1];
+extern int setjmp (jmp_buf);
+extern int bar (unsigned int *);
+extern jmp_buf *baz (void);
+struct C { int c1; unsigned int c2, c3, c4; };
+
+void
+foo (struct C *x, const int *y, unsigned int *z, unsigned int e, unsigned int
g)
+{
+ unsigned int d = 0;
+ unsigned long f;
+ setjmp (*baz ());
+ f = 1 + d;
+ if ((x->c1 || x->c2) && g && (!e || d >= 8))
+ d = 16;
+ else
+ d = 8;
+ if ((!x->c3 && !x->c4 || *y == 0) && !e && bar (z))
+ *z = 1 + f;
+}