guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] 04/04: Fix NaN handling in <= and >=


From: Andy Wingo
Subject: [Guile-commits] 04/04: Fix NaN handling in <= and >=
Date: Sat, 2 Dec 2017 15:15:42 -0500 (EST)

wingo pushed a commit to branch master
in repository guile.

commit 64acf24b4018627b2616567c74dae3f6800f3a9d
Author: Andy Wingo <address@hidden>
Date:   Sat Dec 2 21:07:48 2017 +0100

    Fix NaN handling in <= and >=
    
    * module/language/cps/compile-bytecode.scm (compile-function): Add
      support for emitting <= via < and jge / jnge.
    * module/language/cps/effects-analysis.scm: Declare effects for <= and
      f64-<=.
    * module/language/cps/primitives.scm (*comparisons*): Add <=, f64-<=.
    * module/language/cps/specialize-numbers.scm (specialize-operations):
      Specialize <= to < for integer comparisons.  Specialize to f64-<= for
      f64 ops.
    * module/language/cps/type-fold.scm (<=): Add folder.
    * module/language/cps/types.scm (infer-<=): Add inferrer.
    * module/language/tree-il/compile-cps.scm (canonicalize): Canonicalize
      <= and >= to <=, so that nans are handled correctly.
---
 module/language/cps/compile-bytecode.scm   |  4 ++++
 module/language/cps/effects-analysis.scm   |  2 ++
 module/language/cps/primitives.scm         |  2 ++
 module/language/cps/specialize-numbers.scm | 11 +++++++++++
 module/language/cps/type-fold.scm          |  8 ++++++++
 module/language/cps/types.scm              |  6 ++++++
 module/language/tree-il/compile-cps.scm    | 14 +++++++-------
 7 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/module/language/cps/compile-bytecode.scm 
b/module/language/cps/compile-bytecode.scm
index f7c8fbb..0baa309 100644
--- a/module/language/cps/compile-bytecode.scm
+++ b/module/language/cps/compile-bytecode.scm
@@ -427,6 +427,8 @@
         (binary op emit-je emit-jne a b))
       (define (binary-< emit-<? a b)
         (binary emit-<? emit-jl emit-jnl a b))
+      (define (binary-<= emit-<? a b)
+        (binary emit-<? emit-jge emit-jnge b a))
       (define (binary-test/imm op a b)
         (op asm (from-sp (slot a)) b)
         (emit-branch emit-je emit-jne))
