From 52af5e483d2aab891a364929dedc221771ac1a52 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 9 Dec 2016 10:21:36 +0100 Subject: [PATCH] re PR middle-end/78726 (Incorrect unsigned arithmetic optimization) PR tree-optimization/78726 * tree-ssa-reassoc.c (make_new_ssa_for_def): Add OPCODE and OP argument. For lhs uses in debug stmts, don't replace lhs with new_lhs, but with a debug temp set to new_lhs opcode op. (make_new_ssa_for_all_defs): Add OPCODE argument, pass OPCODE and OP down to make_new_ssa_for_def. (zero_one_operation): Call make_new_ssa_for_all_defs even when stmts_to_fix is empty, if *def has not changed yet. Pass OPCODE to make_new_ssa_for_all_defs. * gcc.c-torture/execute/pr78726.c: New test. * gcc.dg/guality/pr78726.c: New test. From-SVN: r243476 --- gcc/ChangeLog | 12 ++++++ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.c-torture/execute/pr78726.c | 23 ++++++++++++ gcc/testsuite/gcc.dg/guality/pr78726.c | 30 +++++++++++++++ gcc/tree-ssa-reassoc.c | 37 +++++++++++++++---- 5 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr78726.c create mode 100644 gcc/testsuite/gcc.dg/guality/pr78726.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e75a77803e5..2ccc00fccae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2016-12-09 Jakub Jelinek + + PR tree-optimization/78726 + * tree-ssa-reassoc.c (make_new_ssa_for_def): Add OPCODE and OP + argument. For lhs uses in debug stmts, don't replace lhs with + new_lhs, but with a debug temp set to new_lhs opcode op. + (make_new_ssa_for_all_defs): Add OPCODE argument, pass OPCODE and + OP down to make_new_ssa_for_def. + (zero_one_operation): Call make_new_ssa_for_all_defs even when + stmts_to_fix is empty, if *def has not changed yet. Pass + OPCODE to make_new_ssa_for_all_defs. + 2016-12-08 Martin Sebor PR c/78284 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 80166f282a7..3ea10f27886 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-12-09 Jakub Jelinek + + PR tree-optimization/78726 + * gcc.c-torture/execute/pr78726.c: New test. + * gcc.dg/guality/pr78726.c: New test. + 2016-12-08 Martin Sebor PR c/78284 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr78726.c b/gcc/testsuite/gcc.c-torture/execute/pr78726.c new file mode 100644 index 00000000000..9c29234b7c7 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr78726.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/78726 */ + +unsigned char b = 36, c = 173; +unsigned int d; + +__attribute__((noinline, noclone)) void +foo (void) +{ + unsigned a = ~b; + d = a * c * c + 1023094746U * a; +} + +int +main () +{ + if (__SIZEOF_INT__ != 4 || __CHAR_BIT__ != 8) + return 0; + asm volatile ("" : : "g" (&b), "g" (&c) : "memory"); + foo (); + if (d != 799092689U) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/guality/pr78726.c b/gcc/testsuite/gcc.dg/guality/pr78726.c new file mode 100644 index 00000000000..dc6b386be1d --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/pr78726.c @@ -0,0 +1,30 @@ +/* PR tree-optimization/78726 */ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +#include "../nop.h" + +unsigned char b = 36, c = 173; +unsigned int d; + +__attribute__((noinline, noclone)) void +foo (void) +{ + unsigned a = ~b; + unsigned d1 = a * c; /* { dg-final { gdb-test 21 "d1" "~36U * 173" } } */ + unsigned d2 = d1 * c; /* { dg-final { gdb-test 21 "d2" "~36U * 173 * 173" } } */ + unsigned d3 = 1023094746 * a; /* { dg-final { gdb-test 21 "d3" "~36U * 1023094746" } } */ + d = d2 + d3; + unsigned d4 = d1 * 2; /* { dg-final { gdb-test 21 "d4" "~36U * 173 * 2" } } */ + unsigned d5 = d2 * 2; /* { dg-final { gdb-test 21 "d5" "~36U * 173 * 173 * 2" } } */ + unsigned d6 = d3 * 2; /* { dg-final { gdb-test 21 "d6" "~36U * 1023094746 * 2" } } */ + asm (NOP : : : "memory"); +} + +int +main () +{ + asm volatile ("" : : "g" (&b), "g" (&c) : "memory"); + foo (); + return 0; +} diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index f781c5ff28c..b0158368931 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -1153,12 +1153,12 @@ decrement_power (gimple *stmt) SSA. Also return the new SSA. */ static tree -make_new_ssa_for_def (gimple *stmt) +make_new_ssa_for_def (gimple *stmt, enum tree_code opcode, tree op) { gimple *use_stmt; use_operand_p use; imm_use_iterator iter; - tree new_lhs; + tree new_lhs, new_debug_lhs = NULL_TREE; tree lhs = gimple_get_lhs (stmt); new_lhs = make_ssa_name (TREE_TYPE (lhs)); @@ -1167,8 +1167,28 @@ make_new_ssa_for_def (gimple *stmt) /* Also need to update GIMPLE_DEBUGs. */ FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs) { + tree repl = new_lhs; + if (is_gimple_debug (use_stmt)) + { + if (new_debug_lhs == NULL_TREE) + { + new_debug_lhs = make_node (DEBUG_EXPR_DECL); + gdebug *def_temp + = gimple_build_debug_bind (new_debug_lhs, + build2 (opcode, TREE_TYPE (lhs), + new_lhs, op), + stmt); + DECL_ARTIFICIAL (new_debug_lhs) = 1; + TREE_TYPE (new_debug_lhs) = TREE_TYPE (lhs); + SET_DECL_MODE (new_debug_lhs, TYPE_MODE (TREE_TYPE (lhs))); + gimple_set_uid (def_temp, gimple_uid (stmt)); + gimple_stmt_iterator gsi = gsi_for_stmt (stmt); + gsi_insert_after (&gsi, def_temp, GSI_SAME_STMT); + } + repl = new_debug_lhs; + } FOR_EACH_IMM_USE_ON_STMT (use, iter) - SET_USE (use, new_lhs); + SET_USE (use, repl); update_stmt (use_stmt); } return new_lhs; @@ -1179,7 +1199,7 @@ make_new_ssa_for_def (gimple *stmt) if *DEF is not OP. */ static void -make_new_ssa_for_all_defs (tree *def, tree op, +make_new_ssa_for_all_defs (tree *def, enum tree_code opcode, tree op, vec &stmts_to_fix) { unsigned i; @@ -1189,10 +1209,10 @@ make_new_ssa_for_all_defs (tree *def, tree op, && TREE_CODE (*def) == SSA_NAME && (stmt = SSA_NAME_DEF_STMT (*def)) && gimple_code (stmt) != GIMPLE_NOP) - *def = make_new_ssa_for_def (stmt); + *def = make_new_ssa_for_def (stmt, opcode, op); FOR_EACH_VEC_ELT (stmts_to_fix, i, stmt) - make_new_ssa_for_def (stmt); + make_new_ssa_for_def (stmt, opcode, op); } /* Find the single immediate use of STMT's LHS, and replace it @@ -1232,6 +1252,7 @@ propagate_op_to_single_use (tree op, gimple *stmt, tree *def) static void zero_one_operation (tree *def, enum tree_code opcode, tree op) { + tree orig_def = *def; gimple *stmt = SSA_NAME_DEF_STMT (*def); /* PR72835 - Record the stmt chain that has to be updated such that we dont use the same LHS when the values computed are different. */ @@ -1335,8 +1356,8 @@ zero_one_operation (tree *def, enum tree_code opcode, tree op) } while (1); - if (stmts_to_fix.length () > 0) - make_new_ssa_for_all_defs (def, op, stmts_to_fix); + if (stmts_to_fix.length () > 0 || *def == orig_def) + make_new_ssa_for_all_defs (def, opcode, op, stmts_to_fix); } /* Returns true if statement S1 dominates statement S2. Like -- 2.30.2