mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-11 22:31:12 +02:00
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.
This commit is contained in:
parent
40dac99d42
commit
64acf24b40
7 changed files with 40 additions and 7 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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?)
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue