diff mbox series

[COMMITTED] Conversion to irange wide_int API.

Message ID 20230501062906.564803-7-aldyh@redhat.com
State New
Headers show
Series [COMMITTED] Conversion to irange wide_int API. | expand

Commit Message

Aldy Hernandez May 1, 2023, 6:29 a.m. UTC
This converts the irange API to use wide_ints exclusively, along with
its users.

This patch will slow down VRP, as there will be more useless
wide_int to tree conversions.  However, this slowdown is only
temporary, as a follow-up patch will convert the internal
representation of iranges to wide_ints for a net overall gain
in performance.

gcc/ChangeLog:

	* fold-const.cc (expr_not_equal_to): Convert to irange wide_int API.
	* gimple-fold.cc (size_must_be_zero_p): Same.
	* gimple-loop-versioning.cc
	(loop_versioning::prune_loop_conditions): Same.
	* gimple-range-edge.cc (gcond_edge_range): Same.
	(gimple_outgoing_range::calc_switch_ranges): Same.
	* gimple-range-fold.cc (adjust_imagpart_expr): Same.
	(adjust_realpart_expr): Same.
	(fold_using_range::range_of_address): Same.
	(fold_using_range::relation_fold_and_or): Same.
	* gimple-range-gori.cc (gori_compute::gori_compute): Same.
	(range_is_either_true_or_false): Same.
	* gimple-range-op.cc (cfn_toupper_tolower::get_letter_range): Same.
	(cfn_clz::fold_range): Same.
	(cfn_ctz::fold_range): Same.
	* gimple-range-tests.cc (class test_expr_eval): Same.
	* gimple-ssa-warn-alloca.cc (alloca_call_type): Same.
	* ipa-cp.cc (ipa_value_range_from_jfunc): Same.
	(propagate_vr_across_jump_function): Same.
	(decide_whether_version_node): Same.
	* ipa-fnsummary.cc (evaluate_conditions_for_known_args): Same.
	* ipa-prop.cc (ipa_get_value_range): Same.
	* range-op.cc (get_shift_range): Same.
	(value_range_from_overflowed_bounds): Same.
	(value_range_with_overflow): Same.
	(create_possibly_reversed_range): Same.
	(equal_op1_op2_relation): Same.
	(not_equal_op1_op2_relation): Same.
	(lt_op1_op2_relation): Same.
	(le_op1_op2_relation): Same.
	(gt_op1_op2_relation): Same.
	(ge_op1_op2_relation): Same.
	(operator_mult::op1_range): Same.
	(operator_exact_divide::op1_range): Same.
	(operator_lshift::op1_range): Same.
	(operator_rshift::op1_range): Same.
	(operator_cast::op1_range): Same.
	(operator_logical_and::fold_range): Same.
	(set_nonzero_range_from_mask): Same.
	(operator_bitwise_or::op1_range): Same.
	(operator_bitwise_xor::op1_range): Same.
	(operator_addr_expr::fold_range): Same.
	(pointer_plus_operator::wi_fold): Same.
	(pointer_or_operator::op1_range): Same.
	(INT): Same.
	(UINT): Same.
	(INT16): Same.
	(UINT16): Same.
	(SCHAR): Same.
	(UCHAR): Same.
	(range_op_cast_tests): Same.
	(range_op_lshift_tests): Same.
	(range_op_rshift_tests): Same.
	(range_op_bitwise_and_tests): Same.
	(range_relational_tests): Same.
	* range.cc (range_zero): Same.
	(range_nonzero): Same.
	* range.h (range_true): Same.
	(range_false): Same.
	(range_true_and_false): Same.
	* tree-data-ref.cc (split_constant_offset_1): Same.
	* tree-ssa-loop-ch.cc (entry_loop_condition_is_static): Same.
	* tree-ssa-loop-unswitch.cc (struct unswitch_predicate): Same.
	(find_unswitching_predicates_for_bb): Same.
	* tree-ssa-phiopt.cc (value_replacement): Same.
	* tree-ssa-threadbackward.cc
	(back_threader::find_taken_edge_cond): Same.
	* tree-ssanames.cc (ssa_name_has_boolean_range): Same.
	* tree-vrp.cc (find_case_label_range): Same.
	* value-query.cc (range_query::get_tree_range): Same.
	* value-range.cc (irange::set_nonnegative): Same.
	(frange::contains_p): Same.
	(frange::singleton_p): Same.
	(frange::internal_singleton_p): Same.
	(irange::irange_set): Same.
	(irange::irange_set_1bit_anti_range): Same.
	(irange::irange_set_anti_range): Same.
	(irange::set): Same.
	(irange::operator==): Same.
	(irange::singleton_p): Same.
	(irange::contains_p): Same.
	(irange::set_range_from_nonzero_bits): Same.
	(DEFINE_INT_RANGE_INSTANCE): Same.
	(INT): Same.
	(UINT): Same.
	(SCHAR): Same.
	(UINT128): Same.
	(UCHAR): Same.
	(range): New.
	(tree_range): New.
	(range_int): New.
	(range_uint): New.
	(range_uint128): New.
	(range_uchar): New.
	(range_char): New.
	(build_range3): Convert to irange wide_int API.
	(range_tests_irange3): Same.
	(range_tests_int_range_max): Same.
	(range_tests_strict_enum): Same.
	(range_tests_misc): Same.
	(range_tests_nonzero_bits): Same.
	(range_tests_nan): Same.
	(range_tests_signed_zeros): Same.
	* value-range.h (Value_Range::Value_Range): Same.
	(irange::set): Same.
	(irange::nonzero_p): Same.
	(irange::contains_p): Same.
	(range_includes_zero_p): Same.
	(irange::set_nonzero): Same.
	(irange::set_zero): Same.
	(contains_zero_p): Same.
	(frange::contains_p): Same.
	* vr-values.cc
	(simplify_using_ranges::op_with_boolean_value_range_p): Same.
	(bounds_of_var_in_loop): Same.
	(simplify_using_ranges::legacy_fold_cond_overflow): Same.
---
 gcc/fold-const.cc              |   3 +-
 gcc/gimple-fold.cc             |   4 +-
 gcc/gimple-loop-versioning.cc  |   2 +-
 gcc/gimple-range-edge.cc       |  17 +-
 gcc/gimple-range-fold.cc       |  14 +-
 gcc/gimple-range-gori.cc       |   7 +-
 gcc/gimple-range-op.cc         |  42 +--
 gcc/gimple-range-tests.cc      |   9 +-
 gcc/gimple-ssa-warn-alloca.cc  |   5 +-
 gcc/ipa-cp.cc                  |  10 +-
 gcc/ipa-prop.cc                |   3 +-
 gcc/ipa-prop.h                 |   5 +-
 gcc/range-op.cc                | 263 +++++++++---------
 gcc/range.cc                   |   7 +-
 gcc/range.h                    |  14 +-
 gcc/tree-data-ref.cc           |   7 +-
 gcc/tree-ssa-loop-ch.cc        |   8 +-
 gcc/tree-ssa-loop-unswitch.cc  |  17 +-
 gcc/tree-ssa-phiopt.cc         |   3 +-
 gcc/tree-ssa-threadbackward.cc |   4 +-
 gcc/tree-ssanames.cc           |   5 +-
 gcc/tree-vrp.cc                |   8 +-
 gcc/value-query.cc             |  17 +-
 gcc/value-range.cc             | 472 ++++++++++++++++++++-------------
 gcc/value-range.h              |  75 ++++--
 gcc/vr-values.cc               |  27 +-
 26 files changed, 608 insertions(+), 440 deletions(-)
diff mbox series

Patch

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 7d2352dbcdd..db54bfc5662 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -10882,8 +10882,7 @@  expr_not_equal_to (tree t, const wide_int &w)
       else
 	get_global_range_query ()->range_of_expr (vr, t);
 
-      if (!vr.undefined_p ()
-	  && !vr.contains_p (wide_int_to_tree (TREE_TYPE (t), w)))
+      if (!vr.undefined_p () && !vr.contains_p (w))
 	return true;
       /* If T has some known zero bits and W has any of those bits set,
 	 then T is known not to be equal to W.  */
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 1d0e4c32c40..581575b65ec 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -873,8 +873,8 @@  size_must_be_zero_p (tree size)
   /* Compute the value of SSIZE_MAX, the largest positive value that
      can be stored in ssize_t, the signed counterpart of size_t.  */
   wide_int ssize_max = wi::lshift (wi::one (prec), prec - 1) - 1;
-  value_range valid_range (build_int_cst (type, 0),
-			   wide_int_to_tree (type, ssize_max));
+  wide_int zero = wi::zero (TYPE_PRECISION (type));
+  value_range valid_range (type, zero, ssize_max);
   value_range vr;
   if (cfun)
     get_range_query (cfun)->range_of_expr (vr, size);
diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc
index 640bb28016f..7b55129baa7 100644
--- a/gcc/gimple-loop-versioning.cc
+++ b/gcc/gimple-loop-versioning.cc
@@ -1476,7 +1476,7 @@  loop_versioning::prune_loop_conditions (class loop *loop)
       gimple *stmt = first_stmt (loop->header);
 
       if (get_range_query (cfun)->range_of_expr (r, name, stmt)
-	  && !r.contains_p (build_one_cst (TREE_TYPE (name))))
+	  && !r.contains_p (wi::one (TYPE_PRECISION (TREE_TYPE (name)))))
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_NOTE, find_loop_location (loop),
diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc
index 22fb709c9b1..5fc7e791c1b 100644
--- a/gcc/gimple-range-edge.cc
+++ b/gcc/gimple-range-edge.cc
@@ -59,9 +59,9 @@  gcond_edge_range (irange &r, edge e)
 {
   gcc_checking_assert (e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE));
   if (e->flags & EDGE_TRUE_VALUE)
-    r = int_range<2> (boolean_true_node, boolean_true_node);
+    r = range_true ();
   else
-    r = int_range<2> (boolean_false_node, boolean_false_node);
+    r = range_false ();
 }
 
 
@@ -136,19 +136,22 @@  gimple_outgoing_range::calc_switch_ranges (gswitch *sw)
       if (e == default_edge)
 	continue;
 
-      tree low = CASE_LOW (gimple_switch_label (sw, x));
-      tree high = CASE_HIGH (gimple_switch_label (sw, x));
-      if (!high)
+      wide_int low = wi::to_wide (CASE_LOW (gimple_switch_label (sw, x)));
+      wide_int high;
+      tree tree_high = CASE_HIGH (gimple_switch_label (sw, x));
+      if (tree_high)
+	high = wi::to_wide (tree_high);
+      else
 	high = low;
 
       // Remove the case range from the default case.
-      int_range_max def_range (low, high);
+      int_range_max def_range (type, low, high);
       range_cast (def_range, type);
       def_range.invert ();
       default_range.intersect (def_range);
 
       // Create/union this case with anything on else on the edge.
-      int_range_max case_range (low, high);
+      int_range_max case_range (type, low, high);
       range_cast (case_range, type);
       vrange_storage *&slot = m_edge_table->get_or_insert (e, &existed);
       if (existed)
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 180f349eda9..62875a35038 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -404,7 +404,8 @@  adjust_imagpart_expr (vrange &res, const gimple *stmt)
       tree cst = gimple_assign_rhs1 (def_stmt);
       if (TREE_CODE (cst) == COMPLEX_CST)
 	{
-	  int_range<2> imag (TREE_IMAGPART (cst), TREE_IMAGPART (cst));
+	  wide_int w = wi::to_wide (TREE_IMAGPART (cst));
+	  int_range<1> imag (TREE_TYPE (TREE_IMAGPART (cst)), w, w);
 	  res.intersect (imag);
 	}
     }
@@ -430,8 +431,8 @@  adjust_realpart_expr (vrange &res, const gimple *stmt)
       tree cst = gimple_assign_rhs1 (def_stmt);
       if (TREE_CODE (cst) == COMPLEX_CST)
 	{
-	  tree imag = TREE_REALPART (cst);
-	  int_range<2> tmp (imag, imag);
+	  wide_int imag = wi::to_wide (TREE_REALPART (cst));
+	  int_range<2> tmp (TREE_TYPE (TREE_REALPART (cst)), imag, imag);
 	  res.intersect (tmp);
 	}
     }
