don't constant-fold an fx operation if the result is non-fx

In fact, the result must be an fx on all platforms, since
compilation should be platform-independent.
This commit is contained in:
Matthew Flatt 2011-07-25 11:28:25 -04:00
parent f13a669d05
commit 73b16c8578
3 changed files with 36 additions and 6 deletions

View File

@ -1296,6 +1296,19 @@
(test-multi 'vector)
(test-multi 'vector-immutable)))
;; + fold to fixnum overflow, fx+ doesn't
(test-comp `(module m racket/base
(+ (sub1 (expt 2 30)) (sub1 (expt 2 30))))
`(module m racket/base
(- (expt 2 31) 2)))
(test-comp `(module m racket/base
(require racket/fixnum)
(fx+ (sub1 (expt 2 30)) (sub1 (expt 2 30))))
`(module m racket/base
(require racket/fixnum)
(- (expt 2 31) 2))
#f)
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Check bytecode verification of lifted functions

View File

@ -1078,7 +1078,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
/* rand2 in R0, and rand in R1 unless it's simple */
if (simple_rand || simple_rand2) {
int pos, va;
int va;
if (simple_rand && SCHEME_INTP(rand)) {
(void)jit_movi_p(JIT_R1, rand);

View File

@ -923,6 +923,22 @@ quotient_remainder(int argc, Scheme_Object *argv[])
scheme_raise_exn(MZEXN_FAIL_CONTRACT_DIVIDE_BY_ZERO, \
name ": undefined for 0");
#ifdef SIXTY_FOUR_BIT_INTEGERS
static void check_always_fixnum(const char *name, Scheme_Object *o)
{
if (SCHEME_INTP(o)) {
intptr_t v = SCHEME_INT_VAL(o);
if ((v < -1073741824) || (v > 1073741823)) {
scheme_arg_mismatch(name,
"cannot fold to result that is not a fixnum on some platforms: ",
o);
}
}
}
# define mzWHEN_64_BITS(e) e
#else
# define mzWHEN_64_BITS(e) /* empty */
#endif
#define SAFE_FX(name, s_name, scheme_op, EXTRA_CHECK) \
static Scheme_Object *name(int argc, Scheme_Object *argv[]) \
@ -932,6 +948,7 @@ quotient_remainder(int argc, Scheme_Object *argv[])
if (!SCHEME_INTP(argv[1])) scheme_wrong_type(s_name, "fixnum", 1, argc, argv); \
EXTRA_CHECK \
o = scheme_op(argc, argv); \
mzWHEN_64_BITS(if (scheme_current_thread->constant_folding) check_always_fixnum(s_name, o);) \
if (!SCHEME_INTP(o)) scheme_non_fixnum_result(s_name, o); \
return o; \
}
@ -961,11 +978,11 @@ static Scheme_Object *fx_abs(int argc, Scheme_Object *argv[])
return scheme_make_integer(v); \
}
UNSAFE_FX(unsafe_fx_plus, +, plus)
UNSAFE_FX(unsafe_fx_minus, -, minus)
UNSAFE_FX(unsafe_fx_mult, *, mult)
UNSAFE_FX(unsafe_fx_div, /, quotient)
UNSAFE_FX(unsafe_fx_rem, %, rem_prim)
UNSAFE_FX(unsafe_fx_plus, +, fx_plus)
UNSAFE_FX(unsafe_fx_minus, -, fx_minus)
UNSAFE_FX(unsafe_fx_mult, *, fx_mult)
UNSAFE_FX(unsafe_fx_div, /, fx_div)
UNSAFE_FX(unsafe_fx_rem, %, fx_rem)
static Scheme_Object *unsafe_fx_mod(int argc, Scheme_Object *argv[])
{