re PR tree-optimization/81661 (ICE in gimplify_modify_expr, at gimplify.c:5638)

PR tree-optimization/81661
	PR tree-optimization/84117
	* tree-eh.h (rewrite_to_non_trapping_overflow): Declare.
	* tree-eh.c: Include gimplify.h.
	(find_trapping_overflow, replace_trapping_overflow,
	rewrite_to_non_trapping_overflow): New functions.
	* tree-vect-loop.c: Include tree-eh.h.
	(vect_get_loop_niters): Use rewrite_to_non_trapping_overflow.
	* tree-data-ref.c: Include tree-eh.h.
	(get_segment_min_max): Use rewrite_to_non_trapping_overflow.

	* gcc.dg/pr81661.c: New test.
	* gfortran.dg/pr84117.f90: New test.

From-SVN: r257284
This commit is contained in:
Jakub Jelinek 2018-02-01 11:08:26 +01:00 committed by Jakub Jelinek
parent eae4d8fbb5
commit 31b6733b16
8 changed files with 132 additions and 2 deletions

View File

@ -1,3 +1,16 @@
2018-02-01 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/81661
PR tree-optimization/84117
* tree-eh.h (rewrite_to_non_trapping_overflow): Declare.
* tree-eh.c: Include gimplify.h.
(find_trapping_overflow, replace_trapping_overflow,
rewrite_to_non_trapping_overflow): New functions.
* tree-vect-loop.c: Include tree-eh.h.
(vect_get_loop_niters): Use rewrite_to_non_trapping_overflow.
* tree-data-ref.c: Include tree-eh.h.
(get_segment_min_max): Use rewrite_to_non_trapping_overflow.
2018-01-31 Uros Bizjak <ubizjak@gmail.com>
PR rtl-optimization/84123

View File

@ -1,3 +1,10 @@
2018-02-01 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/81661
PR tree-optimization/84117
* gcc.dg/pr81661.c: New test.
* gfortran.dg/pr84117.f90: New test.
2018-02-01 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/83705

View File

@ -0,0 +1,12 @@
/* PR tree-optimization/81661 */
/* { dg-do compile } */
/* { dg-options "-O3 -ftrapv" } */
int a, b, c;
void
foo (void)
{
while (a + c > b)
a--;
}

View File

@ -0,0 +1,7 @@
! PR tree-optimization/84117
! { dg-do compile }
! { dg-options "-O3 -ftrapv" }
FUNCTION pw_integral_aa ( cc ) RESULT ( integral_value )
COMPLEX(KIND=8), DIMENSION(:), POINTER :: cc
integral_value = accurate_sum ( CONJG ( cc (:) ) * cc (:) )
END FUNCTION pw_integral_aa

View File

