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:
parent
eae4d8fbb5
commit
31b6733b16
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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--;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue