diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ff65c4d136bd3de1862bfbf3cb5e8d188f6f1cb1..6485d48c19dbcf964660ef0a3429901f46ace7fa 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -12,7 +12,7 @@ linux-runner:
     - mkdir snapshot
     - (cd snapshot; tar xjf ../cmucl-$version-linux.tar.bz2; tar xjf ../cmucl-$version-linux.extra.tar.bz2)
   script:
-    - bin/build.sh $bootstrap -C "" -o snapshot/bin/lisp
+    - bin/build.sh $bootstrap -R -C "" -o snapshot/bin/lisp
     - bin/make-dist.sh -I dist linux-4
     - bin/run-tests.sh -l dist/bin/lisp 2>&1 | tee test.log
 
@@ -24,6 +24,6 @@ osx-runner:
     - mkdir snapshot
     - (cd snapshot; tar xjf ../cmucl-$version-darwin.tar.bz2)
   script:
-    - bin/build.sh $bootstrap -C "" -o snapshot/bin/lisp
+    - bin/build.sh $bootstrap -R -C "" -o snapshot/bin/lisp
     - bin/make-dist.sh -I dist darwin-4
     - bin/run-tests.sh -l dist/bin/lisp 2>&1 | tee test.log
diff --git a/src/lisp/Config.x86_linux b/src/lisp/Config.x86_linux
index b991683940163375ea8d8f390668237844ab39b5..4aa3eee86cb75889d15fb3ecd895a5a8d5aa47e3 100644
--- a/src/lisp/Config.x86_linux
+++ b/src/lisp/Config.x86_linux
@@ -3,7 +3,7 @@ include Config.x86_common
 
 # gcc 8.1.1 and 8.3.1 (and probably anything after 8.1.1?) won't
 # produce a working lisp with -O2.  Just use -O1.
-COPT = -O1
+COPT = -O2
 CFLAGS += $(COPT)
 CPPFLAGS += -m32 -D__NO_CTYPE -D_GNU_SOURCE
 CFLAGS += -rdynamic  -march=pentium4 -mfpmath=sse -mtune=generic