@ -98,6 +98,7 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "tree-vrp.h"
#include "tree-ssanames.h"
#include "tree-eh.h"
static struct datadep_stats
{
@ -1790,7 +1791,8 @@ get_segment_min_max (const dr_with_seg_len &d, tree *seg_min_out,
tree addr_base = fold_build_pointer_plus (DR_BASE_ADDRESS (d.dr),
DR_OFFSET (d.dr));
addr_base = fold_build_pointer_plus (addr_base, DR_INIT (d.dr));
tree seg_len = fold_convert (sizetype, d.seg_len);
tree seg_len
= fold_convert (sizetype, rewrite_to_non_trapping_overflow (d.seg_len));
tree min_reach = fold_build3 (COND_EXPR, sizetype, neg_step,
seg_len, size_zero_node);

View File

@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
#include "gimplify.h"
/* In some instances a tree and a gimple need to be stored in a same table,
i.e. in hash tables. This is a structure to do this. */
@ -2720,6 +2721,91 @@ tree_could_trap_p (tree expr)
}
}
/* Return non-NULL if there is an integer operation with trapping overflow
we can rewrite into non-trapping. Called via walk_tree from
rewrite_to_non_trapping_overflow. */
static tree
find_trapping_overflow (tree *tp, int *walk_subtrees, void *data)
{
if (EXPR_P (*tp)
&& !operation_no_trapping_overflow (TREE_TYPE (*tp), TREE_CODE (*tp)))
return *tp;
if (IS_TYPE_OR_DECL_P (*tp)
|| (TREE_CODE (*tp) == SAVE_EXPR && data == NULL))
*walk_subtrees = 0;
return NULL_TREE;
}
/* Rewrite selected operations into unsigned arithmetics, so that they
don't trap on overflow. */
static tree
replace_trapping_overflow (tree *tp, int *walk_subtrees, void *data)
{
if (find_trapping_overflow (tp, walk_subtrees, data))
{
tree type = TREE_TYPE (*tp);
tree utype = unsigned_type_for (type);
*walk_subtrees = 0;
int len = TREE_OPERAND_LENGTH (*tp);
for (int i = 0; i < len; ++i)
walk_tree (&TREE_OPERAND (*tp, i), replace_trapping_overflow,
data, (hash_set<tree> *) data);
if (TREE_CODE (*tp) == ABS_EXPR)
{
tree op = TREE_OPERAND (*tp, 0);
op = save_expr (op);
/* save_expr skips simple arithmetics, which is undesirable
here, if it might trap due to flag_trapv. We need to
force a SAVE_EXPR in the COND_EXPR condition, to evaluate
it before the comparison. */
if (EXPR_P (op)
&& TREE_CODE (op) != SAVE_EXPR
&& walk_tree (&op, find_trapping_overflow, NULL, NULL))
{
op = build1_loc (EXPR_LOCATION (op), SAVE_EXPR, type, op);
TREE_SIDE_EFFECTS (op) = 1;
}
/* Change abs (op) to op < 0 ? -op : op and handle the NEGATE_EXPR
like other signed integer trapping operations. */
tree cond = fold_build2 (LT_EXPR, boolean_type_node,
op, build_int_cst (type, 0));
tree neg = fold_build1 (NEGATE_EXPR, utype,
fold_convert (utype, op));
*tp = fold_build3 (COND_EXPR, type, cond,
fold_convert (type, neg), op);
}
else
{
TREE_TYPE (*tp) = utype;
len = TREE_OPERAND_LENGTH (*tp);
for (int i = 0; i < len; ++i)
TREE_OPERAND (*tp, i)
= fold_convert (utype, TREE_OPERAND (*tp, i));
*tp = fold_convert (type, *tp);
}
}
return NULL_TREE;
}
/* If any subexpression of EXPR can trap due to -ftrapv, rewrite it
using unsigned arithmetics to avoid traps in it. */
tree
rewrite_to_non_trapping_overflow (tree expr)
{
if (!flag_trapv)
return expr;
hash_set<tree> pset;
if (!walk_tree (&expr, find_trapping_overflow, &pset, &pset))
return expr;
expr = unshare_expr (expr);
pset.empty ();
walk_tree (&expr, replace_trapping_overflow, &pset, &pset);
return expr;
}
/* Helper for stmt_could_throw_p. Return true if STMT (assumed to be a
an assignment or a conditional) may throw. */

View File

@ -37,6 +37,7 @@ extern bool operation_could_trap_helper_p (enum tree_code, bool, bool, bool,
bool, tree, bool *);
extern bool operation_could_trap_p (enum tree_code, bool, bool, tree);
extern bool tree_could_trap_p (tree);
extern tree rewrite_to_non_trapping_overflow (tree);
extern bool stmt_could_throw_p (gimple *);
extern bool tree_could_throw_p (tree);
extern bool stmt_can_throw_external (gimple *);

View File

@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see
#include "internal-fn.h"
#include "tree-vector-builder.h"
#include "vec-perm-indices.h"
#include "tree-eh.h"
/* Loop Vectorization Pass.
@ -1063,7 +1064,8 @@ vect_get_loop_niters (struct loop *loop, tree *assumptions,
may_be_zero));
else
niter = fold_build3 (COND_EXPR, TREE_TYPE (niter), may_be_zero,
build_int_cst (TREE_TYPE (niter), 0), niter);
build_int_cst (TREE_TYPE (niter), 0),
rewrite_to_non_trapping_overflow (niter));
may_be_zero = NULL_TREE;
}