From 478cc962ad174bfc64c573152a0658935651fce3 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 15 Jul 2021 11:07:12 -0400 Subject: [PATCH] Add gimple_range_type for statements. The existing mechanisms for picking up the type of a statement are inconsistent with the needs of ranger. Encapsulate all the bits required to pick up the return type of a statement in one place, and check whether the type is supported. * gimple-range-fold.cc (adjust_pointer_diff_expr): Use gimple_range_type. (fold_using_range::fold_stmt): Ditto. (fold_using_range::range_of_range_op): Ditto. (fold_using_range::range_of_phi): Ditto. (fold_using_range::range_of_call): Ditto. (fold_using_range::range_of_builtin_ubsan_call): Ditto. (fold_using_range::range_of_builtin_call): Ditto. (fold_using_range::range_of_cond_expr): Ditto. * gimple-range-fold.h (gimple_range_type): New. --- gcc/gimple-range-fold.cc | 44 +++++++++++++++++++------------------------- gcc/gimple-range-fold.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index eff5d1f..f8578c0 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -362,7 +362,7 @@ adjust_pointer_diff_expr (irange &res, const gimple *diff_stmt) { tree max = vrp_val_max (ptrdiff_type_node); wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max))); - tree expr_type = gimple_expr_type (diff_stmt); + tree expr_type = gimple_range_type (diff_stmt); tree range_min = build_zero_cst (expr_type); tree range_max = wide_int_to_tree (expr_type, wmax - 1); int_range<2> r (range_min, range_max); @@ -522,16 +522,8 @@ fold_using_range::fold_stmt (irange &r, gimple *s, fur_source &src, tree name) if (!res) { - // If no name is specified, try the expression kind. - if (!name) - { - tree t = gimple_expr_type (s); - if (!irange::supports_type_p (t)) - return false; - r.set_varying (t); - return true; - } - if (!gimple_range_ssa_p (name)) + // If no name specified or range is unsupported, bail. + if (!name || !gimple_range_ssa_p (name)) return false; // We don't understand the stmt, so return the global range. r = gimple_range_global (name); @@ -558,10 +550,11 @@ bool fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src) { int_range_max range1, range2; - tree type = gimple_expr_type (s); + tree type = gimple_range_type (s); + if (!type) + return false; range_operator *handler = gimple_range_handler (s); gcc_checking_assert (handler); - gcc_checking_assert (irange::supports_type_p (type)); tree lhs = gimple_get_lhs (s); tree op1 = gimple_range_operand1 (s); @@ -719,11 +712,11 @@ bool fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src) { tree phi_def = gimple_phi_result (phi); - tree type = TREE_TYPE (phi_def); + tree type = gimple_range_type (phi); int_range_max arg_range; unsigned x; - if (!irange::supports_type_p (type)) + if (!type) return false; // Start with an empty range, unioning in each argument's range. @@ -780,13 +773,13 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src) bool fold_using_range::range_of_call (irange &r, gcall *call, fur_source &src) { - tree type = gimple_call_return_type (call); + tree type = gimple_range_type (call); + if (!type) + return false; + tree lhs = gimple_call_lhs (call); bool strict_overflow_p; - if (!irange::supports_type_p (type)) - return false; - if (range_of_builtin_call (r, call, src)) ; else if (gimple_stmt_nonnegative_warnv_p (call, &strict_overflow_p)) @@ -817,7 +810,7 @@ fold_using_range::range_of_builtin_ubsan_call (irange &r, gcall *call, { gcc_checking_assert (code == PLUS_EXPR || code == MINUS_EXPR || code == MULT_EXPR); - tree type = gimple_call_return_type (call); + tree type = gimple_range_type (call); range_operator *op = range_op_handler (code, type); gcc_checking_assert (op); int_range_max ir0, ir1; @@ -853,7 +846,7 @@ fold_using_range::range_of_builtin_call (irange &r, gcall *call, if (func == CFN_LAST) return false; - tree type = gimple_call_return_type (call); + tree type = gimple_range_type (call); tree arg; int mini, maxi, zerov = 0, prec; scalar_int_mode mode; @@ -1094,12 +1087,12 @@ fold_using_range::range_of_cond_expr (irange &r, gassign *s, fur_source &src) tree op1 = gimple_assign_rhs2 (s); tree op2 = gimple_assign_rhs3 (s); - gcc_checking_assert (gimple_assign_rhs_code (s) == COND_EXPR); - gcc_checking_assert (useless_type_conversion_p (TREE_TYPE (op1), - TREE_TYPE (op2))); - if (!irange::supports_type_p (TREE_TYPE (op1))) + tree type = gimple_range_type (s); + if (!type) return false; + gcc_checking_assert (gimple_assign_rhs_code (s) == COND_EXPR); + gcc_checking_assert (range_compatible_p (TREE_TYPE (op1), TREE_TYPE (op2))); src.get_operand (cond_range, cond); src.get_operand (range1, op1); src.get_operand (range2, op2); @@ -1118,6 +1111,7 @@ fold_using_range::range_of_cond_expr (irange &r, gassign *s, fur_source &src) r = range1; r.union_ (range2); } + gcc_checking_assert (range_compatible_p (r.type (), type)); return true; } diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h index dc1b28f..ceed7ba 100644 --- a/gcc/gimple-range-fold.h +++ b/gcc/gimple-range-fold.h @@ -56,6 +56,36 @@ gimple_range_handler (const gimple *s) return NULL; } +// Return the type of range which statement S calculates. If the type is +// unsupported or no type can be determined, return NULL_TREE. + +static inline tree +gimple_range_type (const gimple *s) +{ + tree lhs = gimple_get_lhs (s); + tree type = NULL_TREE; + if (lhs) + type = TREE_TYPE (lhs); + else + { + enum gimple_code code = gimple_code (s); + if (code == GIMPLE_COND) + type = boolean_type_node; + else if (code == GIMPLE_PHI) + type = TREE_TYPE (gimple_phi_result (s)); + else if (code == GIMPLE_CALL) + { + type = gimple_call_fntype (s); + // If it has a type, get the return type. + if (type) + type = TREE_TYPE (type); + } + } + if (irange::supports_type_p (type)) + return type; + return NULL_TREE; +} + // Return EXP if it is an SSA_NAME with a type supported by gimple ranges. static inline tree -- 2.7.4