diff --git a/example/mini_core.rs b/example/mini_core.rs
index 94336154748..a972beedaa3 100644
--- a/example/mini_core.rs
+++ b/example/mini_core.rs
@@ -58,6 +58,7 @@ unsafe impl Copy for char {}
 unsafe impl<'a, T: ?Sized> Copy for &'a T {}
 unsafe impl<T: ?Sized> Copy for *const T {}
 unsafe impl<T: ?Sized> Copy for *mut T {}
+unsafe impl<T: Copy> Copy for Option<T> {}
 
 #[lang = "sync"]
 pub unsafe trait Sync {}
@@ -336,6 +337,24 @@ impl<T: ?Sized> PartialEq for *const T {
     }
 }
 
+impl <T: PartialEq> PartialEq for Option<T> {
+    fn eq(&self, other: &Self) -> bool {
+        match (self, other) {
+            (Some(lhs), Some(rhs)) => *lhs == *rhs,
+            (None, None) => true,
+            _ => false,
+        }
+    }
+
+    fn ne(&self, other: &Self) -> bool {
+        match (self, other) {
+            (Some(lhs), Some(rhs)) => *lhs != *rhs,
+            (None, None) => false,
+            _ => true,
+        }
+    }
+}
+
 #[lang = "neg"]
 pub trait Neg {
     type Output;
diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs
index d79f9f5f79c..f1c037696d8 100644
--- a/example/mini_core_hello_world.rs
+++ b/example/mini_core_hello_world.rs
@@ -285,6 +285,10 @@ fn main() {
     let slice_ptr = &[] as *const [u8];
     slice_ptr as *const u8;
 
+    let repeat = [Some(42); 2];
+    assert_eq!(repeat[0], Some(42));
+    assert_eq!(repeat[1], Some(42));
+
     #[cfg(not(jit))]
     test_tls();
 
diff --git a/src/base.rs b/src/base.rs
index 7c43dc68deb..cae2115ab18 100644
--- a/src/base.rs
+++ b/src/base.rs
@@ -693,10 +693,29 @@ fn trans_stmt<'tcx>(
                         .val
                         .try_to_bits(fx.tcx.data_layout.pointer_size)
                         .unwrap();
-                    for i in 0..times {
-                        let index = fx.bcx.ins().iconst(fx.pointer_type, i as i64);
+                    if fx.clif_type(operand.layout().ty) == Some(types::I8) {
+                        let times = fx.bcx.ins().iconst(fx.pointer_type, times as i64);
+                        // FIXME use emit_small_memset where possible
+                        let addr = lval.to_ptr().get_addr(fx);
+                        let val = operand.load_scalar(fx);
+                        fx.bcx.call_memset(fx.cx.module.target_config(), addr, val, times);
+                    } else {
+                        let loop_block = fx.bcx.create_block();
+                        let done_block = fx.bcx.create_block();
+                        let index = fx.bcx.append_block_param(loop_block, fx.pointer_type);
+                        let zero = fx.bcx.ins().iconst(fx.pointer_type, 0);
+                        fx.bcx.ins().jump(loop_block, &[zero]);
+
+                        fx.bcx.switch_to_block(loop_block);
                         let to = lval.place_index(fx, index);
                         to.write_cvalue(fx, operand);
+
+                        let index = fx.bcx.ins().iadd_imm(index, 1);
+                        let done = fx.bcx.ins().icmp_imm(IntCC::Equal, index, times as i64);
+                        fx.bcx.ins().brz(done, loop_block, &[index]);
+                        fx.bcx.ins().jump(done_block, &[]);
+
+                        fx.bcx.switch_to_block(done_block);
                     }
                 }
                 Rvalue::Len(place) => {