@@ -458,6 +460,7 @@
         (($ $primcall 'heap-numbers-equal? #f (a b))
          (binary-test emit-heap-numbers-equal? a b))
         (($ $primcall '< #f (a b)) (binary-< emit-<? a b))
+        (($ $primcall '<= #f (a b)) (binary-<= emit-<? a b))
         (($ $primcall '= #f (a b)) (binary-test emit-=? a b))
         (($ $primcall 'u64-< #f (a b)) (binary-< emit-u64<? a b))
         (($ $primcall 'u64-imm-< b (a)) (binary-</imm emit-u64-imm<? a b))
@@ -470,6 +473,7 @@
         (($ $primcall 's64-imm-< b (a)) (binary-</imm emit-s64-imm<? a b))
         (($ $primcall 'imm-s64-< b (a)) (binary-</imm emit-imm-s64<? a b))
         (($ $primcall 'f64-< #f (a b)) (binary-< emit-f64<? a b))
+        (($ $primcall 'f64-<= #f (a b)) (binary-<= emit-f64<? a b))
         (($ $primcall 'f64-= #f (a b)) (binary-test emit-f64=? a b))))
 
     (define (compile-trunc label k exp nreq rest-var)
diff --git a/module/language/cps/effects-analysis.scm 
b/module/language/cps/effects-analysis.scm
index 298a7be..9b86bec 100644
--- a/module/language/cps/effects-analysis.scm
+++ b/module/language/cps/effects-analysis.scm
@@ -449,6 +449,7 @@ the LABELS that are clobbered by the effects of LABEL."
 (define-primitive-effects
   ((heap-numbers-equal? . _))
   ((= . _)                         &type-check)
+  ((<= . _)                         &type-check)
   ((< . _)                         &type-check)
   ((u64-= . _))
   ((u64-imm-= . _))
@@ -462,6 +463,7 @@ the LABELS that are clobbered by the effects of LABEL."
   ((imm-s64-< . _))
   ((f64-= . _))
   ((f64-< . _))
+  ((f64-<= . _))
   ((zero? . _)                     &type-check)
   ((add . _)                       &type-check)
   ((add/immediate . _)             &type-check)
diff --git a/module/language/cps/primitives.scm 
b/module/language/cps/primitives.scm
index 7feead6..8d774cb 100644
--- a/module/language/cps/primitives.scm
+++ b/module/language/cps/primitives.scm
@@ -144,6 +144,7 @@ before it is lowered to CPS?"
     heap-numbers-equal?
 
     <
+    <=
     =
 
     u64-<
@@ -152,6 +153,7 @@ before it is lowered to CPS?"
     s64-<
 
     f64-<
+    f64-<=
     f64-=))
 
 (define *branching-primcall-arities* (make-hash-table))
diff --git a/module/language/cps/specialize-numbers.scm 
b/module/language/cps/specialize-numbers.scm
index 5b0103f..d8ec5e6 100644
--- a/module/language/cps/specialize-numbers.scm
+++ b/module/language/cps/specialize-numbers.scm
@@ -565,6 +565,17 @@ BITS indicating the significant bits needed for a 
variable.  BITS may be
 
     (define (specialize-branch cps kf kt src op param args)
       (match (cons op args)
+        (('<= a b)
+         (cond
+          ((f64-operands? a b)
+           (specialize-comparison cps kf kt src 'f64-<= a b
+                                  (unbox-f64 a) (unbox-f64 b)))
+          ((and (exact-integer-operand? a) (exact-integer-operand? b))
+           ;; If NaN is impossible, reduce (<= a b) to (not (< b a)) and
+           ;; try again.
+           (specialize-branch cps kt kf src '< param (list b a)))
+          (else
+           (with-cps cps #f))))
         (((or '< '=) a b)
          (cond
           ((f64-operands? a b)
diff --git a/module/language/cps/type-fold.scm 
b/module/language/cps/type-fold.scm
index f4e24f4..1fd933b 100644
--- a/module/language/cps/type-fold.scm
+++ b/module/language/cps/type-fold.scm
@@ -160,6 +160,14 @@
 ;;
 ;; (define-branch-folder-alias f64-< <)
 
+(define-binary-branch-folder (<= type0 min0 max0 type1 min1 max1)
+  (if (type<=? (logior type0 type1) &exact-number)
+      (case (compare-exact-ranges min0 max0 min1 max1)
+        ((< <= =) (values #t #t))
+        ((>) (values #t #f))
+        (else (values #f #f)))
+      (values #f #f)))
+
 (define-unary-branch-folder* (u64-imm-= c type min max)
   (cond
    ((= c min max) (values #t #t))
diff --git a/module/language/cps/types.scm b/module/language/cps/types.scm
index dd2206b..5c213fc 100644
--- a/module/language/cps/types.scm
+++ b/module/language/cps/types.scm
@@ -1068,6 +1068,12 @@ minimum, and maximum."
           (restrict! a &exact-number (max min0 min1) max0)
           (restrict! b &exact-number min1 (min max0 max1)))))))))
 
+(define (infer-<= types succ param a b)
+  ;; Infer "(<= a b)" as "(not (< b a))", knowing that we only make
+  ;; inferences when NaN is impossible.
+  ((hashq-ref *type-inferrers* '<) types (match succ (0 1) (1 0)) param b a))
+(hashq-set! *type-inferrers* '<= infer-<=)
+
 (define-predicate-inferrer (u64-= a b true?)
   (infer-= a b true?))
 (define-predicate-inferrer (u64-< a b true?)
diff --git a/module/language/tree-il/compile-cps.scm 
b/module/language/tree-il/compile-cps.scm
index 49274c4..ed7ed47 100644
--- a/module/language/tree-il/compile-cps.scm
+++ b/module/language/tree-il/compile-cps.scm
@@ -1140,16 +1140,16 @@ integer."
                              (make-const src #f)))))
 
        (($ <primcall> src '<= (a b))
-        ;; No need to reduce as < is a branching primitive.
-        (make-conditional src (make-primcall src '< (list b a))
-                          (make-const src #f)
-                          (make-const src #t)))
+        ;; No need to reduce as <= is a branching primitive.
+        (make-conditional src (make-primcall src '<= (list a b))
+                          (make-const src #t)
+                          (make-const src #f)))
 
        (($ <primcall> src '>= (a b))
         ;; No need to reduce as < is a branching primitive.
-        (make-conditional src (make-primcall src '< (list a b))
-                          (make-const src #f)
-                          (make-const src #t)))
+        (make-conditional src (make-primcall src '<= (list b a))
+                          (make-const src #t)
+                          (make-const src #f)))
 
        (($ <primcall> src '> (a b))
         ;; No need to reduce as < is a branching primitive.



reply via email to

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