@@ -689,7 +690,8 @@  fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
 	{
 	  /* For -fdelete-null-pointer-checks -fno-wrapv-pointer we don't
 	     allow going from non-NULL pointer to NULL.  */
-	  if (r.undefined_p () || !r.contains_p (build_zero_cst (r.type ())))
+	  if (r.undefined_p ()
+	      || !r.contains_p (wi::zero (TYPE_PRECISION (TREE_TYPE (expr)))))
 	    {
 	      /* We could here instead adjust r by off >> LOG2_BITS_PER_UNIT
 		 using POINTER_PLUS_EXPR if off_cst and just fall back to
@@ -1069,7 +1071,7 @@  fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s,
   else if (ssa1_dep1 != ssa2_dep2 || ssa1_dep2 != ssa2_dep1)
     return;
 
-  int_range<2> bool_one (boolean_true_node, boolean_true_node);
+  int_range<2> bool_one = range_true ();
 
   relation_kind relation1 = handler1.op1_op2_relation (bool_one);
   relation_kind relation2 = handler2.op1_op2_relation (bool_one);
@@ -1081,7 +1083,7 @@  fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s,
 
   // x && y is false if the relation intersection of the true cases is NULL.
   if (is_and && relation_intersect (relation1, relation2) == VREL_UNDEFINED)
-    lhs_range = int_range<2> (boolean_false_node, boolean_false_node);
+    lhs_range = range_false (boolean_type_node);
   // x || y is true if the union of the true cases is NO-RELATION..
   // ie, one or the other being true covers the full range of possibilities.
   else if (!is_and && relation_union (relation1, relation2) == VREL_VARYING)
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 9d0cc97bf8c..a1c8d51e484 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -562,8 +562,8 @@  gori_compute::gori_compute (int not_executable_flag)
 {
   m_not_executable_flag = not_executable_flag;
   // Create a boolean_type true and false range.
-  m_bool_zero = int_range<2> (boolean_false_node, boolean_false_node);
-  m_bool_one = int_range<2> (boolean_true_node, boolean_true_node);
+  m_bool_zero = range_false ();
+  m_bool_one = range_true ();
   if (dump_file && (param_ranger_debug & RANGER_DEBUG_GORI))
     tracer.enable_trace ();
 }
@@ -731,7 +731,8 @@  range_is_either_true_or_false (const irange &r)
   // so true can be ~[0, 0] (i.e. [1,MAX]).
   tree type = r.type ();
   gcc_checking_assert (range_compatible_p (type, boolean_type_node));
-  return (r.singleton_p () || !r.contains_p (build_zero_cst (type)));
+  return (r.singleton_p ()
+	  || !r.contains_p (wi::zero (TYPE_PRECISION (type))));
 }
 
 // Evaluate a binary logical expression by combining the true and
diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc
index 6fa26f5d3a2..29c7c776a2c 100644
--- a/gcc/gimple-range-op.cc
+++ b/gcc/gimple-range-op.cc
@@ -276,7 +276,8 @@  public:
   {
     if (lh.singleton_p ())
       {
-	r.set (build_one_cst (type), build_one_cst (type));
+	wide_int one = wi::one (TYPE_PRECISION (type));
+	r.set (type, one, one);
 	return true;
       }
     if (cfun->after_inlining)
@@ -298,7 +299,8 @@  public:
   {
     if (lh.singleton_p ())
       {
-	r.set (build_one_cst (type), build_one_cst (type));
+	wide_int one = wi::one (TYPE_PRECISION (type));
+	r.set (type, one, one);
 	return true;
       }
     if (cfun->after_inlining)
@@ -359,7 +361,7 @@  public:
 	r.update_nan (false);
 	return true;
       }
-    if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+    if (!lhs.contains_p (wi::zero (TYPE_PRECISION (lhs.type ()))))
       {
 	r.set (type, frange_val_min (type), dconstm0);
 	r.update_nan (true);
@@ -589,8 +591,12 @@  cfn_toupper_tolower::get_letter_range (tree type, irange &lowers,
 
   if ((z - a == 25) && (Z - A == 25))
     {
-      lowers = int_range<2> (build_int_cst (type, a), build_int_cst (type, z));
-      uppers = int_range<2> (build_int_cst (type, A), build_int_cst (type, Z));
+      lowers = int_range<2> (type,
+			     wi::shwi (a, TYPE_PRECISION (type)),
+			     wi::shwi (z, TYPE_PRECISION (type)));
+      uppers = int_range<2> (type,
+			     wi::shwi (A, TYPE_PRECISION (type)),
+			     wi::shwi (Z, TYPE_PRECISION (type)));
       return true;
     }
   // Unknown character set.
@@ -648,7 +654,7 @@  public:
       range_cast (tmp, unsigned_type_for (tmp.type ()));
     wide_int max = tmp.upper_bound ();
     maxi = wi::floor_log2 (max) + 1;
-    r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
+    r.set (type, wi::shwi (mini, prec), wi::shwi (maxi, prec));
     return true;
   }
 } op_cfn_ffs;
@@ -753,7 +759,9 @@  cfn_clz::fold_range (irange &r, tree type, const irange &lh,
 
   if (mini == -2)
     return false;
-  r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
+  r.set (type,
+	 wi::shwi (mini, TYPE_PRECISION (type)),
+	 wi::shwi (maxi, TYPE_PRECISION (type)));
   return true;
 }
 
@@ -823,7 +831,9 @@  cfn_ctz::fold_range (irange &r, tree type, const irange &lh,
 
   if (mini == -2)
     return false;
-  r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
+  r.set (type,
+	 wi::shwi (mini, TYPE_PRECISION (type)),
+	 wi::shwi (maxi, TYPE_PRECISION (type)));
   return true;
 }
 
@@ -839,7 +849,9 @@  public:
     if (lh.undefined_p ())
       return false;
     int prec = TYPE_PRECISION (lh.type ());
-    r.set (build_int_cst (type, 0), build_int_cst (type, prec - 1));
+    r.set (type,
+	   wi::zero (TYPE_PRECISION (type)),
+	   wi::shwi (prec - 1, TYPE_PRECISION (type)));
     return true;
   }
 } op_cfn_clrsb;
@@ -891,14 +903,12 @@  public:
     tree max = vrp_val_max (ptrdiff_type_node);
     wide_int wmax
       = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
-    tree range_min = build_zero_cst (type);
     // To account for the terminating NULL, the maximum length
     // is one less than the maximum array size, which in turn
     // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
     // smaller than the former type).
     // FIXME: Use max_object_size() - 1 here.
-    tree range_max = wide_int_to_tree (type, wmax - 2);
-    r.set (range_min, range_max);
+    r.set (type, wi::zero (TYPE_PRECISION (type)), wmax - 2);
     return true;
   }
 } op_cfn_strlen;
@@ -922,9 +932,11 @@  public:
       // If it's dynamic, the backend might know a hardware limitation.
       size = targetm.goacc.dim_limit (axis);
 
-    r.set (build_int_cst (type, m_is_pos ? 0 : 1),
+    r.set (type,
+	   wi::shwi (m_is_pos ? 0 : 1, TYPE_PRECISION (type)),
 	   size
-	   ? build_int_cst (type, size - m_is_pos) : vrp_val_max (type));
+	   ? wi::shwi (size - m_is_pos, TYPE_PRECISION (type))
+	   : wi::to_wide (vrp_val_max (type)));
     return true;
   }
 private:
@@ -940,7 +952,7 @@  public:
   virtual bool fold_range (irange &r, tree type, const irange &,
 			   const irange &, relation_trio) const
   {
-    r.set (build_zero_cst (type), build_one_cst (type));
+    r = range_true_and_false (type);
     return true;
   }
 } op_cfn_parity;
diff --git a/gcc/gimple-range-tests.cc b/gcc/gimple-range-tests.cc
index 7e4d234ddda..c325a7bcebd 100644
--- a/gcc/gimple-range-tests.cc
+++ b/gcc/gimple-range-tests.cc
@@ -35,7 +35,9 @@  public:
 
     // [5,10] + [15,20] => [20, 30]
     tree expr = fold_build2 (PLUS_EXPR, type, op0, op1);
-    int_range<2> expect (build_int_cst (type, 20), build_int_cst (type, 30));
+    int_range<1> expect (type,
+			 wi::shwi (20, TYPE_PRECISION (type)),
+			 wi::shwi (30, TYPE_PRECISION (type)));
     int_range_max r;
 
     ASSERT_TRUE (range_of_expr (r, expr));
@@ -45,14 +47,15 @@  public:
   virtual bool range_of_expr (vrange &v, tree expr, gimple * = NULL) override
   {
     irange &r = as_a <irange> (v);
+    unsigned prec = TYPE_PRECISION (type);
     if (expr == op0)
       {
-	r.set (build_int_cst (type, 5), build_int_cst (type, 10));
+	r.set (type, wi::shwi (5, prec), wi::shwi (10, prec));
 	return true;
       }
     if (expr == op1)
       {
-	r.set (build_int_cst (type, 15), build_int_cst (type, 20));
+	r.set (type, wi::shwi (15, prec), wi::shwi (20, prec));
 	return true;
       }
     return gimple_ranger::range_of_expr (r, expr);
diff --git a/gcc/gimple-ssa-warn-alloca.cc b/gcc/gimple-ssa-warn-alloca.cc
index 4374f572cd9..c129aca16e2 100644
--- a/gcc/gimple-ssa-warn-alloca.cc
+++ b/gcc/gimple-ssa-warn-alloca.cc
@@ -222,8 +222,9 @@  alloca_call_type (gimple *stmt, bool is_vla)
       && !r.varying_p ())
     {
       // The invalid bits are anything outside of [0, MAX_SIZE].
-      int_range<2> invalid_range (build_int_cst (size_type_node, 0),
-				  build_int_cst (size_type_node, max_size),
+      int_range<1> invalid_range (size_type_node,
+				  wi::shwi (0, TYPE_PRECISION (size_type_node)),
+				  wi::shwi (max_size, TYPE_PRECISION (size_type_node)),
 				  VR_ANTI_RANGE);
 
       r.intersect (invalid_range);
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index a5b45a8e6b9..1f5e0e13872 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -1943,8 +1943,9 @@  ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
       if (!(*sum->m_vr)[idx].known)
 	return vr;
       tree vr_type = ipa_get_type (info, idx);
-      value_range srcvr (wide_int_to_tree (vr_type, (*sum->m_vr)[idx].min),
-			 wide_int_to_tree (vr_type, (*sum->m_vr)[idx].max),
+      value_range srcvr (vr_type,
+			 (*sum->m_vr)[idx].min,
+			 (*sum->m_vr)[idx].max,
 			 (*sum->m_vr)[idx].type);
 
       enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
@@ -2799,7 +2800,8 @@  propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
 	  if (TREE_OVERFLOW_P (val))
 	    val = drop_tree_overflow (val);
 
-	  value_range tmpvr (val, val);
+	  value_range tmpvr (TREE_TYPE (val),
+			     wi::to_wide (val), wi::to_wide (val));
 	  return dest_lat->meet_with (&tmpvr);
 	}
     }
@@ -6204,7 +6206,7 @@  decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
    necessary.  */
 
 static inline bool
-ipa_range_contains_p (const irange &r, tree val)
+ipa_range_contains_p (const vrange &r, tree val)
 {
   if (r.undefined_p ())
     return false;
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index c6d4585aed1..0f3cb3dd9f9 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -2220,7 +2220,8 @@  ipa_get_value_range (value_range *tmp)
 static value_range *
 ipa_get_value_range (enum value_range_kind kind, tree min, tree max)
 {
-  value_range tmp (min, max, kind);
+  value_range tmp (TREE_TYPE (min),
+		   wi::to_wide (min), wi::to_wide (max), kind);
   return ipa_get_value_range (&tmp);
 }
 
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 93785a6a8e6..d4936d4eaff 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -1208,7 +1208,10 @@  inline void
 ipa_range_set_and_normalize (irange &r, tree val)
 {
   if (TREE_CODE (val) == INTEGER_CST)
-    r.set (val, val);
+    {
+      wide_int w = wi::to_wide (val);
+      r.set (TREE_TYPE (val), w, w);
+    }
   else if (TREE_CODE (val) == ADDR_EXPR)
     r.set_nonzero (TREE_TYPE (val));
   else
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 215a1613b38..224a561c170 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -119,8 +119,9 @@  get_shift_range (irange &r, tree type, const irange &op)
     return false;
 
   // Build valid range and intersect it with the shift range.
-  r = value_range (build_int_cst_type (op.type (), 0),
-		   build_int_cst_type (op.type (), TYPE_PRECISION (type) - 1));
+  r = value_range (op.type (),
+		   wi::shwi (0, TYPE_PRECISION (op.type ())),
+		   wi::shwi (TYPE_PRECISION (type) - 1, TYPE_PRECISION (op.type ())));
   r.intersect (op);
 
   // If there are no valid ranges in the shift range, returned false.
@@ -414,11 +415,7 @@  value_range_from_overflowed_bounds (irange &r, tree type,
   if (covers || wi::cmp (tmin, tmax, sgn) > 0)
     r.set_varying (type);
   else
-    {
-      tree tree_min = wide_int_to_tree (type, tmin);
-      tree tree_max = wide_int_to_tree (type, tmax);
-      r.set (tree_min, tree_max, VR_ANTI_RANGE);
-    }
+    r.set (type, tmin, tmax, VR_ANTI_RANGE);
 }
 
 // Create and return a range from a pair of wide-ints.  MIN_OVF and
@@ -458,8 +455,7 @@  value_range_with_overflow (irange &r, tree type,
 	  else
 	    // No overflow or both overflow or underflow.  The range
 	    // kind stays normal.
-	    r.set (wide_int_to_tree (type, tmin),
-		   wide_int_to_tree (type, tmax));
+	    r.set (type, tmin, tmax);
 	  return;
 	}
 
@@ -497,8 +493,7 @@  value_range_with_overflow (irange &r, tree type,
       else
         new_ub = wmax;
 
-      r.set (wide_int_to_tree (type, new_lb),
-	     wide_int_to_tree (type, new_ub));
+      r.set (type, new_lb, new_ub);
     }
 }
 
@@ -516,7 +511,7 @@  create_possibly_reversed_range (irange &r, tree type,
     value_range_from_overflowed_bounds (r, type, new_lb, new_ub);
   else
     // Otherwise it's just a normal range.
-    r.set (wide_int_to_tree (type, new_lb), wide_int_to_tree (type, new_ub));
+    r.set (type, new_lb, new_ub);
 }
 
 // Return the summary information about boolean range LHS.  If EMPTY/FULL,
@@ -581,7 +576,7 @@  equal_op1_op2_relation (const irange &lhs)
     return VREL_NE;
 
   // TRUE = op1 == op2 indicates EQ_EXPR.
-  if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+  if (lhs.undefined_p () || !contains_zero_p (lhs))
     return VREL_EQ;
   return VREL_VARYING;
 }
@@ -701,7 +696,7 @@  not_equal_op1_op2_relation (const irange &lhs)
     return VREL_EQ;
 
   // TRUE = op1 != op2  indicates NE_EXPR.
-  if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+  if (lhs.undefined_p () || !contains_zero_p (lhs))
     return VREL_NE;
   return VREL_VARYING;
 }
@@ -881,7 +876,7 @@  lt_op1_op2_relation (const irange &lhs)
     return VREL_GE;
 
   // TRUE = op1 < op2 indicates LT_EXPR.
-  if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+  if (lhs.undefined_p () || !contains_zero_p (lhs))
     return VREL_LT;
   return VREL_VARYING;
 }
@@ -1001,7 +996,7 @@  le_op1_op2_relation (const irange &lhs)
     return VREL_GT;
 
   // TRUE = op1 <= op2 indicates LE_EXPR.
-  if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+  if (lhs.undefined_p () || !contains_zero_p (lhs))
     return VREL_LE;
   return VREL_VARYING;
 }
@@ -1118,7 +1113,7 @@  gt_op1_op2_relation (const irange &lhs)
     return VREL_LE;
 
   // TRUE = op1 > op2 indicates GT_EXPR.
-  if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+  if (!contains_zero_p (lhs))
     return VREL_GT;
   return VREL_VARYING;
 }
@@ -1234,7 +1229,7 @@  ge_op1_op2_relation (const irange &lhs)
     return VREL_LT;
 
   // TRUE = op1 >= op2 indicates GE_EXPR.
-  if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+  if (!contains_zero_p (lhs))
     return VREL_GE;
   return VREL_VARYING;
 }
