https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24021

Aldy Hernandez <aldyh at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |aldyh at gcc dot gnu.org
                 CC|                            |sayle at gcc dot gnu.org

--- Comment #20 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
(In reply to Andrew Macleod from comment #19)
> We can use the original testcase as the litmus test for basic support if we
> compile it with
> 
> -O2  -fno-tree-fre  -fno-tree-dominator-opts
> 
> The unroller will unroll the loop and the VRP2 pass will be presented with:
> 
>  <bb 2> [local count: 97603129]:
>  i_1 = 1.1000000149011611438876201418679556809365749359130859375e-1;
>  i_17 = i_1 + 1.00000001490116119384765625e-1;
>  i_22 = i_17 + 1.00000001490116119384765625e-1;
>  i_27 = i_22 + 1.00000001490116119384765625e-1;
>  i_32 = i_27 + 1.00000001490116119384765625e-1;
>  i_37 = i_32 + 1.00000001490116119384765625e-1;
>  i_42 = i_37 + 1.00000001490116119384765625e-1;
>  i_47 = i_42 + 1.00000001490116119384765625e-1;
>  i_52 = i_47 + 1.00000001490116119384765625e-1;
>  if (i_52 == 0.0)
>    goto <bb 4>; [50.00%]
>  else
>    goto <bb 3>; [50.00%]
> 
>  <bb 3> [local count: 48801565]:
> 
>  <bb 4> [local count: 97603129]:
>  # lastPoint_12 = PHI <i_52(2), 2.0e+0(3)>
>  return lastPoint_12;
> 
> Which is we can track floating point ranges in VRP and simplification,
> recognize that i_52 != 0.0 and VRP2 should be able to resolve this to 
> 
> return 2.0e+0;

We can definitely get this with the current work.  All that's missing is the
snippet implementing the PLUS_EXPR operator.  A simple implementation (with
likely the NAN bits wrong :)) follows:

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index d1c7a3b571b..cba7166ad2b 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -1055,6 +1055,54 @@ foperator_mult::fold_range (frange &r, tree type,
   return true;
 }

+class foperator_plus : public range_operator
+{
+  using range_operator::fold_range;
+public:
+  virtual bool fold_range (frange &r, tree type,
+                          const frange &lh,
+                          const frange &rh,
+                          relation_kind rel = VREL_NONE) const override;
+} fop_plus;
+
+bool
+foperator_plus::fold_range (frange &r, tree type,
+                           const frange &lh,
+                           const frange &rh,
+                           relation_kind) const
+{
+  if (empty_range_varying (r, type, lh, rh))
+    return true;
+
+  if (lh.get_prop (FRANGE_PROP_NAN)
+      || rh.get_prop (FRANGE_PROP_NAN))
+    {
+      r.set_varying (type);
+      return true;
+    }
+
+  enum tree_code code_lb, code_ub;
+  tree lh_lb = lh.lower_bound (&code_lb);
+  tree lh_ub = lh.upper_bound (&code_ub);
+  tree rh_lb = rh.lower_bound ();
+  tree rh_ub = rh.upper_bound ();
+
+  REAL_VALUE_TYPE res_lb, res_ub;
+  real_arithmetic (&res_lb, PLUS_EXPR,
+                  TREE_REAL_CST_PTR (lh_lb),
+                  TREE_REAL_CST_PTR (rh_lb));
+  real_arithmetic (&res_ub, PLUS_EXPR,
+                  TREE_REAL_CST_PTR (lh_ub),
+                  TREE_REAL_CST_PTR (rh_ub));
+
+  r.set (code_lb,
+        build_real (type, res_lb),
+        build_real (type, res_ub),
+        code_ub);
+  return true;
+}
+
+
 class floating_table : public range_op_table
 {
 public:
@@ -1081,6 +1129,7 @@ floating_table::floating_table ()
   set (UNORDERED_EXPR, fop_unordered);
   set (ORDERED_EXPR, fop_ordered);
   set (MULT_EXPR, fop_mult);
+  set (PLUS_EXPR, fop_plus);
 }

 #if CHECKING_P


And voila...

./cc1 a.c -quiet -I/tmp -O2 -fno-tree-fre -fno-tree-dominator-opts
-fno-thread-jumps -fdump-tree-vrp2-details=/dev/stdout

Folding statement: i_1 =
1.1000000149011611438876201418679556809365749359130859375e-1;
Queued stmt for removal.  Folds to:
1.1000000149011611438876201418679556809365749359130859375e-1
Folding statement: i_17 = i_1 + 1.00000001490116119384765625e-1;
Queued stmt for removal.  Folds to:
2.1000000298023223377352763918679556809365749359130859375e-1
...
...
...
double BG_SplineLength ()
{
  double i;
  double lastPoint;

  <bb 2> [local count: 97603129]:
  return 2.0e+0;

}

Notice the -fno-thread-jumps, because otherwise the now floating point aware
threader will thread the conditional before VRP2 gets a chance to see it.

I should probably take this PR ;-).

Reply via email to