This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR71887
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 15 Jul 2016 14:55:00 +0200 (CEST)
- Subject: [PATCH] Fix PR71887
- Authentication-results: sourceware.org; auth=none
Bootstrapped / tested on x86_64-unknown-linux-gnu, applied.
Richard.
2016-07-15 Richard Biener <rguenther@suse.de>
PR tree-optimization/71887
* tree-ssa-phiopt.c (absorbing_element_p): Add rhs arg and
verify it is not zero for division / modulo handling.
(value_replacement): Adjust.
* gcc.dg/torture/pr71887.c: New testcase.
Index: gcc/tree-ssa-phiopt.c
===================================================================
*** gcc/tree-ssa-phiopt.c (revision 238364)
--- gcc/tree-ssa-phiopt.c (working copy)
*************** neutral_element_p (tree_code code, tree
*** 812,818 ****
/* Returns true if ARG is an absorbing element for operation CODE. */
static bool
! absorbing_element_p (tree_code code, tree arg, bool right)
{
switch (code)
{
--- 812,818 ----
/* Returns true if ARG is an absorbing element for operation CODE. */
static bool
! absorbing_element_p (tree_code code, tree arg, bool right, tree rval)
{
switch (code)
{
*************** absorbing_element_p (tree_code code, tre
*** 827,832 ****
--- 827,834 ----
case RSHIFT_EXPR:
case LROTATE_EXPR:
case RROTATE_EXPR:
+ return !right && integer_zerop (arg);
+
case TRUNC_DIV_EXPR:
case CEIL_DIV_EXPR:
case FLOOR_DIV_EXPR:
*************** absorbing_element_p (tree_code code, tre
*** 836,842 ****
case CEIL_MOD_EXPR:
case FLOOR_MOD_EXPR:
case ROUND_MOD_EXPR:
! return !right && integer_zerop (arg);
default:
return false;
--- 838,846 ----
case CEIL_MOD_EXPR:
case FLOOR_MOD_EXPR:
case ROUND_MOD_EXPR:
! return (!right
! && integer_zerop (arg)
! && tree_single_nonzero_warnv_p (rval, NULL));
default:
return false;
*************** value_replacement (basic_block cond_bb,
*** 1010,1018 ****
&& neutral_element_p (code_def, cond_rhs, false))
|| (operand_equal_for_phi_arg_p (arg1, cond_rhs)
&& ((operand_equal_for_phi_arg_p (rhs2, cond_lhs)
! && absorbing_element_p (code_def, cond_rhs, true))
|| (operand_equal_for_phi_arg_p (rhs1, cond_lhs)
! && absorbing_element_p (code_def, cond_rhs, false))))))
{
gsi = gsi_for_stmt (cond);
if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
--- 1014,1023 ----
&& neutral_element_p (code_def, cond_rhs, false))
|| (operand_equal_for_phi_arg_p (arg1, cond_rhs)
&& ((operand_equal_for_phi_arg_p (rhs2, cond_lhs)
! && absorbing_element_p (code_def, cond_rhs, true, rhs2))
|| (operand_equal_for_phi_arg_p (rhs1, cond_lhs)
! && absorbing_element_p (code_def,
! cond_rhs, false, rhs2))))))
{
gsi = gsi_for_stmt (cond);
if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
Index: gcc/testsuite/gcc.dg/torture/pr71887.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr71887.c (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr71887.c (working copy)
***************
*** 0 ****
--- 1,11 ----
+ /* { dg-do run } */
+
+ char a;
+ int b;
+
+ int main ()
+ {
+ unsigned char c = a, d = a;
+ b = d == 0 ? c : c % d;
+ return 0;
+ }