@@ -1963,7 +1958,6 @@  operator_mult::op1_range (irange &r, tree type,
 			  const irange &lhs, const irange &op2,
 			  relation_trio) const
 {
-  tree offset;
   if (lhs.undefined_p ())
     return false;
 
@@ -1973,7 +1967,8 @@  operator_mult::op1_range (irange &r, tree type,
   if (TYPE_OVERFLOW_WRAPS (type))
     return false;
 
-  if (op2.singleton_p (&offset) && !integer_zerop (offset))
+  wide_int offset;
+  if (op2.singleton_p (offset) && offset != 0)
     return range_op_handler (TRUNC_DIV_EXPR, type).fold_range (r, type,
 							       lhs, op2);
   return false;
@@ -2284,15 +2279,14 @@  operator_exact_divide::op1_range (irange &r, tree type,
 {
   if (lhs.undefined_p ())
     return false;
-  tree offset;
+  wide_int offset;
   // [2, 4] = op1 / [3,3]   since its exact divide, no need to worry about
   // remainders in the endpoints, so op1 = [2,4] * [3,3] = [6,12].
   // We wont bother trying to enumerate all the in between stuff :-P
   // TRUE accuracy is [6,6][9,9][12,12].  This is unlikely to matter most of
   // the time however.
   // If op2 is a multiple of 2, we would be able to set some non-zero bits.
-  if (op2.singleton_p (&offset)
-      && !integer_zerop (offset))
+  if (op2.singleton_p (offset) && offset != 0)
     return range_op_handler (MULT_EXPR, type).fold_range (r, type, lhs, op2);
   return false;
 }
@@ -2495,16 +2489,15 @@  operator_lshift::op1_range (irange &r,
 {
   if (lhs.undefined_p ())
     return false;
-  tree shift_amount;
 
-  if (!lhs.contains_p (build_zero_cst (type)))
+  if (!contains_zero_p (lhs))
     r.set_nonzero (type);
   else
     r.set_varying (type);
 
-  if (op2.singleton_p (&shift_amount))
+  wide_int shift;
+  if (op2.singleton_p (shift))
     {
-      wide_int shift = wi::to_wide (shift_amount);
       if (wi::lt_p (shift, 0, SIGNED))
 	return false;
       if (wi::ge_p (shift, wi::uhwi (TYPE_PRECISION (type),
@@ -2541,8 +2534,7 @@  operator_lshift::op1_range (irange &r,
       // This would be [0x42, 0xFC] aka [01000010, 11111100].
 
       // Ideally we do this for each subrange, but just lump them all for now.
-      unsigned low_bits = TYPE_PRECISION (utype)
-			  - TREE_INT_CST_LOW (shift_amount);
+      unsigned low_bits = TYPE_PRECISION (utype) - shift.to_uhwi ();
       wide_int up_mask = wi::mask (low_bits, true, TYPE_PRECISION (utype));
       wide_int new_ub = wi::bit_or (up_mask, tmp_range.upper_bound ());
       wide_int new_lb = wi::set_bit (tmp_range.lower_bound (), low_bits);
@@ -2566,18 +2558,18 @@  operator_rshift::op1_range (irange &r,
 			    const irange &op2,
 			    relation_trio) const
 {
-  tree shift;
   if (lhs.undefined_p ())
     return false;
-  if (op2.singleton_p (&shift))
+  wide_int shift;
+  if (op2.singleton_p (shift))
     {
       // Ignore nonsensical shifts.
       unsigned prec = TYPE_PRECISION (type);
-      if (wi::ge_p (wi::to_wide (shift),
-		    wi::uhwi (prec, TYPE_PRECISION (TREE_TYPE (shift))),
+      if (wi::ge_p (shift,
+		    wi::uhwi (prec, TYPE_PRECISION (op2.type ())),
 		    UNSIGNED))
 	return false;
-      if (wi::to_wide (shift) == 0)
+      if (shift == 0)
 	{
 	  r = lhs;
 	  return true;
@@ -2593,7 +2585,7 @@  operator_rshift::op1_range (irange &r,
 	  r.set_undefined ();
 	  return true;
 	}
-      int_range_max shift_range (shift, shift);
+      int_range_max shift_range (op2.type (), shift, shift);
       int_range_max lb, ub;
       op_lshift.fold_range (lb, type, lhs_refined, shift_range);
       //    LHS
@@ -2605,12 +2597,14 @@  operator_rshift::op1_range (irange &r,
       tree mask = fold_build1 (BIT_NOT_EXPR, type,
 			       fold_build2 (LSHIFT_EXPR, type,
 					    build_minus_one_cst (type),
-					    shift));
-      int_range_max mask_range (build_zero_cst (type), mask);
+					    wide_int_to_tree (op2.type (), shift)));
+      int_range_max mask_range (type,
+				wi::zero (TYPE_PRECISION (type)),
+				wi::to_wide (mask));
       op_plus.fold_range (ub, type, lb, mask_range);
       r = lb;
       r.union_ (ub);
-      if (!lhs_refined.contains_p (build_zero_cst (type)))
+      if (!contains_zero_p (lhs_refined))
 	{
 	  mask_range.invert ();
 	  r.intersect (mask_range);
@@ -2853,7 +2847,7 @@  operator_cast::op1_range (irange &r, tree type,
 	{
 	  // If the LHS is not a pointer nor a singleton, then it is
 	  // either VARYING or non-zero.
-	  if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+	  if (!contains_zero_p (lhs))
 	    r.set_nonzero (type);
 	  else
 	    r.set_varying (type);
@@ -2971,8 +2965,7 @@  operator_logical_and::fold_range (irange &r, tree type,
   if ((wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (lh.upper_bound (), 0))
       || (wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (rh.upper_bound (), 0)))
     r = range_false (type);
-  else if (lh.contains_p (build_zero_cst (lh.type ()))
-	   || rh.contains_p (build_zero_cst (rh.type ())))
+  else if (contains_zero_p (lh) || contains_zero_p (rh))
     // To reach this point, there must be a logical 1 on each side, and
     // the only remaining question is whether there is a zero or not.
     r = range_true_and_false (type);
@@ -3288,7 +3281,7 @@  operator_bitwise_and::wi_fold (irange &r, tree type,
 static void
 set_nonzero_range_from_mask (irange &r, tree type, const irange &lhs)
 {
-  if (!lhs.contains_p (build_zero_cst (type)))
+  if (!contains_zero_p (lhs))
     r = range_nonzero (type);
   else
     r.set_varying (type);
@@ -3605,8 +3598,7 @@  operator_bitwise_or::op1_range (irange &r, tree type,
 
   if (lhs.zero_p ())
     {
-      tree zero = build_zero_cst (type);
-      r = int_range<1> (zero, zero);
+      r.set_zero (type);
       return true;
     }
   r.set_varying (type);
@@ -3743,7 +3735,7 @@  operator_bitwise_xor::op1_range (irange &r, tree type,
 	  else if (op2.zero_p ())
 	    r = range_true (type);
 	  // See get_bool_state for the rationale
-	  else if (op2.contains_p (build_zero_cst (op2.type ())))
+	  else if (contains_zero_p (op2))
 	    r = range_true_and_false (type);
 	  else
 	    r = range_false (type);
@@ -4346,7 +4338,7 @@  operator_addr_expr::fold_range (irange &r, tree type,
   // Return a non-null pointer of the LHS type (passed in op2).
   if (lh.zero_p ())
     r = range_zero (type);
-  else if (!lh.contains_p (build_zero_cst (lh.type ())))
+  else if (!contains_zero_p (lh))
     r = range_nonzero (type);
   else
     r.set_varying (type);
@@ -4387,8 +4379,7 @@  pointer_plus_operator::wi_fold (irange &r, tree type,
   // Check for [0,0] + const, and simply return the const.
   if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
     {
-      tree val = wide_int_to_tree (type, rh_lb);
-      r.set (val, val);
+      r.set (type, rh_lb, rh_lb);
       return;
     }
 
@@ -4522,8 +4513,7 @@  pointer_or_operator::op1_range (irange &r, tree type,
     return false;
   if (lhs.zero_p ())
     {
-      tree zero = build_zero_cst (type);
-      r = int_range<1> (zero, zero);
+      r.set_zero (type);
       return true;
     }
   r.set_varying (type);
@@ -4880,112 +4870,120 @@  range_cast (vrange &r, tree type)
 
 namespace selftest
 {
-#define INT(N) build_int_cst (integer_type_node, (N))
-#define UINT(N) build_int_cstu (unsigned_type_node, (N))
-#define INT16(N) build_int_cst (short_integer_type_node, (N))
-#define UINT16(N) build_int_cstu (short_unsigned_type_node, (N))
-#define SCHAR(N) build_int_cst (signed_char_type_node, (N))
-#define UCHAR(N) build_int_cstu (unsigned_char_type_node, (N))
+#define INT(x) wi::shwi ((x), TYPE_PRECISION (integer_type_node))
+#define UINT(x) wi::uhwi ((x), TYPE_PRECISION (unsigned_type_node))
+#define INT16(x) wi::shwi ((x), TYPE_PRECISION (short_integer_type_node))
+#define UINT16(x) wi::uhwi ((x), TYPE_PRECISION (short_unsigned_type_node))
+#define SCHAR(x) wi::shwi ((x), TYPE_PRECISION (signed_char_type_node))
+#define UCHAR(x) wi::uhwi ((x), TYPE_PRECISION (unsigned_char_type_node))
 
 static void
 range_op_cast_tests ()
 {
   int_range<2> r0, r1, r2, rold;
   r0.set_varying (integer_type_node);
-  tree maxint = wide_int_to_tree (integer_type_node, r0.upper_bound ());
+  wide_int maxint = r0.upper_bound ();
 
   // If a range is in any way outside of the range for the converted
   // to range, default to the range for the new type.
   r0.set_varying (short_integer_type_node);
-  tree minshort = wide_int_to_tree (short_integer_type_node, r0.lower_bound ());
-  tree maxshort = wide_int_to_tree (short_integer_type_node, r0.upper_bound ());
-  if (TYPE_PRECISION (TREE_TYPE (maxint))
+  wide_int minshort = r0.lower_bound ();
+  wide_int maxshort = r0.upper_bound ();
+  if (TYPE_PRECISION (integer_type_node)
       > TYPE_PRECISION (short_integer_type_node))
     {
-      r1 = int_range<1> (integer_zero_node, maxint);
+      r1 = int_range<1> (integer_type_node,
+			 wi::zero (TYPE_PRECISION (integer_type_node)),
+			 maxint);
       range_cast (r1, short_integer_type_node);
-      ASSERT_TRUE (r1.lower_bound () == wi::to_wide (minshort)
-		   && r1.upper_bound() == wi::to_wide (maxshort));
+      ASSERT_TRUE (r1.lower_bound () == minshort
+		   && r1.upper_bound() == maxshort);
     }
 
   // (unsigned char)[-5,-1] => [251,255].
-  r0 = rold = int_range<1> (SCHAR (-5), SCHAR (-1));
+  r0 = rold = int_range<1> (signed_char_type_node, SCHAR (-5), SCHAR (-1));
   range_cast (r0, unsigned_char_type_node);
-  ASSERT_TRUE (r0 == int_range<1> (UCHAR (251), UCHAR (255)));
+  ASSERT_TRUE (r0 == int_range<1> (unsigned_char_type_node,
+				   UCHAR (251), UCHAR (255)));
   range_cast (r0, signed_char_type_node);
   ASSERT_TRUE (r0 == rold);
 
   // (signed char)[15, 150] => [-128,-106][15,127].
-  r0 = rold = int_range<1> (UCHAR (15), UCHAR (150));
+  r0 = rold = int_range<1> (unsigned_char_type_node, UCHAR (15), UCHAR (150));
   range_cast (r0, signed_char_type_node);
-  r1 = int_range<1> (SCHAR (15), SCHAR (127));
-  r2 = int_range<1> (SCHAR (-128), SCHAR (-106));
+  r1 = int_range<1> (signed_char_type_node, SCHAR (15), SCHAR (127));
+  r2 = int_range<1> (signed_char_type_node, SCHAR (-128), SCHAR (-106));
   r1.union_ (r2);
   ASSERT_TRUE (r1 == r0);
   range_cast (r0, unsigned_char_type_node);
   ASSERT_TRUE (r0 == rold);
 
   // (unsigned char)[-5, 5] => [0,5][251,255].
-  r0 = rold = int_range<1> (SCHAR (-5), SCHAR (5));
+  r0 = rold = int_range<1> (signed_char_type_node, SCHAR (-5), SCHAR (5));
   range_cast (r0, unsigned_char_type_node);
-  r1 = int_range<1> (UCHAR (251), UCHAR (255));
-  r2 = int_range<1> (UCHAR (0), UCHAR (5));
+  r1 = int_range<1> (unsigned_char_type_node, UCHAR (251), UCHAR (255));
+  r2 = int_range<1> (unsigned_char_type_node, UCHAR (0), UCHAR (5));
   r1.union_ (r2);
   ASSERT_TRUE (r0 == r1);
   range_cast (r0, signed_char_type_node);
   ASSERT_TRUE (r0 == rold);
 
   // (unsigned char)[-5,5] => [0,5][251,255].
-  r0 = int_range<1> (INT (-5), INT (5));
+  r0 = int_range<1> (integer_type_node, INT (-5), INT (5));
   range_cast (r0, unsigned_char_type_node);
-  r1 = int_range<1> (UCHAR (0), UCHAR (5));
-  r1.union_ (int_range<1> (UCHAR (251), UCHAR (255)));
+  r1 = int_range<1> (unsigned_char_type_node, UCHAR (0), UCHAR (5));
+  r1.union_ (int_range<1> (unsigned_char_type_node, UCHAR (251), UCHAR (255)));
   ASSERT_TRUE (r0 == r1);
 
   // (unsigned char)[5U,1974U] => [0,255].
-  r0 = int_range<1> (UINT (5), UINT (1974));
+  r0 = int_range<1> (unsigned_type_node, UINT (5), UINT (1974));
   range_cast (r0, unsigned_char_type_node);
-  ASSERT_TRUE (r0 == int_range<1> (UCHAR (0), UCHAR (255)));
+  ASSERT_TRUE (r0 == int_range<1> (unsigned_char_type_node, UCHAR (0), UCHAR (255)));
   range_cast (r0, integer_type_node);
   // Going to a wider range should not sign extend.
-  ASSERT_TRUE (r0 == int_range<1> (INT (0), INT (255)));
+  ASSERT_TRUE (r0 == int_range<1> (integer_type_node, INT (0), INT (255)));
 
   // (unsigned char)[-350,15] => [0,255].
-  r0 = int_range<1> (INT (-350), INT (15));
+  r0 = int_range<1> (integer_type_node, INT (-350), INT (15));
   range_cast (r0, unsigned_char_type_node);
   ASSERT_TRUE (r0 == (int_range<1>
-		      (TYPE_MIN_VALUE (unsigned_char_type_node),
-		       TYPE_MAX_VALUE (unsigned_char_type_node))));
+		      (unsigned_char_type_node,
+		       min_limit (unsigned_char_type_node),
+		       max_limit (unsigned_char_type_node))));
 
   // Casting [-120,20] from signed char to unsigned short.
   // => [0, 20][0xff88, 0xffff].
-  r0 = int_range<1> (SCHAR (-120), SCHAR (20));
+  r0 = int_range<1> (signed_char_type_node, SCHAR (-120), SCHAR (20));
   range_cast (r0, short_unsigned_type_node);
-  r1 = int_range<1> (UINT16 (0), UINT16 (20));
-  r2 = int_range<1> (UINT16 (0xff88), UINT16 (0xffff));
+  r1 = int_range<1> (short_unsigned_type_node, UINT16 (0), UINT16 (20));
+  r2 = int_range<1> (short_unsigned_type_node,
+		     UINT16 (0xff88), UINT16 (0xffff));
   r1.union_ (r2);
   ASSERT_TRUE (r0 == r1);
   // A truncating cast back to signed char will work because [-120, 20]
   // is representable in signed char.
   range_cast (r0, signed_char_type_node);
-  ASSERT_TRUE (r0 == int_range<1> (SCHAR (-120), SCHAR (20)));
+  ASSERT_TRUE (r0 == int_range<1> (signed_char_type_node,
+				   SCHAR (-120), SCHAR (20)));
 
   // unsigned char -> signed short
   //	(signed short)[(unsigned char)25, (unsigned char)250]
   // => [(signed short)25, (signed short)250]
-  r0 = rold = int_range<1> (UCHAR (25), UCHAR (250));
+  r0 = rold = int_range<1> (unsigned_char_type_node, UCHAR (25), UCHAR (250));
   range_cast (r0, short_integer_type_node);
-  r1 = int_range<1> (INT16 (25), INT16 (250));
+  r1 = int_range<1> (short_integer_type_node, INT16 (25), INT16 (250));
   ASSERT_TRUE (r0 == r1);
   range_cast (r0, unsigned_char_type_node);
   ASSERT_TRUE (r0 == rold);
 
   // Test casting a wider signed [-MIN,MAX] to a narrower unsigned.
-  r0 = int_range<1> (TYPE_MIN_VALUE (long_long_integer_type_node),
-	       TYPE_MAX_VALUE (long_long_integer_type_node));
+  r0 = int_range<1> (long_long_integer_type_node,
+		     min_limit (long_long_integer_type_node),
+		     max_limit (long_long_integer_type_node));
   range_cast (r0, short_unsigned_type_node);
-  r1 = int_range<1> (TYPE_MIN_VALUE (short_unsigned_type_node),
-	       TYPE_MAX_VALUE (short_unsigned_type_node));
+  r1 = int_range<1> (short_unsigned_type_node,
+		     min_limit (short_unsigned_type_node),
+		     max_limit (short_unsigned_type_node));
   ASSERT_TRUE (r0 == r1);
 
   // Casting NONZERO to a narrower type will wrap/overflow so
@@ -4999,8 +4997,9 @@  range_op_cast_tests ()
     {
       r0 = range_nonzero (integer_type_node);
       range_cast (r0, short_integer_type_node);
-      r1 = int_range<1> (TYPE_MIN_VALUE (short_integer_type_node),
-			 TYPE_MAX_VALUE (short_integer_type_node));
+      r1 = int_range<1> (short_integer_type_node,
+			 min_limit (short_integer_type_node),
+			 max_limit (short_integer_type_node));
       ASSERT_TRUE (r0 == r1);
     }
 
@@ -5010,8 +5009,8 @@  range_op_cast_tests ()
   // Converting this to 32-bits signed is [-MIN_16,-1][1, +MAX_16].
   r0 = range_nonzero (short_integer_type_node);
   range_cast (r0, integer_type_node);
-  r1 = int_range<1> (INT (-32768), INT (-1));
-  r2 = int_range<1> (INT (1), INT (32767));
+  r1 = int_range<1> (integer_type_node, INT (-32768), INT (-1));
+  r2 = int_range<1> (integer_type_node, INT (1), INT (32767));
   r1.union_ (r2);
   ASSERT_TRUE (r0 == r1);
 }
@@ -5024,17 +5023,16 @@  range_op_lshift_tests ()
   {
     int_range_max res;
     tree big_type = long_long_unsigned_type_node;
+    unsigned big_prec = TYPE_PRECISION (big_type);
     // big_num = 0x808,0000,0000,0000
-    tree big_num = fold_build2 (LSHIFT_EXPR, big_type,
-				build_int_cst (big_type, 0x808),
-				build_int_cst (big_type, 48));
+    wide_int big_num = wi::lshift (wi::uhwi (0x808, big_prec),
+				   wi::uhwi (48, big_prec));
     op_bitwise_and.fold_range (res, big_type,
 			       int_range <1> (big_type),
-			       int_range <1> (big_num, big_num));
+			       int_range <1> (big_type, big_num, big_num));
     // val = 0x8,0000,0000,0000
-    tree val = fold_build2 (LSHIFT_EXPR, big_type,
-			    build_int_cst (big_type, 0x8),
-			    build_int_cst (big_type, 48));
+    wide_int val = wi::lshift (wi::uhwi (8, big_prec),
+			       wi::uhwi (48, big_prec));
     ASSERT_TRUE (res.contains_p (val));
   }
 
@@ -5042,13 +5040,13 @@  range_op_lshift_tests ()
     {
       // unsigned VARYING = op1 << 1 should be VARYING.
       int_range<2> lhs (unsigned_type_node);
-      int_range<2> shift (INT (1), INT (1));
+      int_range<2> shift (unsigned_type_node, INT (1), INT (1));
       int_range_max op1;
       op_lshift.op1_range (op1, unsigned_type_node, lhs, shift);
       ASSERT_TRUE (op1.varying_p ());
 
       // 0 = op1 << 1  should be [0,0], [0x8000000, 0x8000000].
-      int_range<2> zero (UINT (0), UINT (0));
+      int_range<2> zero (unsigned_type_node, UINT (0), UINT (0));
       op_lshift.op1_range (op1, unsigned_type_node, zero, shift);
       ASSERT_TRUE (op1.num_pairs () == 2);
       // Remove the [0,0] range.
@@ -5065,13 +5063,13 @@  range_op_lshift_tests ()
     {
       // unsigned VARYING = op1 << 1 should be VARYING.
       int_range<2> lhs (integer_type_node);
-      int_range<2> shift (INT (1), INT (1));
+      int_range<2> shift (integer_type_node, INT (1), INT (1));
       int_range_max op1;
       op_lshift.op1_range (op1, integer_type_node, lhs, shift);
       ASSERT_TRUE (op1.varying_p ());
 
       //  0 = op1 << 1  should be [0,0], [0x8000000, 0x8000000].
-      int_range<2> zero (INT (0), INT (0));
+      int_range<2> zero (integer_type_node, INT (0), INT (0));
       op_lshift.op1_range (op1, integer_type_node, zero, shift);
       ASSERT_TRUE (op1.num_pairs () == 2);
       // Remove the [0,0] range.
@@ -5090,10 +5088,11 @@  range_op_rshift_tests ()
 {
   // unsigned: [3, MAX] = OP1 >> 1
   {
-    int_range_max lhs (build_int_cst (unsigned_type_node, 3),
-		       TYPE_MAX_VALUE (unsigned_type_node));
-    int_range_max one (build_one_cst (unsigned_type_node),
-		       build_one_cst (unsigned_type_node));
+    int_range_max lhs (unsigned_type_node,
+		       UINT (3), max_limit (unsigned_type_node));
+    int_range_max one (unsigned_type_node,
+		       wi::one (TYPE_PRECISION (unsigned_type_node)),
+		       wi::one (TYPE_PRECISION (unsigned_type_node)));
     int_range_max op1;
     op_rshift.op1_range (op1, unsigned_type_node, lhs, one);
     ASSERT_FALSE (op1.contains_p (UINT (3)));
@@ -5101,8 +5100,9 @@  range_op_rshift_tests ()
 
   // signed: [3, MAX] = OP1 >> 1
   {
-    int_range_max lhs (INT (3), TYPE_MAX_VALUE (integer_type_node));
-    int_range_max one (INT (1), INT (1));
+    int_range_max lhs (integer_type_node,
+		       INT (3), max_limit (integer_type_node));
+    int_range_max one (integer_type_node, INT (1), INT (1));
     int_range_max op1;
     op_rshift.op1_range (op1, integer_type_node, lhs, one);
     ASSERT_FALSE (op1.contains_p (INT (-2)));
@@ -5111,9 +5111,10 @@  range_op_rshift_tests ()
   // This is impossible, so OP1 should be [].
   // signed: [MIN, MIN] = OP1 >> 1
   {
-    int_range_max lhs (TYPE_MIN_VALUE (integer_type_node),
-		       TYPE_MIN_VALUE (integer_type_node));
-    int_range_max one (INT (1), INT (1));
+    int_range_max lhs (integer_type_node,
+		       min_limit (integer_type_node),
+		       min_limit (integer_type_node));
+    int_range_max one (integer_type_node, INT (1), INT (1));
     int_range_max op1;
     op_rshift.op1_range (op1, integer_type_node, lhs, one);
     ASSERT_TRUE (op1.undefined_p ());
@@ -5122,8 +5123,8 @@  range_op_rshift_tests ()
   // signed: ~[-1] = OP1 >> 31
   if (TYPE_PRECISION (integer_type_node) > 31)
     {
-      int_range_max lhs (INT (-1), INT (-1), VR_ANTI_RANGE);
-      int_range_max shift (INT (31), INT (31));
+      int_range_max lhs (integer_type_node, INT (-1), INT (-1), VR_ANTI_RANGE);
+      int_range_max shift (integer_type_node, INT (31), INT (31));
       int_range_max op1;
       op_rshift.op1_range (op1, integer_type_node, lhs, shift);
       int_range_max negatives = range_negatives (integer_type_node);
@@ -5136,13 +5137,11 @@  static void
 range_op_bitwise_and_tests ()
 {
   int_range_max res;
-  tree min = vrp_val_min (integer_type_node);
-  tree max = vrp_val_max (integer_type_node);
-  tree tiny = fold_build2 (PLUS_EXPR, integer_type_node, min,
-			   build_one_cst (integer_type_node));
-  int_range_max i1 (tiny, max);
-  int_range_max i2 (build_int_cst (integer_type_node, 255),
-		    build_int_cst (integer_type_node, 255));
+  wide_int min = min_limit (integer_type_node);
+  wide_int max = max_limit (integer_type_node);
+  wide_int tiny = wi::add (min, wi::one (TYPE_PRECISION (integer_type_node)));
+  int_range_max i1 (integer_type_node, tiny, max);
+  int_range_max i2 (integer_type_node, INT (255), INT (255));
 
   // [MIN+1, MAX] = OP1 & 255: OP1 is VARYING
   op_bitwise_and.op1_range (res, integer_type_node, i1, i2);
@@ -5155,8 +5154,8 @@  range_op_bitwise_and_tests ()
 
   // For 0 = x & MASK, x is ~MASK.
   {
-    int_range<2> zero (integer_zero_node, integer_zero_node);
-    int_range<2> mask = int_range<2> (INT (7), INT (7));
+    int_range<2> zero (integer_type_node, INT (0), INT (0));
+    int_range<2> mask = int_range<2> (integer_type_node, INT (7), INT (7));
     op_bitwise_and.op1_range (res, integer_type_node, zero, mask);
     wide_int inv = wi::shwi (~7U, TYPE_PRECISION (integer_type_node));
     ASSERT_TRUE (res.get_nonzero_bits () == inv);
@@ -5169,7 +5168,7 @@  range_op_bitwise_and_tests ()
   ASSERT_TRUE (res.nonzero_p ());
 
   // (NEGATIVE | X) is nonzero.
-  i1 = int_range<1> (INT (-5), INT (-3));
+  i1 = int_range<1> (integer_type_node, INT (-5), INT (-3));
   i2.set_varying (integer_type_node);
   op_bitwise_or.fold_range (res, integer_type_node, i1, i2);
   ASSERT_FALSE (res.contains_p (INT (0)));
@@ -5179,22 +5178,22 @@  static void
 range_relational_tests ()
 {
   int_range<2> lhs (unsigned_char_type_node);
-  int_range<2> op1 (UCHAR (8), UCHAR (10));
-  int_range<2> op2 (UCHAR (20), UCHAR (20));
+  int_range<2> op1 (unsigned_char_type_node, UCHAR (8), UCHAR (10));
+  int_range<2> op2 (unsigned_char_type_node, UCHAR (20), UCHAR (20));
 
   // Never wrapping additions mean LHS > OP1.
   relation_kind code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_VARYING);
   ASSERT_TRUE (code == VREL_GT);
 
   // Most wrapping additions mean nothing...
-  op1 = int_range<2> (UCHAR (8), UCHAR (10));
-  op2 = int_range<2> (UCHAR (0), UCHAR (255));
+  op1 = int_range<2> (unsigned_char_type_node, UCHAR (8), UCHAR (10));
+  op2 = int_range<2> (unsigned_char_type_node, UCHAR (0), UCHAR (255));
   code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_VARYING);
   ASSERT_TRUE (code == VREL_VARYING);
 
   // However, always wrapping additions mean LHS < OP1.
-  op1 = int_range<2> (UCHAR (1), UCHAR (255));
-  op2 = int_range<2> (UCHAR (255), UCHAR (255));
+  op1 = int_range<2> (unsigned_char_type_node, UCHAR (1), UCHAR (255));
+  op2 = int_range<2> (unsigned_char_type_node, UCHAR (255), UCHAR (255));
   code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_VARYING);
   ASSERT_TRUE (code == VREL_LT);
 }
diff --git a/gcc/range.cc b/gcc/range.cc
index d9e9e0c788c..7c4a83032d7 100644
--- a/gcc/range.cc
+++ b/gcc/range.cc
@@ -32,14 +32,15 @@  along with GCC; see the file COPYING3.  If not see
 value_range
 range_zero (tree type)
 {
-  return value_range (build_zero_cst (type), build_zero_cst (type));
+  wide_int zero = wi::zero (TYPE_PRECISION (type));
+  return value_range (type, zero, zero);
 }
 
 value_range
 range_nonzero (tree type)
 {
-  return value_range (build_zero_cst (type), build_zero_cst (type),
-		      VR_ANTI_RANGE);
+  wide_int zero = wi::zero (TYPE_PRECISION (type));
+  return value_range (type, zero, zero, VR_ANTI_RANGE);
 }
 
 value_range
diff --git a/gcc/range.h b/gcc/range.h
index 3b0e9efffbf..f6a55baf80e 100644
--- a/gcc/range.h
+++ b/gcc/range.h
@@ -29,30 +29,30 @@  value_range range_negatives (tree type);
 // Return an irange instance that is a boolean TRUE.
 
 inline int_range<1>
-range_true (tree type)
+range_true (tree type = boolean_type_node)
 {
   unsigned prec = TYPE_PRECISION (type);
-  return int_range<2> (type, wi::one (prec), wi::one (prec));
+  return int_range<1> (type, wi::one (prec), wi::one (prec));
 }
 
 // Return an irange instance that is a boolean FALSE.
 
 inline int_range<1>
-range_false (tree type)
+range_false (tree type = boolean_type_node)
 {
   unsigned prec = TYPE_PRECISION (type);
-  return int_range<2> (type, wi::zero (prec), wi::zero (prec));
+  return int_range<1> (type, wi::zero (prec), wi::zero (prec));
 }
 
 // Return an irange that covers both true and false.
 
 inline int_range<1>
-range_true_and_false (tree type)
+range_true_and_false (tree type = boolean_type_node)
 {
   unsigned prec = TYPE_PRECISION (type);
   if (prec == 1)
-    return int_range<2> (type);
-  return int_range<2> (type, wi::zero (prec), wi::one (prec));
+    return int_range<1> (type);
+  return int_range<1> (type, wi::zero (prec), wi::one (prec));
 }
 
 #endif // GCC_RANGE_H
diff --git a/gcc/tree-data-ref.cc b/gcc/tree-data-ref.cc
index b3a1d410cbd..b576cce6db6 100644
--- a/gcc/tree-data-ref.cc
+++ b/gcc/tree-data-ref.cc
@@ -769,7 +769,10 @@  split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
       *var = size_int (0);
       *off = fold_convert (ssizetype, op0);
       if (result_range)
-	result_range->set (op0, op0);
+	{
+	  wide_int w = wi::to_wide (op0);
+	  result_range->set (TREE_TYPE (op0), w, w);
+	}
       return true;
 
     case POINTER_PLUS_EXPR:
@@ -795,7 +798,7 @@  split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
 	return false;
 
       split_constant_offset (op0, &var0, &off0, &op0_range, cache, limit);
-      op1_range.set (op1, op1);
+      op1_range.set (TREE_TYPE (op1), wi::to_wide (op1), wi::to_wide (op1));
       *off = size_binop (MULT_EXPR, off0, fold_convert (ssizetype, op1));
       if (!compute_distributive_range (type, op0_range, code, op1_range,
 				       off, result_range))
diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
index 83c2c1c6792..692e8ce7c38 100644
--- a/gcc/tree-ssa-loop-ch.cc
+++ b/gcc/tree-ssa-loop-ch.cc
@@ -79,15 +79,15 @@  entry_loop_condition_is_static (class loop *l, gimple_ranger *ranger)
   if (!loop_exit_edge_p (l, true_e) && !loop_exit_edge_p (l, false_e))
     return false;
 
-  tree desired_static_value;
+  int_range<1> desired_static_range;
   if (loop_exit_edge_p (l, true_e))
-    desired_static_value = boolean_false_node;
+    desired_static_range = range_false ();
   else
-    desired_static_value = boolean_true_node;
+    desired_static_range = range_true ();
 
   int_range<2> r;
   edge_range_query (r, e, last, *ranger);
-  return r == int_range<2> (desired_static_value, desired_static_value);
+  return r == desired_static_range;
 }
 
 /* Check whether we should duplicate HEADER of LOOP.  At most *LIMIT
diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
index 588610eaa47..081fb42ba54 100644
--- a/gcc/tree-ssa-loop-unswitch.cc
+++ b/gcc/tree-ssa-loop-unswitch.cc
@@ -142,14 +142,14 @@  struct unswitch_predicate
 	auto range_op = range_op_handler (code, TREE_TYPE (lhs));
 	int_range<2> rhs_range (TREE_TYPE (rhs));
 	if (CONSTANT_CLASS_P (rhs))
-	  rhs_range.set (rhs, rhs);
+	  {
+	    wide_int w = wi::to_wide (rhs);
+	    rhs_range.set (TREE_TYPE (rhs), w, w);
+	  }
 	if (!range_op.op1_range (true_range, TREE_TYPE (lhs),
-				 int_range<2> (boolean_true_node,
-					       boolean_true_node), rhs_range)
+				 range_true (), rhs_range)
 	    || !range_op.op1_range (false_range, TREE_TYPE (lhs),
-				    int_range<2> (boolean_false_node,
-						  boolean_false_node),
-				    rhs_range))
+				    range_false (), rhs_range))
 	  {
 	    true_range.set_varying (TREE_TYPE (lhs));
 	    false_range.set_varying (TREE_TYPE (lhs));
@@ -605,12 +605,13 @@  find_unswitching_predicates_for_bb (basic_block bb, class loop *loop,
 	      tree cmp1 = fold_build2 (GE_EXPR, boolean_type_node, idx, low);
 	      tree cmp2 = fold_build2 (LE_EXPR, boolean_type_node, idx, high);
 	      cmp = fold_build2 (BIT_AND_EXPR, boolean_type_node, cmp1, cmp2);
-	      lab_range.set (low, high);
+	      lab_range.set (idx_type, wi::to_wide (low), wi::to_wide (high));
 	    }
 	  else
 	    {
 	      cmp = fold_build2 (EQ_EXPR, boolean_type_node, idx, low);
-	      lab_range.set (low, low);
+	      wide_int w = wi::to_wide (low);
+	      lab_range.set (idx_type, w, w);
 	    }
 
 	  /* Combine the expression with the existing one.  */
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 4b43f1abdbc..874526f0baa 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -1138,7 +1138,8 @@  value_replacement (basic_block cond_bb, basic_block middle_bb,
 		      if (get_global_range_query ()->range_of_expr (r, phires,
 								    phi))
 			{
-			  int_range<2> tmp (carg, carg);
+			  wide_int warg = wi::to_wide (carg);
+			  int_range<2> tmp (TREE_TYPE (carg), warg, warg);
 			  r.union_ (tmp);
 			  reset_flow_sensitive_info (phires);
 			  set_range_info (phires, r);
diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc
index 962b33d88da..d5da4b0c1b1 100644
--- a/gcc/tree-ssa-threadbackward.cc
+++ b/gcc/tree-ssa-threadbackward.cc
@@ -327,8 +327,8 @@  back_threader::find_taken_edge_cond (const vec<basic_block> &path,
   if (solver.unreachable_path_p ())
     return UNREACHABLE_EDGE;
 
-  int_range<2> true_range (boolean_true_node, boolean_true_node);
-  int_range<2> false_range (boolean_false_node, boolean_false_node);
+  int_range<2> true_range = range_true ();
+  int_range<2> false_range = range_false ();
 
   if (r == true_range || r == false_range)
     {
diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc
index b6cbf97b878..a510dfa031a 100644
--- a/gcc/tree-ssanames.cc
+++ b/gcc/tree-ssanames.cc
@@ -522,10 +522,9 @@  ssa_name_has_boolean_range (tree op)
   if (INTEGRAL_TYPE_P (TREE_TYPE (op))
       && (TYPE_PRECISION (TREE_TYPE (op)) > 1))
     {
-      int_range<2> onezero (build_zero_cst (TREE_TYPE (op)),
-			    build_one_cst (TREE_TYPE (op)));
       int_range<2> r;
-      if (get_range_query (cfun)->range_of_expr (r, op) && r == onezero)
+      if (get_range_query (cfun)->range_of_expr (r, op)
+	  && r == range_true_and_false (TREE_TYPE (op)))
 	return true;
 
       if (wi::eq_p (get_nonzero_bits (op), 1))
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index c0dcd50ee01..d28637b1918 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -837,7 +837,9 @@  find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
       tree label = gimple_switch_label (switch_stmt, i);
       tree case_high
 	= CASE_HIGH (label) ? CASE_HIGH (label) : CASE_LOW (label);
-      int_range_max label_range (CASE_LOW (label), case_high);
+      int_range_max label_range (type,
+				 wi::to_wide (CASE_LOW (label)),
+				 wi::to_wide (case_high));
       if (!types_compatible_p (label_range.type (), range_of_op->type ()))
 	range_cast (label_range, range_of_op->type ());
       label_range.intersect (*range_of_op);
@@ -861,7 +863,9 @@  find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
       tree case_high = CASE_HIGH (max_label);
       if (!case_high)
 	case_high = CASE_LOW (max_label);
-      int_range_max label_range (CASE_LOW (min_label), case_high);
+      int_range_max label_range (TREE_TYPE (CASE_LOW (min_label)),
+				 wi::to_wide (CASE_LOW (min_label)),
+				 wi::to_wide (case_high));
       if (!types_compatible_p (label_range.type (), range_of_op->type ()))
 	range_cast (label_range, range_of_op->type ());
       label_range.intersect (*range_of_op);
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 8ccdc9f8852..43297f17c39 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -176,16 +176,21 @@  range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
   switch (TREE_CODE (expr))
     {
     case INTEGER_CST:
-      if (TREE_OVERFLOW_P (expr))
-	expr = drop_tree_overflow (expr);
-      r.set (expr, expr);
-      return true;
+      {
+	irange &i = as_a <irange> (r);
+	if (TREE_OVERFLOW_P (expr))
+	  expr = drop_tree_overflow (expr);
+	wide_int w = wi::to_wide (expr);
+	i.set (TREE_TYPE (expr), w, w);
+	return true;
+      }
 
     case REAL_CST:
       {
 	frange &f = as_a <frange> (r);
-	f.set (expr, expr);
-	if (!real_isnan (TREE_REAL_CST_PTR (expr)))
+	REAL_VALUE_TYPE *rv = TREE_REAL_CST_PTR (expr);
+	f.set (TREE_TYPE (expr), *rv, *rv);
+	if (!real_isnan (rv))
 	  f.clear_nan ();
 	return true;
       }
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 69b214ecc06..f2148722a3a 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -301,7 +301,9 @@  irange::fits_p (const vrange &r) const
 void
 irange::set_nonnegative (tree type)
 {
-  set (build_int_cst (type, 0), TYPE_MAX_VALUE (type));
+  set (type,
+       wi::zero (TYPE_PRECISION (type)),
+       wi::to_wide (TYPE_MAX_VALUE (type)));
 }
 
 void
@@ -700,13 +702,12 @@  frange::operator== (const frange &src) const
   return false;
 }
 
-// Return TRUE if range contains the TREE_REAL_CST_PTR in CST.
+// Return TRUE if range contains R.
 
 bool
-frange::contains_p (tree cst) const
+frange::contains_p (const REAL_VALUE_TYPE &r) const
 {
   gcc_checking_assert (m_kind != VR_ANTI_RANGE);
-  const REAL_VALUE_TYPE *rv = TREE_REAL_CST_PTR (cst);
 
   if (undefined_p ())
     return false;
@@ -714,7 +715,7 @@  frange::contains_p (tree cst) const
   if (varying_p ())
     return true;
 
-  if (real_isnan (rv))
+  if (real_isnan (&r))
     {
       // No NAN in range.
       if (!m_pos_nan && !m_neg_nan)
@@ -722,16 +723,16 @@  frange::contains_p (tree cst) const
       // Both +NAN and -NAN are present.
       if (m_pos_nan && m_neg_nan)
 	return true;
-      return m_neg_nan == rv->sign;
+      return m_neg_nan == r.sign;
     }
   if (known_isnan ())
     return false;
 
-  if (real_compare (GE_EXPR, rv, &m_min) && real_compare (LE_EXPR, rv, &m_max))
+  if (real_compare (GE_EXPR, &r, &m_min) && real_compare (LE_EXPR, &r, &m_max))
     {
       // Make sure the signs are equal for signed zeros.
-      if (HONOR_SIGNED_ZEROS (m_type) && real_iszero (rv))
-	return rv->sign == m_min.sign || rv->sign == m_max.sign;
+      if (HONOR_SIGNED_ZEROS (m_type) && real_iszero (&r))
+	return r.sign == m_min.sign || r.sign == m_max.sign;
       return true;
     }
   return false;
@@ -743,7 +744,7 @@  frange::contains_p (tree cst) const
 // A NAN can never be a singleton.
 
 bool
-frange::singleton_p (tree *result) const
+frange::internal_singleton_p (REAL_VALUE_TYPE *result) const
 {
   if (m_kind == VR_RANGE && real_identical (&m_min, &m_max))
     {
@@ -766,6 +767,18 @@  frange::singleton_p (tree *result) const
 	    return false;
 	}
 
+      if (result)
+	*result = m_min;
+      return true;
+    }
+  return false;
+}
+
+bool
+frange::singleton_p (tree *result) const
+{
+  if (internal_singleton_p ())
+    {
       if (result)
 	*result = build_real (m_type, m_min);
       return true;
@@ -773,6 +786,12 @@  frange::singleton_p (tree *result) const
   return false;
 }
 
+bool
+frange::singleton_p (REAL_VALUE_TYPE &r) const
+{
+  return internal_singleton_p (&r);
+}
+
 bool
 frange::supports_type_p (const_tree type) const
 {
@@ -942,13 +961,10 @@  get_legacy_range (const irange &r, tree &min, tree &max)
 }
 
 void
-irange::irange_set (tree min, tree max)
+irange::irange_set (tree type, const wide_int &min, const wide_int &max)
 {
-  gcc_checking_assert (!POLY_INT_CST_P (min));
-  gcc_checking_assert (!POLY_INT_CST_P (max));
-
-  m_base[0] = min;
-  m_base[1] = max;
+  m_base[0] = wide_int_to_tree (type, min);
+  m_base[1] = wide_int_to_tree (type, max);
   m_num_ranges = 1;
   m_kind = VR_RANGE;
   m_nonzero_mask = NULL;
@@ -959,26 +975,31 @@  irange::irange_set (tree min, tree max)
 }
 
 void
-irange::irange_set_1bit_anti_range (tree min, tree max)
+irange::irange_set_1bit_anti_range (tree type,
+				    const wide_int &min, const wide_int &max)
 {
-  tree type = TREE_TYPE (min);
   gcc_checking_assert (TYPE_PRECISION (type) == 1);
 
-  if (operand_equal_p (min, max))
+  if (min == max)
     {
       // Since these are 1-bit quantities, they can only be [MIN,MIN]
       // or [MAX,MAX].
-      if (vrp_val_is_min (min))
-	min = max = vrp_val_max (type);
+      if (min == wi::to_wide (TYPE_MIN_VALUE (type)))
+	{
+	  wide_int tmp = wi::to_wide (TYPE_MAX_VALUE (type));
+	  set (type, tmp, tmp);
+	}
       else
-	min = max = vrp_val_min (type);
-      set (min, max);
+	{
+	  wide_int tmp = wi::to_wide (TYPE_MIN_VALUE (type));
+	  set (type, tmp, tmp);
+	}
     }
   else
     {
       // The only alternative is [MIN,MAX], which is the empty range.
-      gcc_checking_assert (vrp_val_is_min (min));
-      gcc_checking_assert (vrp_val_is_max (max));
+      gcc_checking_assert (min == wi::to_wide (TYPE_MIN_VALUE (type)));
+      gcc_checking_assert (max == wi::to_wide (TYPE_MAX_VALUE (type)));
       set_undefined ();
     }
   if (flag_checking)
@@ -986,43 +1007,38 @@  irange::irange_set_1bit_anti_range (tree min, tree max)
 }
 
 void
-irange::irange_set_anti_range (tree min, tree max)
+irange::irange_set_anti_range (tree type,
+			       const wide_int &min, const wide_int &max)
 {
-  gcc_checking_assert (!POLY_INT_CST_P (min));
-  gcc_checking_assert (!POLY_INT_CST_P (max));
-
-  if (TYPE_PRECISION (TREE_TYPE (min)) == 1)
+  if (TYPE_PRECISION (type) == 1)
     {
-      irange_set_1bit_anti_range (min, max);
+      irange_set_1bit_anti_range (type, min, max);
       return;
     }
 
   // set an anti-range
-  tree type = TREE_TYPE (min);
   signop sign = TYPE_SIGN (type);
   int_range<2> type_range (type);
   // Calculate INVERSE([I,J]) as [-MIN, I-1][J+1, +MAX].
   m_num_ranges = 0;
   wi::overflow_type ovf;
 
-  wide_int w_min = wi::to_wide (min);
-  if (wi::ne_p (w_min, type_range.lower_bound ()))
+  if (wi::ne_p (min, type_range.lower_bound ()))
     {
-      wide_int lim1 = wi::sub (w_min, 1, sign, &ovf);
+      wide_int lim1 = wi::sub (min, 1, sign, &ovf);
       gcc_checking_assert (ovf != wi::OVF_OVERFLOW);
       m_base[0] = wide_int_to_tree (type, type_range.lower_bound (0));
       m_base[1] = wide_int_to_tree (type, lim1);
       m_num_ranges = 1;
     }
-  wide_int w_max = wi::to_wide (max);
-  if (wi::ne_p (w_max, type_range.upper_bound ()))
+  if (wi::ne_p (max, type_range.upper_bound ()))
     {
       if (m_max_ranges == 1 && m_num_ranges)
 	{
 	  set_varying (type);
 	  return;
 	}
-      wide_int lim2 = wi::add (w_max, 1, sign, &ovf);
+      wide_int lim2 = wi::add (max, 1, sign, &ovf);
       gcc_checking_assert (ovf != wi::OVF_OVERFLOW);
       m_base[m_num_ranges * 2] = wide_int_to_tree (type, lim2);
       m_base[m_num_ranges * 2 + 1]
@@ -1047,6 +1063,36 @@  irange::irange_set_anti_range (tree min, tree max)
    This routine exists to ease canonicalization in the case where we
    extract ranges from var + CST op limit.  */
 
+void
+irange::set (tree type, const wide_int &rmin, const wide_int &rmax,
+	     value_range_kind kind)
+{
+  if (kind == VR_UNDEFINED)
+    {
+      irange::set_undefined ();
+      return;
+    }
+
+  if (kind == VR_VARYING)
+    {
+      set_varying (type);
+      return;
+    }
+
+  signop sign = TYPE_SIGN (type);
+  unsigned prec = TYPE_PRECISION (type);
+  wide_int min = wide_int::from (rmin, prec, sign);
+  wide_int max = wide_int::from (rmax, prec, sign);
+
+  if (kind == VR_RANGE)
+    irange_set (type, min, max);
+  else
+    {
+      gcc_checking_assert (kind == VR_ANTI_RANGE);
+      irange_set_anti_range (type, min, max);
+    }
+}
+
 void
 irange::set (tree min, tree max, value_range_kind kind)
 {
@@ -1072,13 +1118,8 @@  irange::set (tree min, tree max, value_range_kind kind)
   if (TREE_OVERFLOW_P (max))
     max = drop_tree_overflow (max);
 
-  if (kind == VR_RANGE)
-    irange_set (min, max);
-  else
-    {
-      gcc_checking_assert (kind == VR_ANTI_RANGE);
-      irange_set_anti_range (min, max);
-    }
+  return set (TREE_TYPE (min),
+	      wi::to_wide (min), wi::to_wide (max), kind);
 }
 
 // Check the validity of the range.
@@ -1138,9 +1179,7 @@  irange::operator== (const irange &other) const
   return nz1 == nz2;
 }
 
-/* If range is a singleton, place it in RESULT and return TRUE.
-   Note: A singleton can be any gimple invariant, not just constants.
-   So, [&x, &x] counts as a singleton.  */
+/* If range is a singleton, place it in RESULT and return TRUE.  */
 
 bool
 irange::singleton_p (tree *result) const
@@ -1154,37 +1193,41 @@  irange::singleton_p (tree *result) const
   return false;
 }
 
-/* Return TRUE if range contains INTEGER_CST.  */
-/* Return 1 if VAL is inside value range.
-	  0 if VAL is not inside value range.
+bool
+irange::singleton_p (wide_int &w) const
+{
+  if (num_pairs () == 1 && lower_bound () == upper_bound ())
+    {
+      w = lower_bound ();
+      return true;
+    }
+  return false;
+}
+
+/* Return 1 if CST is inside value range.
+	  0 if CST is not inside value range.
 
    Benchmark compile/20001226-1.c compilation time after changing this
    function.  */
 
-
 bool
-irange::contains_p (tree cst) const
+irange::contains_p (const wide_int &cst) const
 {
   if (undefined_p ())
     return false;
 
-  gcc_checking_assert (TREE_CODE (cst) == INTEGER_CST);
-
   // See if we can exclude CST based on the nonzero bits.
-  if (m_nonzero_mask)
-    {
-      wide_int cstw = wi::to_wide (cst);
-      if (cstw != 0 && wi::bit_and (wi::to_wide (m_nonzero_mask), cstw) == 0)
-	return false;
-    }
+  if (m_nonzero_mask
+      && cst != 0
+      && wi::bit_and (wi::to_wide (m_nonzero_mask), cst) == 0)
+    return false;
 
-  signop sign = TYPE_SIGN (TREE_TYPE (cst));
-  wide_int v = wi::to_wide (cst);
+  signop sign = TYPE_SIGN (type ());
   for (unsigned r = 0; r < m_num_ranges; ++r)
     {
-      if (wi::lt_p (v, lower_bound (r), sign))
+      if (wi::lt_p (cst, lower_bound (r), sign))
 	return false;
-      if (wi::le_p (v, upper_bound (r), sign))
+      if (wi::le_p (cst, upper_bound (r), sign))
 	return true;
     }
 
@@ -1760,10 +1803,10 @@  irange::set_range_from_nonzero_bits ()
   if (popcount == 1)
     {
       // Make sure we don't pessimize the range.
-      if (!contains_p (m_nonzero_mask))
+      if (!contains_p (wi::to_wide (m_nonzero_mask)))
 	return false;
 
-      bool has_zero = contains_p (build_zero_cst (type ()));
+      bool has_zero = contains_zero_p (*this);
       tree nz = m_nonzero_mask;
       set (nz, nz);
       m_nonzero_mask = nz;
@@ -2085,7 +2128,6 @@  gt_ggc_mx (int_range<2> *&x)
 }
 
 #define DEFINE_INT_RANGE_INSTANCE(N)					\
-  template int_range<N>::int_range(tree, tree, value_range_kind);	\
   template int_range<N>::int_range(tree_node *,				\
 				   const wide_int &,			\
 				   const wide_int &,			\
@@ -2103,20 +2145,73 @@  DEFINE_INT_RANGE_INSTANCE(255)
 #if CHECKING_P
 #include "selftest.h"
 
+#define INT(x) wi::shwi ((x), TYPE_PRECISION (integer_type_node))
+#define UINT(x) wi::uhwi ((x), TYPE_PRECISION (unsigned_type_node))
+#define SCHAR(x) wi::shwi ((x), TYPE_PRECISION (signed_char_type_node))
+
 namespace selftest
 {
-#define INT(N) build_int_cst (integer_type_node, (N))
-#define UINT(N) build_int_cstu (unsigned_type_node, (N))
-#define UINT128(N) build_int_cstu (u128_type, (N))
-#define UCHAR(N) build_int_cstu (unsigned_char_type_node, (N))
-#define SCHAR(N) build_int_cst (signed_char_type_node, (N))
+
+static int_range<2>
+range (tree type, int a, int b, value_range_kind kind = VR_RANGE)
+{
+  wide_int w1, w2;
+  if (TYPE_UNSIGNED (type))
+    {
+      w1 = wi::uhwi (a, TYPE_PRECISION (type));
+      w2 = wi::uhwi (b, TYPE_PRECISION (type));
+    }
+  else
+    {
+      w1 = wi::shwi (a, TYPE_PRECISION (type));
+      w2 = wi::shwi (b, TYPE_PRECISION (type));
+    }
+  return int_range<2> (type, w1, w2, kind);
+}
+
+static int_range<2>
+tree_range (tree a, tree b, value_range_kind kind = VR_RANGE)
+{
+  return int_range<2> (TREE_TYPE (a), wi::to_wide (a), wi::to_wide (b), kind);
+}
+
+static int_range<2>
+range_int (int a, int b, value_range_kind kind = VR_RANGE)
+{
+  return range (integer_type_node, a, b, kind);
+}
+
+static int_range<2>
+range_uint (int a, int b, value_range_kind kind = VR_RANGE)
+{
+  return range (unsigned_type_node, a, b, kind);
+}
+
+static int_range<2>
+range_uint128 (int a, int b, value_range_kind kind = VR_RANGE)
+{
+  tree u128_type_node = build_nonstandard_integer_type (128, 1);
+  return range (u128_type_node, a, b, kind);
+}
+
+static int_range<2>
+range_uchar (int a, int b, value_range_kind kind = VR_RANGE)
+{
+  return range (unsigned_char_type_node, a, b, kind);
+}
+
+static int_range<2>
+range_char (int a, int b, value_range_kind kind = VR_RANGE)
+{
+  return range (signed_char_type_node, a, b, kind);
+}
 
 static int_range<3>
 build_range3 (int a, int b, int c, int d, int e, int f)
 {
-  int_range<3> i1 (INT (a), INT (b));
-  int_range<3> i2 (INT (c), INT (d));
-  int_range<3> i3 (INT (e), INT (f));
+  int_range<3> i1 = range_int (a, b);
+  int_range<3> i2 = range_int (c, d);
+  int_range<3> i3 = range_int (e, f);
   i1.union_ (i2);
   i1.union_ (i3);
   return i1;
@@ -2125,76 +2220,75 @@  build_range3 (int a, int b, int c, int d, int e, int f)
 static void
 range_tests_irange3 ()
 {
-  typedef int_range<3> int_range3;
-  int_range3 r0, r1, r2;
-  int_range3 i1, i2, i3;
+  int_range<3> r0, r1, r2;
+  int_range<3> i1, i2, i3;
 
   // ([10,20] U [5,8]) U [1,3] ==> [1,3][5,8][10,20].
-  r0 = int_range3 (INT (10), INT (20));
-  r1 = int_range3 (INT (5), INT (8));
+  r0 = range_int (10, 20);
+  r1 = range_int (5, 8);
   r0.union_ (r1);
-  r1 = int_range3 (INT (1), INT (3));
+  r1 = range_int (1, 3);
   r0.union_ (r1);
   ASSERT_TRUE (r0 == build_range3 (1, 3, 5, 8, 10, 20));
 
   // [1,3][5,8][10,20] U [-5,0] => [-5,3][5,8][10,20].
-  r1 = int_range3 (INT (-5), INT (0));
+  r1 = range_int (-5, 0);
   r0.union_ (r1);
   ASSERT_TRUE (r0 == build_range3 (-5, 3, 5, 8, 10, 20));
 
   // [10,20][30,40] U [50,60] ==> [10,20][30,40][50,60].
-  r1 = int_range3 (INT (50), INT (60));
-  r0 = int_range3 (INT (10), INT (20));
-  r0.union_ (int_range3 (INT (30), INT (40)));
+  r1 = range_int (50, 60);
+  r0 = range_int (10, 20);
+  r0.union_ (range_int (30, 40));
   r0.union_ (r1);
   ASSERT_TRUE (r0 == build_range3 (10, 20, 30, 40, 50, 60));
   // [10,20][30,40][50,60] U [70, 80] ==> [10,20][30,40][50,60][70,80].
-  r1 = int_range3 (INT (70), INT (80));
+  r1 = range_int (70, 80);
   r0.union_ (r1);
 
   r2 = build_range3 (10, 20, 30, 40, 50, 60);
-  r2.union_ (int_range3 (INT (70), INT (80)));
+  r2.union_ (range_int (70, 80));
   ASSERT_TRUE (r0 == r2);
 
   // [10,20][30,40][50,60] U [6,35] => [6,40][50,60].
   r0 = build_range3 (10, 20, 30, 40, 50, 60);
-  r1 = int_range3 (INT (6), INT (35));
+  r1 = range_int (6, 35);
   r0.union_ (r1);
-  r1 = int_range3 (INT (6), INT (40));
-  r1.union_ (int_range3 (INT (50), INT (60)));
+  r1 = range_int (6, 40);
+  r1.union_ (range_int (50, 60));
   ASSERT_TRUE (r0 == r1);
 
   // [10,20][30,40][50,60] U [6,60] => [6,60].
   r0 = build_range3 (10, 20, 30, 40, 50, 60);
-  r1 = int_range3 (INT (6), INT (60));
+  r1 = range_int (6, 60);
   r0.union_ (r1);
-  ASSERT_TRUE (r0 == int_range3 (INT (6), INT (60)));
+  ASSERT_TRUE (r0 == range_int (6, 60));
 
   // [10,20][30,40][50,60] U [6,70] => [6,70].
   r0 = build_range3 (10, 20, 30, 40, 50, 60);
-  r1 = int_range3 (INT (6), INT (70));
+  r1 = range_int (6, 70);
   r0.union_ (r1);
-  ASSERT_TRUE (r0 == int_range3 (INT (6), INT (70)));
+  ASSERT_TRUE (r0 == range_int (6, 70));
 
   // [10,20][30,40][50,60] U [35,70] => [10,20][30,70].
   r0 = build_range3 (10, 20, 30, 40, 50, 60);
-  r1 = int_range3 (INT (35), INT (70));
+  r1 = range_int (35, 70);
   r0.union_ (r1);
-  r1 = int_range3 (INT (10), INT (20));
-  r1.union_ (int_range3 (INT (30), INT (70)));
+  r1 = range_int (10, 20);
+  r1.union_ (range_int (30, 70));
   ASSERT_TRUE (r0 == r1);
 
   // [10,20][30,40][50,60] U [15,35] => [10,40][50,60].
   r0 = build_range3 (10, 20, 30, 40, 50, 60);
-  r1 = int_range3 (INT (15), INT (35));
+  r1 = range_int (15, 35);
   r0.union_ (r1);
-  r1 = int_range3 (INT (10), INT (40));
-  r1.union_ (int_range3 (INT (50), INT (60)));
+  r1 = range_int (10, 40);
+  r1.union_ (range_int (50, 60));
   ASSERT_TRUE (r0 == r1);
 
   // [10,20][30,40][50,60] U [35,35] => [10,20][30,40][50,60].
   r0 = build_range3 (10, 20, 30, 40, 50, 60);
-  r1 = int_range3 (INT (35), INT (35));
+  r1 = range_int (35, 35);
   r0.union_ (r1);
   ASSERT_TRUE (r0 == build_range3 (10, 20, 30, 40, 50, 60));
 }
@@ -2208,7 +2302,7 @@  range_tests_int_range_max ()
   // Build a huge multi-range range.
   for (nrange = 0; nrange < 50; ++nrange)
     {
-      int_range<1> tmp (INT (nrange*10), INT (nrange*10 + 5));
+      int_range<1> tmp = range_int (nrange*10, nrange *10 + 5);
       big.union_ (tmp);
     }
   ASSERT_TRUE (big.num_pairs () == nrange);
@@ -2221,18 +2315,16 @@  range_tests_int_range_max ()
   big.invert ();
   ASSERT_TRUE (big.num_pairs () == nrange + 1);
 
-  int_range<1> tmp (INT (5), INT (37));
+  int_range<1> tmp = range_int (5, 37);
   big.intersect (tmp);
   ASSERT_TRUE (big.num_pairs () == 4);
 
   // Test that [10,10][20,20] does NOT contain 15.
   {
-    int_range_max i1 (build_int_cst (integer_type_node, 10),
-		      build_int_cst (integer_type_node, 10));
-    int_range_max i2 (build_int_cst (integer_type_node, 20),
-		      build_int_cst (integer_type_node, 20));
+    int_range_max i1 = range_int (10, 10);
+    int_range_max i2 = range_int (20, 20);
     i1.union_ (i2);
-    ASSERT_FALSE (i1.contains_p (build_int_cst (integer_type_node, 15)));
+    ASSERT_FALSE (i1.contains_p (INT (15)));
   }
 }
 
@@ -2249,11 +2341,10 @@  range_tests_strict_enum ()
 
   // Test that even though vr1 covers the strict enum domain ([0, 3]),
   // it does not cover the domain of the underlying type.
-  int_range<1> vr1 (build_int_cstu (rtype, 0), build_int_cstu (rtype, 1));
-  int_range<1> vr2 (build_int_cstu (rtype, 2), build_int_cstu (rtype, 3));
+  int_range<1> vr1 = range (rtype, 0, 1);
+  int_range<1> vr2 = range (rtype, 2, 3);
   vr1.union_ (vr2);
-  ASSERT_TRUE (vr1 == int_range<1> (build_int_cstu (rtype, 0),
-				    build_int_cstu (rtype, 3)));
+  ASSERT_TRUE (vr1 == range (rtype, 0, 3));
   ASSERT_FALSE (vr1.varying_p ());
 
   // Test that copying to a multi-range does not change things.
@@ -2262,7 +2353,7 @@  range_tests_strict_enum ()
   ASSERT_FALSE (ir1.varying_p ());
 
   // The same test as above, but using TYPE_{MIN,MAX}_VALUE instead of [0,3].
-  vr1 = int_range<1> (TYPE_MIN_VALUE (rtype), TYPE_MAX_VALUE (rtype));
+  vr1 = tree_range (TYPE_MIN_VALUE (rtype), TYPE_MAX_VALUE (rtype));
   ir1 = vr1;
   ASSERT_TRUE (ir1 == vr1);
   ASSERT_FALSE (ir1.varying_p ());
@@ -2281,8 +2372,8 @@  range_tests_misc ()
   tree one_bit_min = vrp_val_min (one_bit_type);
   tree one_bit_max = vrp_val_max (one_bit_type);
   {
-    int_range<2> min (one_bit_min, one_bit_min);
-    int_range<2> max (one_bit_max, one_bit_max);
+    int_range<2> min = tree_range (one_bit_min, one_bit_min);
+    int_range<2> max = tree_range (one_bit_max, one_bit_max);
     max.union_ (min);
     ASSERT_TRUE (max.varying_p ());
   }
@@ -2291,8 +2382,8 @@  range_tests_misc ()
 
   // Test inversion of 1-bit signed integers.
   {
-    int_range<2> min (one_bit_min, one_bit_min);
-    int_range<2> max (one_bit_max, one_bit_max);
+    int_range<2> min = tree_range (one_bit_min, one_bit_min);
+    int_range<2> max = tree_range (one_bit_max, one_bit_max);
     int_range<2> t;
     t = min;
     t.invert ();
@@ -2303,79 +2394,81 @@  range_tests_misc ()
   }
 
   // Test that NOT(255) is [0..254] in 8-bit land.
-  int_range<1> not_255 (UCHAR (255), UCHAR (255), VR_ANTI_RANGE);
-  ASSERT_TRUE (not_255 == int_range<1> (UCHAR (0), UCHAR (254)));
+  int_range<1> not_255 = range_uchar (255, 255, VR_ANTI_RANGE);
+  ASSERT_TRUE (not_255 == range_uchar (0, 254));
 
   // Test that NOT(0) is [1..255] in 8-bit land.
   int_range<2> not_zero = range_nonzero (unsigned_char_type_node);
-  ASSERT_TRUE (not_zero == int_range<1> (UCHAR (1), UCHAR (255)));
+  ASSERT_TRUE (not_zero == range_uchar (1, 255));
 
   // Check that [0,127][0x..ffffff80,0x..ffffff]
   //  => ~[128, 0x..ffffff7f].
-  r0 = int_range<1> (UINT128 (0), UINT128 (127));
-  tree high = build_minus_one_cst (u128_type);
+  r0 = range_uint128 (0, 127);
+  wide_int high = wi::minus_one (128);
   // low = -1 - 127 => 0x..ffffff80.
-  tree low = fold_build2 (MINUS_EXPR, u128_type, high, UINT128(127));
-  r1 = int_range<1> (low, high); // [0x..ffffff80, 0x..ffffffff]
+  wide_int low = wi::sub (high, wi::uhwi (127, 128));
+  r1 = int_range<1> (u128_type, low, high); // [0x..ffffff80, 0x..ffffffff]
   // r0 = [0,127][0x..ffffff80,0x..fffffff].
   r0.union_ (r1);
   // r1 = [128, 0x..ffffff7f].
-  r1 = int_range<1> (UINT128(128),
-		     fold_build2 (MINUS_EXPR, u128_type,
-				  build_minus_one_cst (u128_type),
-				  UINT128(128)));
+  r1 = int_range<1> (u128_type,
+		     wi::uhwi (128, 128),
+		     wi::sub (wi::minus_one (128), wi::uhwi (128, 128)));
   r0.invert ();
   ASSERT_TRUE (r0 == r1);
 
   r0.set_varying (integer_type_node);
-  tree minint = wide_int_to_tree (integer_type_node, r0.lower_bound ());
-  tree maxint = wide_int_to_tree (integer_type_node, r0.upper_bound ());
+  wide_int minint = r0.lower_bound ();
+  wide_int maxint = r0.upper_bound ();
 
   r0.set_varying (short_integer_type_node);
 
   r0.set_varying (unsigned_type_node);
-  tree maxuint = wide_int_to_tree (unsigned_type_node, r0.upper_bound ());
+  wide_int maxuint = r0.upper_bound ();
 
   // Check that ~[0,5] => [6,MAX] for unsigned int.
-  r0 = int_range<1> (UINT (0), UINT (5));
+  r0 = range_uint (0, 5);
   r0.invert ();
-  ASSERT_TRUE (r0 == int_range<1> (UINT(6), maxuint));
+  ASSERT_TRUE (r0 == int_range<1> (unsigned_type_node,
+				   wi::uhwi (6, TYPE_PRECISION (unsigned_type_node)),
+				   maxuint));
 
   // Check that ~[10,MAX] => [0,9] for unsigned int.
-  r0 = int_range<1> (UINT(10), maxuint);
+  r0 = int_range<1> (unsigned_type_node,
+		     wi::uhwi (10, TYPE_PRECISION (unsigned_type_node)),
+		     maxuint);
   r0.invert ();
-  ASSERT_TRUE (r0 == int_range<1> (UINT (0), UINT (9)));
+  ASSERT_TRUE (r0 == range_uint (0, 9));
 
   // Check that ~[0,5] => [6,MAX] for unsigned 128-bit numbers.
-  r0 = int_range<1> (UINT128 (0), UINT128 (5), VR_ANTI_RANGE);
-  r1 = int_range<1> (UINT128(6), build_minus_one_cst (u128_type));
+  r0 = range_uint128 (0, 5, VR_ANTI_RANGE);
+  r1 = int_range<1> (u128_type, wi::uhwi (6, 128), wi::minus_one (128));
   ASSERT_TRUE (r0 == r1);
 
   // Check that [~5] is really [-MIN,4][6,MAX].
-  r0 = int_range<2> (INT (5), INT (5), VR_ANTI_RANGE);
-  r1 = int_range<1> (minint, INT (4));
-  r1.union_ (int_range<1> (INT (6), maxint));
+  r0 = range_int (5, 5, VR_ANTI_RANGE);
+  r1 = int_range<1> (integer_type_node, minint, INT (4));
+  r1.union_ (int_range<1> (integer_type_node, INT (6), maxint));
   ASSERT_FALSE (r1.undefined_p ());
   ASSERT_TRUE (r0 == r1);
 
-  r1 = int_range<1> (INT (5), INT (5));
+  r1 = range_int (5, 5);
   int_range<2> r2 (r1);
   ASSERT_TRUE (r1 == r2);
 
-  r1 = int_range<1> (INT (5), INT (10));
+  r1 = range_int (5, 10);
 
-  r1 = int_range<1> (integer_type_node,
-		     wi::to_wide (INT (5)), wi::to_wide (INT (10)));
+  r1 = range_int (5, 10);
   ASSERT_TRUE (r1.contains_p (INT (7)));
 
-  r1 = int_range<1> (SCHAR (0), SCHAR (20));
+  r1 = range_char (0, 20);
   ASSERT_TRUE (r1.contains_p (SCHAR(15)));
   ASSERT_FALSE (r1.contains_p (SCHAR(300)));
 
   // NOT([10,20]) ==> [-MIN,9][21,MAX].
-  r0 = r1 = int_range<1> (INT (10), INT (20));
-  r2 = int_range<1> (minint, INT(9));
-  r2.union_ (int_range<1> (INT(21), maxint));
+  r0 = r1 = range_int (10, 20);
+  r2 = int_range<1> (integer_type_node, minint, INT(9));
+  r2.union_ (int_range<1> (integer_type_node, INT(21), maxint));
   ASSERT_FALSE (r2.undefined_p ());
   r1.invert ();
   ASSERT_TRUE (r1 == r2);
@@ -2385,11 +2478,9 @@  range_tests_misc ()
 
   // Test that booleans and their inverse work as expected.
   r0 = range_zero (boolean_type_node);
-  ASSERT_TRUE (r0 == int_range<1> (build_zero_cst (boolean_type_node),
-				   build_zero_cst (boolean_type_node)));
+  ASSERT_TRUE (r0 == range_false ());
   r0.invert ();
-  ASSERT_TRUE (r0 == int_range<1> (build_one_cst (boolean_type_node),
-				   build_one_cst (boolean_type_node)));
+  ASSERT_TRUE (r0 == range_true ());
 
   // Make sure NULL and non-NULL of pointer types work, and that
   // inverses of them are consistent.
@@ -2401,34 +2492,34 @@  range_tests_misc ()
   ASSERT_TRUE (r0 == r1);
 
   // [10,20] U [15, 30] => [10, 30].
-  r0 = int_range<1> (INT (10), INT (20));
-  r1 = int_range<1> (INT (15), INT (30));
+  r0 = range_int (10, 20);
+  r1 = range_int (15, 30);
   r0.union_ (r1);
-  ASSERT_TRUE (r0 == int_range<1> (INT (10), INT (30)));
+  ASSERT_TRUE (r0 == range_int (10, 30));
 
   // [15,40] U [] => [15,40].
-  r0 = int_range<1> (INT (15), INT (40));
+  r0 = range_int (15, 40);
   r1.set_undefined ();
   r0.union_ (r1);
-  ASSERT_TRUE (r0 == int_range<1> (INT (15), INT (40)));
+  ASSERT_TRUE (r0 == range_int (15, 40));
 
   // [10,20] U [10,10] => [10,20].
-  r0 = int_range<1> (INT (10), INT (20));
-  r1 = int_range<1> (INT (10), INT (10));
+  r0 = range_int (10, 20);
+  r1 = range_int (10, 10);
   r0.union_ (r1);
-  ASSERT_TRUE (r0 == int_range<1> (INT (10), INT (20)));
+  ASSERT_TRUE (r0 == range_int (10, 20));
 
   // [10,20] U [9,9] => [9,20].
-  r0 = int_range<1> (INT (10), INT (20));
-  r1 = int_range<1> (INT (9), INT (9));
+  r0 = range_int (10, 20);
+  r1 = range_int (9, 9);
   r0.union_ (r1);
-  ASSERT_TRUE (r0 == int_range<1> (INT (9), INT (20)));
+  ASSERT_TRUE (r0 == range_int (9, 20));
 
   // [10,20] ^ [15,30] => [15,20].
-  r0 = int_range<1> (INT (10), INT (20));
-  r1 = int_range<1> (INT (15), INT (30));
+  r0 = range_int (10, 20);
+  r1 = range_int (15, 30);
   r0.intersect (r1);
-  ASSERT_TRUE (r0 == int_range<1> (INT (15), INT (20)));
+  ASSERT_TRUE (r0 == range_int (15, 20));
 
   // Test the internal sanity of wide_int's wrt HWIs.
   ASSERT_TRUE (wi::max_value (TYPE_PRECISION (boolean_type_node),
@@ -2436,18 +2527,18 @@  range_tests_misc ()
 	       == wi::uhwi (1, TYPE_PRECISION (boolean_type_node)));
 
   // Test zero_p().
-  r0 = int_range<1> (INT (0), INT (0));
+  r0 = range_int (0, 0);
   ASSERT_TRUE (r0.zero_p ());
 
   // Test nonzero_p().
-  r0 = int_range<1> (INT (0), INT (0));
+  r0 = range_int (0, 0);
   r0.invert ();
   ASSERT_TRUE (r0.nonzero_p ());
 
   // r0 = ~[1,1]
-  r0 = int_range<2> (UINT (1), UINT (1), VR_ANTI_RANGE);
+  r0 = range_int (1, 1, VR_ANTI_RANGE);
   // r1 = ~[3,3]
-  r1 = int_range<2> (UINT (3), UINT (3), VR_ANTI_RANGE);
+  r1 = range_int (3, 3, VR_ANTI_RANGE);
 
   // vv = [0,0][2,2][4, MAX]
   int_range<3> vv = r0;
@@ -2456,7 +2547,7 @@  range_tests_misc ()
   ASSERT_TRUE (vv.contains_p (UINT (2)));
   ASSERT_TRUE (vv.num_pairs () == 3);
 
-  r0 = int_range<1> (UINT (1), UINT (1));
+  r0 = range_uint (1, 1);
   // And union it with  [0,0][2,2][4,MAX] multi range
   r0.union_ (vv);
   // The result should be [0,2][4,MAX], or ~[3,3]  but it must contain 2
@@ -2493,7 +2584,7 @@  range_tests_nonzero_bits ()
   ASSERT_TRUE (r0.get_nonzero_bits () == 0xff);
 
   // Intersect of nonzero bits.
-  r0.set (INT (0), INT (255));
+  r0 = range_int (0, 255);
   r0.set_nonzero_bits (0xfe);
   r1.set_varying (integer_type_node);
   r1.set_nonzero_bits (0xf0);
@@ -2502,7 +2593,7 @@  range_tests_nonzero_bits ()
 
   // Intersect where the mask of nonzero bits is implicit from the range.
   r0.set_varying (integer_type_node);
-  r1.set (INT (0), INT (255));
+  r1 = range_int (0, 255);
   r0.intersect (r1);
   ASSERT_TRUE (r0.get_nonzero_bits () == 0xff);
 
@@ -2631,13 +2722,13 @@  range_tests_nan ()
   // NAN is in a VARYING.
   r0.set_varying (float_type_node);
   real_nan (&r, "", 1, TYPE_MODE (float_type_node));
-  tree nan = build_real (float_type_node, r);
+  REAL_VALUE_TYPE nan = r;
   ASSERT_TRUE (r0.contains_p (nan));
 
   // -NAN is in a VARYING.
   r0.set_varying (float_type_node);
   q = real_value_negate (&r);
-  tree neg_nan = build_real (float_type_node, q);
+  REAL_VALUE_TYPE neg_nan = q;
   ASSERT_TRUE (r0.contains_p (neg_nan));
 
   // Clearing the NAN on a [] NAN is the empty set.
@@ -2669,28 +2760,29 @@  range_tests_nan ()
 static void
 range_tests_signed_zeros ()
 {
-  tree zero = build_zero_cst (float_type_node);
-  tree neg_zero = fold_build1 (NEGATE_EXPR, float_type_node, zero);
+  REAL_VALUE_TYPE zero = dconst0;
+  REAL_VALUE_TYPE neg_zero = zero;
+  neg_zero.sign = 1;
   frange r0, r1;
   bool signbit;
 
   // [0,0] contains [0,0] but not [-0,-0] and vice versa.
-  r0 = frange (zero, zero);
-  r1 = frange (neg_zero, neg_zero);
+  r0 = frange_float ("0.0", "0.0");
+  r1 = frange_float ("-0.0", "-0.0");
   ASSERT_TRUE (r0.contains_p (zero));
   ASSERT_TRUE (!r0.contains_p (neg_zero));
   ASSERT_TRUE (r1.contains_p (neg_zero));
   ASSERT_TRUE (!r1.contains_p (zero));
 
   // Test contains_p() when we know the sign of the zero.
-  r0 = frange (zero, zero);
+  r0 = frange_float ("0.0", "0.0");
   ASSERT_TRUE (r0.contains_p (zero));
   ASSERT_FALSE (r0.contains_p (neg_zero));
-  r0 = frange (neg_zero, neg_zero);
+  r0 = frange_float ("-0.0", "-0.0");
   ASSERT_TRUE (r0.contains_p (neg_zero));
   ASSERT_FALSE (r0.contains_p (zero));
 
-  r0 = frange (neg_zero, zero);
+  r0 = frange_float ("-0.0", "0.0");
   ASSERT_TRUE (r0.contains_p (neg_zero));
   ASSERT_TRUE (r0.contains_p (zero));
 
@@ -2700,8 +2792,8 @@  range_tests_signed_zeros ()
 
   // The intersection of zeros that differ in sign is a NAN (or
   // undefined if not honoring NANs).
-  r0 = frange (neg_zero, neg_zero);
-  r1 = frange (zero, zero);
+  r0 = frange_float ("-0.0", "-0.0");
+  r1 = frange_float ("0.0", "0.0");
   r0.intersect (r1);
   if (HONOR_NANS (float_type_node))
     ASSERT_TRUE (r0.known_isnan ());
@@ -2709,18 +2801,18 @@  range_tests_signed_zeros ()
     ASSERT_TRUE (r0.undefined_p ());
 
   // The union of zeros that differ in sign is a zero with unknown sign.
-  r0 = frange (zero, zero);
-  r1 = frange (neg_zero, neg_zero);
+  r0 = frange_float ("0.0", "0.0");
+  r1 = frange_float ("-0.0", "-0.0");
   r0.union_ (r1);
   ASSERT_TRUE (r0.zero_p () && !r0.signbit_p (signbit));
 
   // [-0, +0] has an unknown sign.
-  r0 = frange (neg_zero, zero);
+  r0 = frange_float ("-0.0", "0.0");
   ASSERT_TRUE (r0.zero_p () && !r0.signbit_p (signbit));
 
   // [-0, +0] ^ [0, 0] is [0, 0]
-  r0 = frange (neg_zero, zero);
-  r1 = frange (zero, zero);
+  r0 = frange_float ("-0.0", "0.0");
+  r1 = frange_float ("0.0", "0.0");
   r0.intersect (r1);
   ASSERT_TRUE (r0.zero_p ());
 
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 6d108154dc1..633a234d41f 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -122,8 +122,7 @@  class GTY((user)) irange : public vrange
   friend class irange_storage;
 public:
   // In-place setters.
-  virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
-  void set (tree type, const wide_int_ref &, const wide_int_ref &,
+  void set (tree type, const wide_int &, const wide_int &,
 	    value_range_kind = VR_RANGE);
   virtual void set_nonzero (tree type) override;
   virtual void set_zero (tree type) override;
@@ -146,7 +145,8 @@  public:
   virtual bool zero_p () const override;
   virtual bool nonzero_p () const override;
   virtual bool singleton_p (tree *result = NULL) const override;
-  virtual bool contains_p (tree cst) const override;
+  bool singleton_p (wide_int &) const;
+  bool contains_p (const wide_int &) const;
 
   // In-place operators.
   virtual bool union_ (const vrange &) override;
@@ -167,11 +167,13 @@  public:
   void set_nonzero_bits (const wide_int_ref &bits);
 
 protected:
+  virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
+  virtual bool contains_p (tree cst) const override;
   irange (tree *, unsigned);
 
    // In-place operators.
-  void irange_set (tree, tree);
-  void irange_set_anti_range (tree, tree);
+  void irange_set (tree type, const wide_int &, const wide_int &);
+  void irange_set_anti_range (tree type, const wide_int &, const wide_int &);
   bool irange_contains_p (const irange &) const;
   bool irange_single_pair_union (const irange &r);
 
@@ -184,7 +186,8 @@  private:
   friend void gt_pch_nx (irange *);
   friend void gt_pch_nx (irange *, gt_pointer_operator, void *);
 
-  void irange_set_1bit_anti_range (tree, tree);
+  void irange_set_1bit_anti_range (tree type,
+				   const wide_int &, const wide_int &);
   bool varying_compatible_p () const;
   bool intersect_nonzero_bits (const irange &r);
   bool union_nonzero_bits (const irange &r);
@@ -206,7 +209,6 @@  class GTY((user)) int_range : public irange
 {
 public:
   int_range ();
-  int_range (tree, tree, value_range_kind = VR_RANGE);
   int_range (tree type, const wide_int &, const wide_int &,
 	     value_range_kind = VR_RANGE);
   int_range (tree type);
@@ -214,6 +216,8 @@  public:
   int_range (const irange &);
   virtual ~int_range () = default;
   int_range& operator= (const int_range &);
+protected:
+  int_range (tree, tree, value_range_kind = VR_RANGE);
 private:
   template <unsigned X> friend void gt_ggc_mx (int_range<X> *);
   template <unsigned X> friend void gt_pch_nx (int_range<X> *);
@@ -319,7 +323,6 @@  public:
     return SCALAR_FLOAT_TYPE_P (type) && !DECIMAL_FLOAT_TYPE_P (type);
   }
   virtual tree type () const override;
-  virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
   void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
 	    value_range_kind = VR_RANGE);
   void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
@@ -330,8 +333,9 @@  public:
   virtual void set_undefined () override;
   virtual bool union_ (const vrange &) override;
   virtual bool intersect (const vrange &) override;
-  virtual bool contains_p (tree) const override;
+  bool contains_p (const REAL_VALUE_TYPE &) const;
   virtual bool singleton_p (tree *result = NULL) const override;
+  bool singleton_p (REAL_VALUE_TYPE &r) const;
   virtual bool supports_type_p (const_tree type) const override;
   virtual void accept (const vrange_visitor &v) const override;
   virtual bool zero_p () const override;
@@ -361,7 +365,13 @@  public:
   bool maybe_isinf () const;
   bool signbit_p (bool &signbit) const;
   bool nan_signbit_p (bool &signbit) const;
+
+protected:
+  virtual bool contains_p (tree cst) const override;
+  virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
+
 private:
+  bool internal_singleton_p (REAL_VALUE_TYPE * = NULL) const;
   void verify_range ();
   bool normalize_kind ();
   bool union_nans (const frange &);
@@ -485,8 +495,6 @@  public:
   static bool supports_type_p (const_tree type);
 
   // Convenience methods for vrange compatibility.
-  void set (tree min, tree max, value_range_kind kind = VR_RANGE)
-    { return m_vrange->set (min, max, kind); }
   tree type () { return m_vrange->type (); }
   bool varying_p () const { return m_vrange->varying_p (); }
   bool undefined_p () const { return m_vrange->undefined_p (); }
@@ -536,7 +544,7 @@  inline
 Value_Range::Value_Range (tree min, tree max, value_range_kind kind)
 {
   init (TREE_TYPE (min));
-  set (min, max, kind);
+  m_vrange->set (min, max, kind);
 }
 
 inline
@@ -674,13 +682,6 @@  irange::varying_compatible_p () const
   return true;
 }
 
-inline void
-irange::set (tree type, const wide_int_ref &min, const wide_int_ref &max,
-	     value_range_kind kind)
-{
-  set (wide_int_to_tree (type, min), wide_int_to_tree (type, max), kind);
-}
-
 inline bool
 vrange::varying_p () const
 {
@@ -707,8 +708,8 @@  irange::nonzero_p () const
   if (undefined_p ())
     return false;
 
-  tree zero = build_zero_cst (type ());
-  return *this == int_range<2> (zero, zero, VR_ANTI_RANGE);
+  wide_int zero = wi::zero (TYPE_PRECISION (type ()));
+  return *this == int_range<2> (type (), zero, zero, VR_ANTI_RANGE);
 }
 
 inline bool
@@ -717,6 +718,12 @@  irange::supports_p (const_tree type)
   return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
 }
 
+inline bool
+irange::contains_p (tree cst) const
+{
+  return contains_p (wi::to_wide (cst));
+}
+
 inline bool
 range_includes_zero_p (const irange *vr)
 {
@@ -726,7 +733,7 @@  range_includes_zero_p (const irange *vr)
   if (vr->varying_p ())
     return true;
 
-  tree zero = build_zero_cst (vr->type ());
+  wide_int zero = wi::zero (TYPE_PRECISION (vr->type ()));
   return vr->contains_p (zero);
 }
 
@@ -906,8 +913,8 @@  irange::upper_bound () const
 inline void
 irange::set_nonzero (tree type)
 {
-  tree zero = build_int_cst (type, 0);
-  irange_set_anti_range (zero, zero);
+  wide_int zero = wi::zero (TYPE_PRECISION (type));
+  set (type, zero, zero, VR_ANTI_RANGE);
 }
 
 // Set value range VR to a ZERO range of type TYPE.
@@ -915,8 +922,8 @@  irange::set_nonzero (tree type)
 inline void
 irange::set_zero (tree type)
 {
-  tree z = build_int_cst (type, 0);
-  irange_set (z, z);
+  wide_int zero = wi::zero (TYPE_PRECISION (type));
+  set (type, zero, zero);
 }
 
 // Normalize a range to VARYING or UNDEFINED if possible.
@@ -935,6 +942,16 @@  irange::normalize_kind ()
     }
 }
 
+inline bool
+contains_zero_p (const irange &r)
+{
+  if (r.undefined_p ())
+    return true;
+
+  wide_int zero = wi::zero (TYPE_PRECISION (r.type ()));
+  return r.contains_p (zero);
+}
+
 // Return the maximum value for TYPE.
 
 inline tree
@@ -1083,6 +1100,12 @@  frange::update_nan (bool sign)
     }
 }
 
+inline bool
+frange::contains_p (tree cst) const
+{
+  return contains_p (*TREE_REAL_CST_PTR (cst));
+}
+
 // Clear the NAN bit and adjust the range.
 
 inline void
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 3d28198f9f5..49ae324419a 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -88,8 +88,7 @@  simplify_using_ranges::op_with_boolean_value_range_p (tree op, gimple *s)
      as [0,1].  */
   value_range vr;
   return (query->range_of_expr (vr, op, s)
-	  && vr == value_range (build_zero_cst (TREE_TYPE (op)),
-				build_one_cst (TREE_TYPE (op))));
+	  && vr == range_true_and_false (TREE_TYPE (op)));
 }
 
 /* Helper function for simplify_internal_call_using_ranges and
@@ -316,7 +315,11 @@  bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
 	      value_range maxvr, vr0, vr1;
 	      if (!query->range_of_expr (vr0, init, stmt))
 		vr0.set_varying (TREE_TYPE (init));
-	      vr1.set (TREE_TYPE (init), wtmp, wtmp);
+	      tree tinit = TREE_TYPE (init);
+	      wide_int winit = wide_int::from (wtmp,
+					       TYPE_PRECISION (tinit),
+					       TYPE_SIGN (tinit));
+	      vr1.set (TREE_TYPE (init), winit, winit);
 
 	      range_op_handler handler (PLUS_EXPR, TREE_TYPE (init));
 	      if (!handler.fold_range (maxvr, TREE_TYPE (init), vr0, vr1))
@@ -444,15 +447,25 @@  simplify_using_ranges::legacy_fold_cond_overflow (gimple *stmt)
       else
 	{
 	  value_range vro, vri;
+	  tree type = TREE_TYPE (op0);
 	  if (code == GT_EXPR || code == GE_EXPR)
 	    {
-	      vro.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x, VR_ANTI_RANGE);
-	      vri.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x);
+	      vro.set (type,
+		       wi::to_wide (TYPE_MIN_VALUE (type)),
+		       wi::to_wide (x), VR_ANTI_RANGE);
+	      vri.set (type,
+		       wi::to_wide (TYPE_MIN_VALUE (type)),
+		       wi::to_wide (x));
 	    }
 	  else if (code == LT_EXPR || code == LE_EXPR)
 	    {
-	      vro.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x);
-	      vri.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x, VR_ANTI_RANGE);
+	      vro.set (type,
+		       wi::to_wide (TYPE_MIN_VALUE (type)),
+		       wi::to_wide (x));
+	      vri.set (type,
+		       wi::to_wide (TYPE_MIN_VALUE (type)),
+		       wi::to_wide (x),
+		       VR_ANTI_RANGE);
 	    }
 	  else
 	    gcc_unreachable ();