guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 01/01: Fix range inference on division in unreachable co


From: Andy Wingo
Subject: [Guile-commits] 01/01: Fix range inference on division in unreachable code
Date: Wed, 27 Nov 2019 10:04:13 -0500 (EST)

wingo pushed a commit to branch master
in repository guile.

commit 8304b15807debfb1aba6ef6510e42d6174a92215
Author: Andy Wingo <address@hidden>
Date:   Wed Nov 27 16:00:43 2019 +0100

    Fix range inference on division in unreachable code
    
    * module/language/cps/types.scm (div-result-range): It is possible for a
      max value to be less than a minimum.  In this bug from zig:
    
        (define (benchmark x)
          (let loop ((count 0)
                     (sum 0))
            (if (= count 10)
                (exact->inexact (/ sum 10)))
            (loop (+ count 1) x)))
    
      Here the first iteration gets peeled, and thus the first "if" can't be
      true, because "count" is zero.  However on the true branch of the if,
      range inference produces bogus ranges -- notably, the variable bound
      to 10 is inferred to have a min of 10 and a max of 0.  This is fine,
      because it's unreachable; but that then infects the division, because
      the same variable bound to 10 is used there, resulting in division by
      zero.
---
 module/language/cps/types.scm | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/module/language/cps/types.scm b/module/language/cps/types.scm
index d224f0c..a0d58fd 100644
--- a/module/language/cps/types.scm
+++ b/module/language/cps/types.scm
@@ -1241,9 +1241,10 @@ minimum, and maximum."
        (not (<= (&min b) 0 (&max b)))))
 (define-type-checker (fdiv a b) #t)
 (define (div-result-range min-a max-a min-b max-b)
-  (if (<= min-b 0 max-b)
-      ;; If the range of the divisor crosses 0, the result spans
-      ;; the whole range.
+  (if (or (<= min-b 0 max-b)
+          (< max-b min-b))
+      ;; If the range of the divisor crosses 0, or if we are in
+      ;; unreachable code, the result spans the whole range.
       (values -inf.0 +inf.0)
       ;; Otherwise min-b and max-b have the same sign, and cannot both
       ;; be infinity.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]