fix optimizer on bitwise-and

The optimizer assumed a fixnum result if either argument to
`bitwise-and` implies a fixnum result. That's not correct if the
fixnum agument is negative.

Thanks to Peter Samarin for a bug report.

Merge to v6.7
This commit is contained in:
Matthew Flatt 2016-10-13 11:25:40 -06:00
parent a9f2765b4f
commit 9011fe7d83
2 changed files with 20 additions and 3 deletions

View File

@ -3387,6 +3387,20 @@
#t))
#f)
;; Make sure that `bitwise-and` is known to return a fixnum for non-negative
;; fixnum arguments but not for a negative one
(test-comp '(lambda (x)
(bitwise-ior (bitwise-and x 7) 1))
'(lambda (x)
(unsafe-fxior (bitwise-and x 7) 1)))
(test-comp '(lambda (x)
(bitwise-ior (bitwise-and x -7) 1))
'(lambda (x)
(unsafe-fxior (bitwise-and x -7) 1))
#f)
(test-comp `(lambda (x)
(thread (lambda () (set! x 5)))
(if (pair? x)
@ -6260,7 +6274,6 @@
(set! f f)
((car f))))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(report-errs)

View File

@ -3029,13 +3029,17 @@ static Scheme_Object *do_expr_implies_predicate(Scheme_Object *expr, Optimize_In
&& IS_NAMED_PRIM(app->rator, "bitwise-and")) {
/* Assume that a fixnum argument to bitwise-and will never get lost,
and so the validator will be able to confirm that a `bitwise-and`
combination produces a fixnum. */
combination produces a fixnum if either argument is a literal,
nonnegative fixnum. */
if ((SCHEME_INTP(app->rand1)
&& (SCHEME_INT_VAL(app->rand1) >= 0)
&& IN_FIXNUM_RANGE_ON_ALL_PLATFORMS(SCHEME_INT_VAL(app->rand1)))
|| (SCHEME_INTP(app->rand2)
&& IN_FIXNUM_RANGE_ON_ALL_PLATFORMS(SCHEME_INT_VAL(app->rand2))))
&& (SCHEME_INT_VAL(app->rand2) >= 0)
&& IN_FIXNUM_RANGE_ON_ALL_PLATFORMS(SCHEME_INT_VAL(app->rand2)))) {
return scheme_fixnum_p_proc;
}
}
if (SCHEME_PRIMP(app->rator)
&& SCHEME_PRIM_PROC_OPT_FLAGS(app->rator) & SCHEME_PRIM_CLOSED_ON_REALS) {