From 73b16c857887875f032fd85db8aad53a0dce52df Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 25 Jul 2011 11:28:25 -0400 Subject: [PATCH] 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. --- collects/tests/racket/optimize.rktl | 13 +++++++++++++ src/racket/src/jitarith.c | 2 +- src/racket/src/numarith.c | 27 ++++++++++++++++++++++----- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/collects/tests/racket/optimize.rktl b/collects/tests/racket/optimize.rktl index e92299f621..0c1336be23 100644 --- a/collects/tests/racket/optimize.rktl +++ b/collects/tests/racket/optimize.rktl @@ -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 diff --git a/src/racket/src/jitarith.c b/src/racket/src/jitarith.c index adac460c95..584e9130ff 100644 --- a/src/racket/src/jitarith.c +++ b/src/racket/src/jitarith.c @@ -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); diff --git a/src/racket/src/numarith.c b/src/racket/src/numarith.c index b3499a3626..8dfd6a1150 100644 --- a/src/racket/src/numarith.c +++ b/src/racket/src/numarith.c @@ -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[]) {