diff --git a/src/lisp/gencgc.c b/src/lisp/gencgc.c
index 01a97fafaa59f9a9c0d4088a854c0eecb54f7693..204a298f37281a61215fcbb20cc084f3d2aded2d 100644
--- a/src/lisp/gencgc.c
+++ b/src/lisp/gencgc.c
@@ -8416,6 +8416,7 @@ char *
 alloc(int nbytes)
 {
     void *new_obj;
+
 #if !(defined(sparc) || (defined(DARWIN) && defined(__ppc__)))
     /*
      * *current-region-free-pointer* is the same as alloc-tn (=
@@ -8442,20 +8443,6 @@ alloc(int nbytes)
 	    set_current_region_free((lispobj) new_free_pointer);
             break;
 	} else if (bytes_allocated <= auto_gc_trigger) {
-#if defined(i386) || defined(__x86_64)
-            /*
-             * Need to save and restore the FPU registers on x86, but only for
-             * sse2.  See Ticket #61.
-             *
-             * Not needed by sparc or ppc because we never call alloc from
-             * Lisp directly to do allocation.
-             */
-            FPU_STATE(fpu_state);
-
-            if (fpu_mode == SSE2) {
-                save_fpu_state(fpu_state);
-            }
-#endif
 	    /* Call gc_alloc.  */
 	    boxed_region.free_pointer = (void *) get_current_region_free();
 	    boxed_region.end_addr =
@@ -8466,11 +8453,6 @@ alloc(int nbytes)
 	    set_current_region_free((lispobj) boxed_region.free_pointer);
 	    set_current_region_end((lispobj) boxed_region.end_addr);
 
-#if defined(i386) || defined(__x86_64)
-            if (fpu_mode == SSE2) {
-                restore_fpu_state(fpu_state);
-            }
-#endif
             break;
 	} else {
 	    /* Run GC and try again.  */
diff --git a/src/lisp/x86-arch.h b/src/lisp/x86-arch.h
index 8314063fd916177cfd89f3b6951704998d6ec3ff..bc9f640395017e2a2b8dede846f6a974ee5a9231 100644
--- a/src/lisp/x86-arch.h
+++ b/src/lisp/x86-arch.h
@@ -17,16 +17,14 @@ extern boolean os_support_sse2(void);
 #define FPU_STATE_SIZE 27
 
 /* 
- * Need 512 byte area, aligned on a 16-byte boundary.  So allocate
- * 512+16 bytes of space and let the routine adjust the appropriate
- * alignment.
+ * Need 512 byte area, aligned on a 16-byte boundary.
  */
-#define SSE_STATE_SIZE ((512+16)/4)
+#define SSE_STATE_SIZE 512
 
 /*
  * Just use the SSE size for both x87 and sse2 since the SSE size is
- * enough for either.
+ * enough for either.  Make sure it's on a 16-byte boundary.
  */
-#define FPU_STATE(name)    int name[SSE_STATE_SIZE];
+#define FPU_STATE(name)    u_int8_t name[SSE_STATE_SIZE] __attribute__((aligned(16)))
 
 #endif
diff --git a/src/lisp/x86-assem.S b/src/lisp/x86-assem.S
index b7aa7f183ecb804d5b00563ef53cbd6172952cba..eda760d633743609e22d09c733c5b126ca2d6a03 100644
--- a/src/lisp/x86-assem.S
+++ b/src/lisp/x86-assem.S
@@ -382,7 +382,39 @@ ENDFUNC(fastcopy16)
  * %eax = address
  */
 FUNCDEF(alloc_overflow_sse2)
-	STACK_PROLOGUE(20)
+	# Need 8*16 bytes for the xmm registers, and space to save ecx
+	# and edx, space for mxcsr, a temp, and one arg to pass to alloc.
+	# That's 8*16 + 5*4 = 148 bytes.  Might as well have a few
+	# more so the xmm0 area is 16-byte aligned. That makes it 160
+	# bytes.
+	#
+	# Stack looks like:
+	#
+	#      +160
+	#      +144 -> xmm7
+	#      +128 -> xmm6
+	#      +112 -> xmm5
+	#      +96  -> xmm4
+	#      +80  -> xmm3
+	#      +64  -> xmm2
+	#      +48  -> xmm1
+	#      +32  -> xmm0
+	#      +20  -> unused
+	#      +16  -> temp
+	#      +12  -> mxcsr
+	#      + 8  -> save ecx
+	#      + 4  -> save edx
+	#  esp + 0  -> arg for alloc
+	STACK_PROLOGUE(160)
+	movapd  %xmm0, (32 + 0*16)(%esp)
+	movapd  %xmm1, (32 + 1*16)(%esp)
+	movapd  %xmm2, (32 + 2*16)(%esp)
+	movapd  %xmm3, (32 + 3*16)(%esp)
+	movapd  %xmm4, (32 + 4*16)(%esp)
+	movapd  %xmm5, (32 + 5*16)(%esp)
+	movapd  %xmm6, (32 + 6*16)(%esp)
+	movapd  %xmm7, (32 + 7*16)(%esp)
+
 	movl	%ecx, 8(%esp)	# Save ecx and edx registers
 	movl	%edx, 4(%esp)
 	stmxcsr 12(%esp)	# Save MXCSR
@@ -398,10 +430,20 @@ FUNCDEF(alloc_overflow_sse2)
 	movl	4(%esp), %edx	# Restore edx and ecx registers.  eax has the return value.
 	movl	8(%esp), %ecx
 	ldmxcsr	12(%esp)
+
+	movapd  (32 + 0*16)(%esp), %xmm0
+	movapd  (32 + 1*16)(%esp), %xmm1
+	movapd  (32 + 2*16)(%esp), %xmm2
+	movapd  (32 + 3*16)(%esp), %xmm3
+	movapd  (32 + 4*16)(%esp), %xmm4
+	movapd  (32 + 5*16)(%esp), %xmm5
+	movapd  (32 + 6*16)(%esp), %xmm6
+	movapd  (32 + 7*16)(%esp), %xmm7
+
 	STACK_EPILOGUE
 	ret
 ENDFUNC(alloc_overflow_sse2)	
-		
+
 #ifdef LINKAGE_TABLE
 
 /* Call into C code to resolve a linkage entry.  The initial code in the