From 39bb7d015297586294c6416a4db78b50345d2a46 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 5 Oct 2016 11:38:59 +0000 Subject: [PATCH] re PR target/77826 (ICE in decompose, at wide-int.h:928 w/ -m64 -O2 and above) 2016-10-05 Richard Biener PR middle-end/77826 * genmatch.c (dt_operand::gen_match_op): Amend operand_equal_p with types_match for GIMPLE code gen to handle type mismatched constants properly. (dt_operand::gen): Adjust. * match.pd ((X /[ex] A) * A -> X): Properly handle converted and constant A. * gcc.dg/torture/pr77826.c: New testcase. From-SVN: r240776 --- gcc/ChangeLog | 10 ++++++++++ gcc/genmatch.c | 16 +++++++++++----- gcc/match.pd | 10 +++++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/torture/pr77826.c | 12 ++++++++++++ 5 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr77826.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0fd86c50900..43858919d12 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-10-05 Richard Biener + + PR middle-end/77826 + * genmatch.c (dt_operand::gen_match_op): Amend operand_equal_p + with types_match for GIMPLE code gen to handle type mismatched + constants properly. + (dt_operand::gen): Adjust. + * match.pd ((X /[ex] A) * A -> X): Properly handle converted + and constant A. + 2016-10-05 Richard Biener * match.pd (copysign(x, CST) -> [-]abs (x)): New pattern. diff --git a/gcc/genmatch.c b/gcc/genmatch.c index c3f128cd26e..5883ba39420 100644 --- a/gcc/genmatch.c +++ b/gcc/genmatch.c @@ -1562,7 +1562,7 @@ struct dt_operand : public dt_node void gen (FILE *, int, bool); unsigned gen_predicate (FILE *, int, const char *, bool); - unsigned gen_match_op (FILE *, int, const char *); + unsigned gen_match_op (FILE *, int, const char *, bool); unsigned gen_gimple_expr (FILE *, int); unsigned gen_generic_expr (FILE *, int, const char *); @@ -2589,12 +2589,18 @@ dt_operand::gen_predicate (FILE *f, int indent, const char *opname, bool gimple) a capture-match. */ unsigned -dt_operand::gen_match_op (FILE *f, int indent, const char *opname) +dt_operand::gen_match_op (FILE *f, int indent, const char *opname, bool gimple) { char match_opname[20]; match_dop->get_name (match_opname); - fprintf_indent (f, indent, "if (%s == %s || operand_equal_p (%s, %s, 0))\n", - opname, match_opname, opname, match_opname); + if (gimple) + fprintf_indent (f, indent, "if (%s == %s || (operand_equal_p (%s, %s, 0) " + "&& types_match (%s, %s)))\n", + opname, match_opname, opname, match_opname, + opname, match_opname); + else + fprintf_indent (f, indent, "if (%s == %s || operand_equal_p (%s, %s, 0))\n", + opname, match_opname, opname, match_opname); fprintf_indent (f, indent + 2, "{\n"); return 1; } @@ -2991,7 +2997,7 @@ dt_operand::gen (FILE *f, int indent, bool gimple) else if (type == DT_TRUE) ; else if (type == DT_MATCH) - n_braces = gen_match_op (f, indent, opname); + n_braces = gen_match_op (f, indent, opname, gimple); else gcc_unreachable (); diff --git a/gcc/match.pd b/gcc/match.pd index e4b5d4d7556..1d80613fdf8 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1781,9 +1781,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (X /[ex] A) * A -> X. */ (simplify - (mult (convert? (exact_div @0 @1)) @1) - /* Look through a sign-changing conversion. */ - (convert @0)) + (mult (convert1? (exact_div @0 @1)) (convert2? @2)) + /* We cannot use matching captures here, since in the case of + constants we don't see the second conversion. Look through + a sign-changing or widening conversions. */ + (if (operand_equal_p (@1, @2, 0) + && element_precision (@0) <= element_precision (type)) + (convert @0))) /* Canonicalization of binary operations. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 818e5a4be23..fa1f310d694 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-10-05 Richard Biener + + PR middle-end/77826 + * gcc.dg/torture/pr77826.c: New testcase. + 2016-10-05 Richard Biener * gcc.dg/fold-copysign-1.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/torture/pr77826.c b/gcc/testsuite/gcc.dg/torture/pr77826.c new file mode 100644 index 00000000000..13e188f28ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr77826.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +void +fi(unsigned long int *v0, unsigned int ow, int q2) +{ + if (ow + q2 != 0) + if (q2 == 1) + { + *v0 |= q2; + q2 ^= *v0; + } +} -- 2.30.2