diff --git a/CMakeLists.txt b/CMakeLists.txt
index ef8906c..1b9b5a7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -157,6 +157,10 @@ option(LLVM_ENABLE_THREADS "Use threads if available." ON)
 
 option(LLVM_ENABLE_ZLIB "Use zlib for compression/decompression if available." ON)
 
+option(LLVM_ENABLE_RNG "Enable random number generation." ON)
+
+option(LLVM_WITH_OPENSSL "Use the OpenSSL libcrypto library." OFF)
+
 if( LLVM_TARGETS_TO_BUILD STREQUAL "all" )
   set( LLVM_TARGETS_TO_BUILD ${LLVM_ALL_TARGETS} )
 endif()
diff --git a/Makefile.config.in b/Makefile.config.in
index dcca45f..b81b58e 100644
--- a/Makefile.config.in
+++ b/Makefile.config.in
@@ -406,3 +406,6 @@ endif
 ifeq ($(USE_OPROFILE), 1)
   OPTIONAL_COMPONENTS += OProfileJIT
 endif
+
+# Do we want to enable openssl support?
+USE_OPENSSL := @USE_OPENSSL@
diff --git a/autoconf/configure.ac b/autoconf/configure.ac
index f9c365c..8f36539 100644
--- a/autoconf/configure.ac
+++ b/autoconf/configure.ac
@@ -1121,6 +1121,23 @@ AC_ARG_WITH(internal-prefix,
     withval="")
 AC_SUBST(INTERNAL_PREFIX,[$withval])
 
+dnl Enable random number generation using openssl (or fallback to a LCG)
+AC_ARG_ENABLE(rng,
+              AS_HELP_STRING([--enable-rng],
+                             [Enable random number generation (default is
+                              YES)]),,
+                              enableval=default)
+case "$enableval" in
+  yes) AC_SUBST(LLVM_ENABLE_RNG,[1]) ;;
+  no)  AC_SUBST(LLVM_ENABLE_RNG,[0]) ;;
+  default) AC_SUBST(LLVM_ENABLE_RNG,[1]) ;;
+  *) AC_MSG_ERROR([Invalid setting for --enable-rng. Use "yes" or "no"]) ;;
+esac
+AC_DEFINE_UNQUOTED([LLVM_ENABLE_RNG],$LLVM_ENABLE_RNG,
+                   [Define if RNG is enabled])
+
+
+
 dnl===-----------------------------------------------------------------------===
 dnl===
 dnl=== SECTION 4: Check for programs we need and that they are the right version
@@ -1553,6 +1570,22 @@ fi
 AC_SUBST(LIBXML2_LIBS)
 AC_SUBST(LIBXML2_INC)
 
+dnl openssl is optional; used for RNG
+AC_ARG_WITH(openssl,
+  AS_HELP_STRING([--with-openssl],
+    [Use the openssl libcrypto library]),
+    [
+      AC_SUBST(USE_OPENSSL, [1])
+      AC_CHECK_LIB(crypto, AES_ctr128_encrypt, [], [
+        echo "Error! You need to have openssl installed."
+        exit -1
+      ])
+    ],
+    AC_SUBST(USE_OPENSSL, [0]))
+AC_DEFINE_UNQUOTED([USE_OPENSSL],$USE_OPENSSL,
+                   [Define if use the openssl libcrypto library])
+
+
 dnl===-----------------------------------------------------------------------===
 dnl===
 dnl=== SECTION 6: Check for header files
@@ -1594,6 +1627,13 @@ if test "$LLVM_ENABLE_ZLIB" -eq 1 ; then
 else
   AC_SUBST(HAVE_LIBZ, 0)
 fi
+if test "$USE_OPENSSL" -eq 1 ; then
+  AC_CHECK_HEADERS([openssl/aes.h openssl/evp.h],
+                   AC_SUBST(HAVE_OPENSSL, 1),
+                   AC_SUBST(HAVE_OPENSSL, 0))
+else
+  AC_SUBST(HAVE_OPENSSL, 0)
+fi
 
 dnl Try to find ffi.h.
 if test "$llvm_cv_enable_libffi" = "yes" ; then
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index 57725f8..c2c93be 100755
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -67,6 +67,8 @@ check_include_file(unistd.h HAVE_UNISTD_H)
 check_include_file(utime.h HAVE_UTIME_H)
 check_include_file(valgrind/valgrind.h HAVE_VALGRIND_VALGRIND_H)
 check_include_file(zlib.h HAVE_ZLIB_H)
+check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
+check_include_file(openssl/evp.h HAVE_OPENSSL_EVP_H)
 check_include_file(fenv.h HAVE_FENV_H)
 check_symbol_exists(FE_ALL_EXCEPT "fenv.h" HAVE_DECL_FE_ALL_EXCEPT)
 check_symbol_exists(FE_INEXACT "fenv.h" HAVE_DECL_FE_INEXACT)
@@ -111,6 +113,11 @@ if( NOT PURE_WINDOWS )
   else()
     set(HAVE_TERMINFO 0)
   endif()
+  if (LLVM_WITH_OPENSSL)
+    check_library_exists(crypto AES_ctr128_encrypt "" HAVE_OPENSSL)
+  else()
+    set(HAVE_OPENSSL 0)
+  endif()
 endif()
 
 # function checks
@@ -474,6 +481,14 @@ if (LLVM_ENABLE_ZLIB )
   endif()
 endif()
 
+if( LLVM_ENABLE_RNG AND LLVM_WITH_OPENSSL )
+  if( NOT HAVE_OPENSSL_AES_H OR NOT HAVE_OPENSSL_EVP_H OR NOT HAVE_OPENSSL )
+    set(LLVM_WITH_OPENSSL 0)
+  else()
+    set(USE_OPENSSL 1)
+  endif()
+endif()
+
 set(LLVM_PREFIX ${CMAKE_INSTALL_PREFIX})
 
 if (LLVM_ENABLE_DOXYGEN)
diff --git a/cmake/modules/LLVM-Config.cmake b/cmake/modules/LLVM-Config.cmake
index 9fa45ce..37e3877 100644
--- a/cmake/modules/LLVM-Config.cmake
+++ b/cmake/modules/LLVM-Config.cmake
@@ -21,6 +21,9 @@ function(get_system_libs return_var)
       if ( LLVM_ENABLE_ZLIB AND HAVE_LIBZ )
         set(system_libs ${system_libs} z)
       endif()
+      if ( LLVM_ENABLE_RNG AND USE_OPENSSL )
+        set(system_libs ${system_libs} crypto)
+      endif()
     endif( MINGW )
   endif( NOT MSVC )
   set(${return_var} ${system_libs} PARENT_SCOPE)
diff --git a/configure b/configure
index f3a6594..ac6ec34 100755
--- a/configure
+++ b/configure
@@ -720,6 +720,7 @@ EXTRA_LD_OPTIONS
 CLANG_SRC_ROOT
 BINUTILS_INCDIR
 INTERNAL_PREFIX
+LLVM_ENABLE_RNG
 NM
 ifGNUmake
 LN_S
@@ -777,9 +778,11 @@ USE_INTEL_JITEVENTS
 XML2CONFIG
 LIBXML2_LIBS
 LIBXML2_INC
+USE_OPENSSL
 CXXCPP
 HAVE_PTHREAD
 HAVE_LIBZ
+HAVE_OPENSSL
 HUGE_VAL_SANITY
 MMAP_FILE
 SHLIBEXT
@@ -1457,6 +1460,7 @@ Optional Features:
   --enable-terminfo       Query the terminfo database if available (default is
                           YES)
   --enable-libffi         Check for the presence of libffi (default is NO)
+  --enable-rng            Enable random number generation (default is YES)
   --enable-ltdl-install   install libltdl
 
 Optional Packages:
@@ -1487,6 +1491,7 @@ Optional Packages:
                           Tell OProfile >= 0.9.4 how to symbolize JIT output
   --with-intel-jitevents  Notify Intel JIT profiling API of generated code
 
+  --with-openssl          Use the openssl libcrypto library
 
 Some influential environment variables:
   CC          C compiler command
@@ -6070,6 +6075,32 @@ fi
 INTERNAL_PREFIX=$withval
 
 
+# Check whether --enable-rng was given.
+if test "${enable_rng+set}" = set; then
+  enableval=$enable_rng;
+else
+  enableval=default
+fi
+
+case "$enableval" in
+  yes) LLVM_ENABLE_RNG=1
+ ;;
+  no)  LLVM_ENABLE_RNG=0
+ ;;
+  default) LLVM_ENABLE_RNG=1
+ ;;
+  *) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-rng. Use \"yes\" or \"no\"" >&5
+echo "$as_me: error: Invalid setting for --enable-rng. Use \"yes\" or \"no\"" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define LLVM_ENABLE_RNG $LLVM_ENABLE_RNG
+_ACEOF
+
+
+
+
 
 { echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
 echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6; }
@@ -10586,7 +10617,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10589 "configure"
+#line 10620 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13805,6 +13836,117 @@ fi
 
 
 
+# Check whether --with-openssl was given.
+if test "${with_openssl+set}" = set; then
+  withval=$with_openssl;
+      USE_OPENSSL=1
+
+
+{ echo "$as_me:$LINENO: checking for AES_ctr128_encrypt in -lcrypto" >&5
+echo $ECHO_N "checking for AES_ctr128_encrypt in -lcrypto... $ECHO_C" >&6; }
+if test "${ac_cv_lib_crypto_AES_ctr128_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char AES_ctr128_encrypt ();
+int
+main ()
+{
+return AES_ctr128_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypto_AES_ctr128_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_crypto_AES_ctr128_encrypt=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_AES_ctr128_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_AES_ctr128_encrypt" >&6; }
+if test $ac_cv_lib_crypto_AES_ctr128_encrypt = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCRYPTO 1
+_ACEOF
+
+  LIBS="-lcrypto $LIBS"
+
+else
+
+        echo "Error! You need to have openssl installed."
+        exit -1
+
+fi
+
+
+else
+  USE_OPENSSL=0
+
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define USE_OPENSSL $USE_OPENSSL
+_ACEOF
+
+
+
+
 
 
 
@@ -16567,6 +16709,185 @@ else
   HAVE_LIBZ=0
 
 fi
+if test "$USE_OPENSSL" -eq 1 ; then
+
+
+for ac_header in openssl/aes.h openssl/evp.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to http://llvm.org/bugs/ ##
+## ------------------------------------ ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ HAVE_OPENSSL=1
+
+else
+  HAVE_OPENSSL=0
+
+fi
+
+done
+
+else
+  HAVE_OPENSSL=0
+
+fi
 
 if test "$llvm_cv_enable_libffi" = "yes" ; then
 
@@ -23084,6 +23405,7 @@ EXTRA_LD_OPTIONS!$EXTRA_LD_OPTIONS$ac_delim
 CLANG_SRC_ROOT!$CLANG_SRC_ROOT$ac_delim
 BINUTILS_INCDIR!$BINUTILS_INCDIR$ac_delim
 INTERNAL_PREFIX!$INTERNAL_PREFIX$ac_delim
+LLVM_ENABLE_RNG!$LLVM_ENABLE_RNG$ac_delim
 NM!$NM$ac_delim
 ifGNUmake!$ifGNUmake$ac_delim
 LN_S!$LN_S$ac_delim
@@ -23141,9 +23463,11 @@ USE_INTEL_JITEVENTS!$USE_INTEL_JITEVENTS$ac_delim
 XML2CONFIG!$XML2CONFIG$ac_delim
 LIBXML2_LIBS!$LIBXML2_LIBS$ac_delim
 LIBXML2_INC!$LIBXML2_INC$ac_delim
+USE_OPENSSL!$USE_OPENSSL$ac_delim
 CXXCPP!$CXXCPP$ac_delim
 HAVE_PTHREAD!$HAVE_PTHREAD$ac_delim
 HAVE_LIBZ!$HAVE_LIBZ$ac_delim
+HAVE_OPENSSL!$HAVE_OPENSSL$ac_delim
 HUGE_VAL_SANITY!$HUGE_VAL_SANITY$ac_delim
 MMAP_FILE!$MMAP_FILE$ac_delim
 SHLIBEXT!$SHLIBEXT$ac_delim
@@ -23157,9 +23481,6 @@ LLVM_INCLUDEDIR!$LLVM_INCLUDEDIR$ac_delim
 LLVM_INFODIR!$LLVM_INFODIR$ac_delim
 LLVM_MANDIR!$LLVM_MANDIR$ac_delim
 LLVM_CONFIGTIME!$LLVM_CONFIGTIME$ac_delim
-BINDINGS_TO_BUILD!$BINDINGS_TO_BUILD$ac_delim
-ALL_BINDINGS!$ALL_BINDINGS$ac_delim
-OCAML_LIBDIR!$OCAML_LIBDIR$ac_delim
 _ACEOF
 
   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -23201,6 +23522,9 @@ _ACEOF
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   cat >conf$$subs.sed <<_ACEOF
+BINDINGS_TO_BUILD!$BINDINGS_TO_BUILD$ac_delim
+ALL_BINDINGS!$ALL_BINDINGS$ac_delim
+OCAML_LIBDIR!$OCAML_LIBDIR$ac_delim
 ENABLE_VISIBILITY_INLINES_HIDDEN!$ENABLE_VISIBILITY_INLINES_HIDDEN$ac_delim
 RPATH!$RPATH$ac_delim
 RDYNAMIC!$RDYNAMIC$ac_delim
@@ -23209,7 +23533,7 @@ LIBOBJS!$LIBOBJS$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 6; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 9; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h
index 0c21e76..facdec4 100644
--- a/include/llvm/CodeGen/CommandFlags.h
+++ b/include/llvm/CodeGen/CommandFlags.h
@@ -210,4 +210,9 @@ cl::opt<std::string> StartAfter("start-after",
                           cl::value_desc("pass-name"),
                           cl::init(""));
 
+cl::opt<bool>
+NOPInsertion("nop-insertion",
+             cl::desc("Randomly add NOPs."),
+             cl::init(false));
+
 #endif
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index e1349a6..dc3e846 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -64,7 +64,8 @@ public:
     FrameSetup   = 1 << 0,              // Instruction is used as a part of
                                         // function frame setup code.
     BundledPred  = 1 << 1,              // Instruction has bundled predecessors.
-    BundledSucc  = 1 << 2               // Instruction has bundled successors.
+    BundledSucc  = 1 << 2,              // Instruction has bundled successors.
+    InsertedNOP  = 1 << 3
   };
 private:
   const MCInstrDesc *MCID;              // Instruction descriptor.
@@ -709,6 +710,12 @@ public:
     }
   }
 
+  //// isInsertedNOP - Return true if the instruction is an
+  //// artificially inserted NOP
+  bool isInsertedNOP() const {
+    return getFlag(InsertedNOP);
+  }
+
   /// Return the number of instructions inside the MI bundle, excluding the
   /// bundle header.
   ///
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index 77de967..fb8dfb5 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -438,6 +438,12 @@
 /* Define to 1 if you have the <zlib.h> header file. */
 #cmakedefine HAVE_ZLIB_H ${HAVE_ZLIB_H}
 
+/* Define to 1 if you have the <openssl/aes.h> header file. */
+#cmakedefine HAVE_OPENSSL_AES_H ${HAVE_OPENSSL_AES_H}
+
+/* Define to 1 if you have the <openssl/evp.h> header file. */
+#cmakedefine HAVE_OPENSSL_EVP_H ${HAVE_OPENSSL_EVP_H}
+
 /* Have host's _alloca */
 #cmakedefine HAVE__ALLOCA ${HAVE__ALLOCA}
 
@@ -507,6 +513,9 @@
 /* Installation directory for documentation */
 #cmakedefine LLVM_DOCSDIR "${LLVM_DOCSDIR}"
 
+/* Define if RNG is enabled */
+#cmakedefine01 LLVM_ENABLE_RNG
+
 /* Define if threads enabled */
 #cmakedefine01 LLVM_ENABLE_THREADS
 
@@ -650,6 +659,9 @@
 /* Define to 1 if your <sys/time.h> declares `struct tm'. */
 #undef TM_IN_SYS_TIME
 
+/* Define if use the openssl libcrypto library */
+#cmakedefine USE_OPENSSL ${USE_OPENSSL}
+
 /* Define if use udis86 library */
 #undef USE_UDIS86
 
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index 860bccb..5a49fca 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -202,6 +202,9 @@
 /* Set to 1 if the isnan function is found in <math.h> */
 #undef HAVE_ISNAN_IN_MATH_H
 
+/* Define to 1 if you have the `crypto' library (-lcrypto). */
+#undef HAVE_LIBCRYPTO
+
 /* Define if you have the libdl library or equivalent. */
 #undef HAVE_LIBDL
 
@@ -297,6 +300,12 @@
 /* Define to 1 if you have the `opendir' function. */
 #undef HAVE_OPENDIR
 
+/* Define to 1 if you have the <openssl/aes.h> header file. */
+#undef HAVE_OPENSSL_AES_H
+
+/* Define to 1 if you have the <openssl/evp.h> header file. */
+#undef HAVE_OPENSSL_EVP_H
+
 /* Define to 1 if you have the `posix_spawn' function. */
 #undef HAVE_POSIX_SPAWN
 
@@ -542,6 +551,9 @@
 /* Installation directory for documentation */
 #undef LLVM_DOCSDIR
 
+/* Define if RNG is enabled */
+#undef LLVM_ENABLE_RNG
+
 /* Define if threads enabled */
 #undef LLVM_ENABLE_THREADS
 
@@ -685,6 +697,9 @@
 /* Define to 1 if your <sys/time.h> declares `struct tm'. */
 #undef TM_IN_SYS_TIME
 
+/* Define if use the openssl libcrypto library */
+#undef USE_OPENSSL
+
 /* Define if use udis86 library */
 #undef USE_UDIS86
 
diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h
index 3fa89c1..8e6b42c 100644
--- a/include/llvm/MC/MCRegisterInfo.h
+++ b/include/llvm/MC/MCRegisterInfo.h
@@ -18,6 +18,7 @@
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/RandomNumberGenerator.h"
 #include <cassert>
 
 namespace llvm {
diff --git a/include/llvm/Support/RandomNumberGenerator.h b/include/llvm/Support/RandomNumberGenerator.h
new file mode 100644
index 0000000..b21398a
--- /dev/null
+++ b/include/llvm/Support/RandomNumberGenerator.h
@@ -0,0 +1,120 @@
+#ifndef RANDOMNUMBERGENERATOR_H_
+#define RANDOMNUMBERGENERATOR_H_
+
+#include <llvm/Config/config.h>
+#include <llvm/ADT/ilist.h>
+#include <llvm/ADT/SmallVector.h>
+#include <string>
+#include <inttypes.h>
+
+#if HAVE_OPENSSL_AES_H
+#include <openssl/aes.h>
+#endif
+
+#define AES_KEY_LENGTH 16 // bytes
+#define AES_BLOCK_SIZE 16
+#define PBKDF_ITERATIONS 1000
+
+namespace llvm {
+
+class StringRef;
+
+/* Random number generator based on either the AES block cipher from
+ * openssl or an integrated linear congruential generator. DO NOT use
+ * the LCG for any security application.
+ */
+class RandomNumberGenerator {
+private:
+  /** Imports state file from disk */
+  void ReadStateFile(StringRef StateFilename);
+
+  /** Writes current RNG state to disk */
+  void WriteStateFile(StringRef StateFilename);
+
+  RandomNumberGenerator();
+  RandomNumberGenerator(RandomNumberGenerator const&);
+  RandomNumberGenerator& operator=(RandomNumberGenerator const&) {
+    return *this;
+  }
+
+  void Reseed(StringRef Password, uint64_t Salt);
+
+  // Internal state
+#if USE_OPENSSL
+  unsigned char IV[AES_BLOCK_SIZE];
+  AES_KEY AESKey;
+  unsigned char Key[AES_KEY_LENGTH];
+  unsigned char EcountBuffer[AES_BLOCK_SIZE];
+  unsigned int Num;
+  unsigned char Plaintext[AES_KEY_LENGTH];
+#else
+  uint64_t state;
+#endif
+
+public:
+  static std::string EntropyData;
+
+  uint64_t Random();
+  uint64_t Random(uint64_t Max);
+
+  static RandomNumberGenerator& Generator() {
+    static RandomNumberGenerator instance;
+    return instance;
+  };
+
+  ~RandomNumberGenerator();
+
+  /**
+   * Shuffles an *array* of type T.
+   *
+   * Uses the Durstenfeld version of the Fisher-Yates method (aka the Knuth
+   * method).  See http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
+   */
+  template<typename T>
+    void shuffle(T* array, size_t length) {
+    for (size_t i = length - 1; i > 0; i--) {
+      size_t j = Random(i + 1);
+      if (j < i)
+        std::swap(array[j], array[i]);
+    }
+  }
+
+  /**
+   * Shuffles a SmallVector of type T, default size N
+   */
+  template<typename T, unsigned N>
+    void shuffle(SmallVector<T, N>& sv) {
+    if (sv.empty()) return;
+    for (size_t i = sv.size() - 1; i > 0; i--) {
+      size_t j = Random(i + 1);
+      if (j < i)
+        std::swap(sv[j], sv[i]);
+    }
+  }
+
+  /**
+   * Shuffles an iplist of type T
+   */
+  template<typename T>
+    void shuffle(iplist<T>& list){
+    if(list.empty()) return;
+    SmallVector<T*, 10> sv;
+    for(typename iplist<T>::iterator i = list.begin(); i != list.end(); ){
+      /* iplist<T>::remove() actually increments the iterator, so the
+       * for loop shouldn't increment it either.
+       */
+      T* t = list.remove(i);
+      sv.push_back(t);
+    }
+    shuffle<T*, 10>(sv);
+    for(typename SmallVector<T*, 10>::size_type i = 0; i < sv.size(); i++){
+      list.push_back(sv[i]);
+    }
+  }
+
+};
+
+
+}
+
+#endif
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index d9c8651..05aa955 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -50,8 +50,9 @@ namespace llvm {
           GuaranteedTailCallOpt(false), DisableTailCalls(false),
           StackAlignmentOverride(0),
           EnableFastISel(false), PositionIndependentExecutable(false),
-          EnableSegmentedStacks(false), UseInitArray(false), TrapFuncName(""),
-          FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard)
+          EnableSegmentedStacks(false), NOPInsertion(false), UseInitArray(false),
+          TrapFuncName(""), FloatABIType(FloatABI::Default),
+          AllowFPOpFusion(FPOpFusion::Standard)
     {}
 
     /// PrintMachineCode - This flag is enabled when the -print-machineinstrs
@@ -154,6 +155,9 @@ namespace llvm {
 
     unsigned EnableSegmentedStacks : 1;
 
+    /// Attempt to insert NOPs
+    unsigned NOPInsertion : 1;
+
     /// UseInitArray - Use .init_array instead of .ctors for static
     /// constructors.
     unsigned UseInitArray : 1;
diff --git a/lib/CodeGen/LLVMBuild.txt b/lib/CodeGen/LLVMBuild.txt
index 81ef1aa..664612b 100644
--- a/lib/CodeGen/LLVMBuild.txt
+++ b/lib/CodeGen/LLVMBuild.txt
@@ -22,4 +22,4 @@ subdirectories = AsmPrinter SelectionDAG
 type = Library
 name = CodeGen
 parent = Libraries
-required_libraries = Analysis Core MC Scalar Support Target TransformUtils ObjCARC
+required_libraries = Analysis Core Instrumentation MC Scalar Support Target TransformUtils ObjCARC
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index 5633271..87afe44 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -171,7 +171,7 @@ MachineBasicBlock::SkipPHIsAndLabels(MachineBasicBlock::iterator I) {
 
 MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() {
   iterator B = begin(), E = end(), I = E;
-  while (I != B && ((--I)->isTerminator() || I->isDebugValue()))
+  while (I != B && ((--I)->isTerminator() || I->isDebugValue() || I->isInsertedNOP()))
     ; /*noop */
   while (I != E && !I->isTerminator())
     ++I;
@@ -181,7 +181,7 @@ MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() {
 MachineBasicBlock::const_iterator
 MachineBasicBlock::getFirstTerminator() const {
   const_iterator B = begin(), E = end(), I = E;
-  while (I != B && ((--I)->isTerminator() || I->isDebugValue()))
+  while (I != B && ((--I)->isTerminator() || I->isDebugValue() || I->isInsertedNOP()))
     ; /*noop */
   while (I != E && !I->isTerminator())
     ++I;
@@ -190,7 +190,7 @@ MachineBasicBlock::getFirstTerminator() const {
 
 MachineBasicBlock::instr_iterator MachineBasicBlock::getFirstInstrTerminator() {
   instr_iterator B = instr_begin(), E = instr_end(), I = E;
-  while (I != B && ((--I)->isTerminator() || I->isDebugValue()))
+  while (I != B && ((--I)->isTerminator() || I->isDebugValue() || I->isInsertedNOP()))
     ; /*noop */
   while (I != E && !I->isTerminator())
     ++I;
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index f5fe168..f3c092b 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -28,6 +28,7 @@
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/RandomNumberGenerator.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetLowering.h"
@@ -103,6 +104,19 @@ static cl::opt<unsigned> AvgIPC(
   "sched-avg-ipc", cl::Hidden, cl::init(1),
   cl::desc("Average inst/cycle whan no target itinerary exists."));
 
+#if LLVM_ENABLE_RNG
+static cl::opt<bool> RandomizeSchedule(
+  "sched-randomize",
+  cl::desc("Enable randomization of scheduling"),
+  cl::init(false));
+
+static cl::opt<unsigned> SchedRandPercentage(
+  "sched-randomize-percentage",
+  cl::desc("Percentage of instructions where schedule is randomized"),
+  cl::init(50));
+#endif
+
+
 namespace {
 //===----------------------------------------------------------------------===//
 /// ScheduleDAGRRList - The actual register reduction list scheduler
@@ -1765,6 +1779,19 @@ template<class SF>
 class RegReductionPriorityQueue : public RegReductionPQBase {
   SF Picker;
 
+#if LLVM_ENABLE_RNG
+  static SUnit *popRandom(std::vector<SUnit*> &Q) {
+    RandomNumberGenerator &randGen =
+      RandomNumberGenerator::Generator();
+    size_t randIndex = randGen.Random(Q.size());
+    SUnit *V = Q[randIndex];
+    if (randIndex < Q.size() - 1)
+      std::swap(Q[randIndex], Q.back());
+    Q.pop_back();
+    return V;
+  }
+#endif
+
 public:
   RegReductionPriorityQueue(MachineFunction &mf,
                             bool tracksrp,
@@ -1785,7 +1812,23 @@ public:
   SUnit *pop() {
     if (Queue.empty()) return NULL;
 
-    SUnit *V = popFromQueue(Queue, Picker, scheduleDAG);
+    SUnit *V;
+#if LLVM_ENABLE_RNG
+    if (RandomizeSchedule) {
+      RandomNumberGenerator &randGen =
+        RandomNumberGenerator::Generator();
+      unsigned int Roll = randGen.Random(100);
+      if (Roll < SchedRandPercentage) {
+        V = popRandom(Queue);
+      } else {
+        V = popFromQueue(Queue, Picker, scheduleDAG);
+      }
+    } else {
+#endif
+      V = popFromQueue(Queue, Picker, scheduleDAG);
+#if LLVM_ENABLE_RNG
+    }
+#endif
     V->NodeQueueId = 0;
     return V;
   }
diff --git a/lib/Makefile b/lib/Makefile
index 0a4435e..c8e5127 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -12,7 +12,7 @@ include $(LEVEL)/Makefile.config
 
 PARALLEL_DIRS := IR AsmParser Bitcode Analysis Transforms CodeGen \
                  Target ExecutionEngine Linker MC Object Option DebugInfo \
-								 IRReader
+                                                                IRReader
 
 include $(LEVEL)/Makefile.common
 
diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt
index 3aecf3f..0f8893d 100644
--- a/lib/Support/CMakeLists.txt
+++ b/lib/Support/CMakeLists.txt
@@ -38,6 +38,7 @@ add_llvm_library(LLVMSupport
   MD5.cpp
   PluginLoader.cpp
   PrettyStackTrace.cpp
+  RandomNumberGenerator.cpp
   Regex.cpp
   SmallPtrSet.cpp
   SmallVector.cpp
diff --git a/lib/Support/RandomNumberGenerator.cpp b/lib/Support/RandomNumberGenerator.cpp
new file mode 100644
index 0000000..75f406c
--- /dev/null
+++ b/lib/Support/RandomNumberGenerator.cpp
@@ -0,0 +1,271 @@
+
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements cryptographically secure random number generation
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "rng"
+#include "llvm/Support/RandomNumberGenerator.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#if LLVM_ENABLE_RNG == 1 && HAVE_OPENSSL_AES_H && HAVE_OPENSSL_EVP_H
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+#endif
+
+extern int errno;
+
+using namespace llvm;
+
+STATISTIC(RandomNumbersGenerated, "Number of random numbers generated");
+
+// This is outside the ENABLE_RNG define since it needs to be set
+// outside of LLVM, without knowledge of how LLVM was configured.
+std::string RandomNumberGenerator::EntropyData;
+
+#if LLVM_ENABLE_RNG == 1
+
+namespace {
+  static cl::opt<unsigned long long>
+  RandomSeed("rng-seed", cl::value_desc("seed"),
+             cl::desc("Seed for the random number generator"));
+
+  static cl::opt<std::string>
+  RNGStateFile("rng-state-file", cl::value_desc("filename"),
+               cl::desc("State filename for the random number generator"));
+
+  static cl::opt<std::string, true>
+  EntropyDataOpt("entropy-data", cl::desc("Entropy data for the random number generator (testing only, should be set by command line options"), cl::Hidden, cl::location(RandomNumberGenerator::EntropyData));
+}
+
+
+RandomNumberGenerator::~RandomNumberGenerator() {
+  if (!RNGStateFile.empty()) {
+    WriteStateFile(RNGStateFile);
+  }
+}
+
+
+#if USE_OPENSSL
+
+RandomNumberGenerator::RandomNumberGenerator() {
+  DEBUG(errs() << "AES RNG: Initializing context ");
+  if (RandomSeed != 0 && !EntropyData.empty()) {
+    DEBUG(errs() << " with command line seed and entropy data\n");
+
+    // Seed properly
+    Reseed(EntropyData, RandomSeed);
+
+  } else if(RNGStateFile != "") {
+    // Fall back on state file...if provided.
+    DEBUG(errs() << " with file\n");
+    ReadStateFile(RNGStateFile);
+  } else{
+    Reseed("", 0);
+    DEBUG(errs() << " to default\n");
+    DEBUG(errs() << "Warning! Using unseeded random number generator\n");
+  }
+}
+
+void RandomNumberGenerator::Reseed(StringRef Password, uint64_t Salt) {
+  DEBUG(errs() << "Re-Seeding AES RNG context from salt and password\n");
+  DEBUG(errs() << "Entropy: " << Password << "\n");
+  DEBUG(errs() << "Seed: " << Salt << "\n");
+
+  unsigned KeyLen = AES_KEY_LENGTH + 2*AES_BLOCK_SIZE;
+  unsigned char *RandomBytes = (unsigned char*) malloc(KeyLen);
+  PKCS5_PBKDF2_HMAC_SHA1(Password.data(), Password.size(), (unsigned char*)&Salt, sizeof(Salt), PBKDF_ITERATIONS, KeyLen, RandomBytes);
+
+  // TODO(sjcrane): check return val
+  memcpy(Key, RandomBytes, AES_KEY_LENGTH);
+  AES_set_encrypt_key(Key, AES_KEY_LENGTH*8, &AESKey);
+  memcpy(IV, RandomBytes + AES_KEY_LENGTH, AES_BLOCK_SIZE);
+  memcpy(Plaintext, RandomBytes + AES_KEY_LENGTH + AES_BLOCK_SIZE, AES_BLOCK_SIZE);
+
+  free(RandomBytes);
+}
+
+void RandomNumberGenerator::ReadStateFile(StringRef StateFilename) {
+  DEBUG(errs() << "Re-Seeding AES RNG context from state file\n");
+  DEBUG(errs() << "File: " << StateFilename << "\n");
+
+
+  struct stat s;
+  /* Don't read if there's no file specified.
+   * TODO(tmjackso): This probably shouldn't fail silently. */
+  if (StateFilename.empty() || stat(StateFilename.data(), &s) != 0) {
+    return;
+  }
+
+  int fhandle = open(StateFilename.data(), O_RDONLY);
+  int bytes_read = 0;
+
+  uint16_t keylength;
+  unsigned char* KeyBytes[AES_KEY_LENGTH];
+
+  /* uint16_t: keysize */
+  bytes_read += read(fhandle, (char *)&keylength, sizeof(uint16_t));
+  assert(keylength == AES_KEY_LENGTH && "Invalid key length");
+
+  /* keylength * uint8_t: key */
+  bytes_read += read(fhandle, (char *)Key, AES_KEY_LENGTH);
+
+  /* 16 * uint8_t: plaintext */
+  bytes_read += read(fhandle, (char *)Plaintext, AES_BLOCK_SIZE);
+
+  /* 8 * uint8_t: IV (nonce+counter) */
+  bytes_read += read(fhandle, (char *)IV, AES_BLOCK_SIZE);
+
+  if (bytes_read != s.st_size) {
+    // We didn't read the whole file
+    errs() << "Warning: Did not read the entire state file!\n";
+  }
+
+  close(fhandle);
+
+  // TODO(sjcrane): check return val
+  AES_set_encrypt_key(Key, AES_KEY_LENGTH*8, &AESKey);
+}
+
+RandomNumberGenerator::RandomNumberGenerator(RandomNumberGenerator const& a) {
+  DEBUG(errs() << "Initialising AES RNG context from copy constructor\n");
+  AESKey = a.AESKey;
+  memcpy(Key, a.Key, AES_KEY_LENGTH);
+  memcpy(IV, a.IV, AES_BLOCK_SIZE);
+  memcpy(EcountBuffer, a.EcountBuffer, AES_BLOCK_SIZE);
+  Num = a.Num;
+}
+
+void RandomNumberGenerator::WriteStateFile(StringRef StateFilename) {
+  DEBUG(errs() << "Writing RNG state file to " << StateFilename << "\n");
+
+  /* Don't serialise without a file name */
+  assert(!StateFilename.empty() && "Cannot serialize RNG state file without a filename");
+
+  uint16_t keylength = AES_KEY_LENGTH;
+
+  int fhandle = open(StateFilename.data(), O_WRONLY);
+  int byte_count = 0;
+  byte_count += write(fhandle, (char *)&keylength, sizeof(uint16_t));
+  byte_count += write(fhandle, (char *)Key, AES_KEY_LENGTH);
+  byte_count += write(fhandle, (char *)Plaintext, AES_BLOCK_SIZE);
+  byte_count += write(fhandle, (char *)IV, AES_BLOCK_SIZE);
+  close(fhandle);
+}
+
+uint64_t RandomNumberGenerator::Random() {
+  RandomNumbersGenerated++;
+
+  unsigned char Output[AES_BLOCK_SIZE];
+  AES_ctr128_encrypt(Plaintext, Output, AES_BLOCK_SIZE, &AESKey, IV, EcountBuffer, &Num);
+
+  uint64_t OutValue;
+  memcpy(&OutValue, Output, sizeof(uint64_t));
+  return OutValue;
+}
+
+uint64_t RandomNumberGenerator::Random(uint64_t Max) {
+  uint64_t t = Max * (((uint64_t)1 << 63) / Max);
+  uint64_t r;
+  while ((r = Random()) >= t) { /* NOOP */ }
+
+  return r % Max;
+}
+
+#else // do not use libcrypto
+
+namespace {
+  static const uint64_t LOW = 0x330e;
+  static const uint64_t A = 0x5deece66dULL;
+  static const uint64_t C = 0xb;
+  static const uint64_t M = 0x0000ffffffffffffULL;
+}
+
+RandomNumberGenerator::RandomNumberGenerator() : state(0) {
+  DEBUG(errs() << "Fallback RNG: Initializing ");
+  if (RandomSeed != 0) {
+    // Seed properly
+    DEBUG(errs() << " with command line seed\n");
+
+    state = (RandomSeed << 16) | LOW;
+  } else if(RNGStateFile != "") {
+    DEBUG(errs() << " with state file\n");
+
+    // Fall back on state file...if provided.
+    ReadStateFile(RNGStateFile);
+  } else{
+    DEBUG(errs() << "Warning! Using unseeded random number generator\n");
+  }
+}
+
+RandomNumberGenerator::RandomNumberGenerator(RandomNumberGenerator const& a) : state(0) {
+  state = a.state;
+}
+
+void RandomNumberGenerator::ReadStateFile(StringRef StateFilename) {
+  struct stat s;
+  // Don't read if there's no file specified.
+  if (StateFilename.empty() || stat(StateFilename.data(), &s) != 0) {
+    return;
+  }
+
+  int fhandle = open(StateFilename.data(), O_RDONLY);
+  int bytes_read = 0;
+
+
+  DEBUG(errs() << "Reading RNG state file from " << RNGStateFile << "\n");
+  bytes_read += read(fhandle, &state, sizeof(uint64_t));
+
+  close(fhandle);
+}
+
+void RandomNumberGenerator::WriteStateFile(StringRef StateFilename) {
+  /* Don't serialise without a file name */
+  assert(!StateFilename.empty() && "Cannot serialize RNG state file without a filename");
+
+
+  int fhandle = open(StateFilename.data(), O_WRONLY);
+  int byte_count = 0;
+  byte_count += write(fhandle, (char *)&state, sizeof(uint64_t));
+  close(fhandle);
+}
+
+/* This RNG only generates 32 bits of randomness, so we have to cast it down
+ * and then up
+ */
+uint64_t RandomNumberGenerator::Random() {
+  RandomNumbersGenerated++;
+
+  state = (A * state + C) & M;
+  return static_cast<uint32_t>(state >> 17);
+}
+
+/*
+ * With only 32 bits of randomness, we do a proportional shift to ensure we
+ * get even distribution over the potential max.
+ */
+uint64_t RandomNumberGenerator::Random(uint64_t max) {
+  return (static_cast<double>(Random()) / UINT32_MAX) * max;
+}
+
+#endif // USE_OPENSSL
+
+#endif // LLVM_ENABLE_RNG
diff --git a/lib/Target/X86/CMakeLists.txt b/lib/Target/X86/CMakeLists.txt
index 7e20151..242327d 100644
--- a/lib/Target/X86/CMakeLists.txt
+++ b/lib/Target/X86/CMakeLists.txt
@@ -13,6 +13,7 @@ tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget)
 add_public_tablegen_target(X86CommonTableGen)
 
 set(sources
+  NOPInsertion.cpp
   X86AsmPrinter.cpp
   X86COFFMachineModuleInfo.cpp
   X86CodeEmitter.cpp
diff --git a/lib/Target/X86/NOPInsertion.cpp b/lib/Target/X86/NOPInsertion.cpp
new file mode 100644
index 0000000..540d4f3
--- /dev/null
+++ b/lib/Target/X86/NOPInsertion.cpp
@@ -0,0 +1,172 @@
+//===- NOPInsertion.cpp - Insert NOPs between instructions    ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the NOPInsertion pass.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "nop-insertion"
+#include "X86InstrBuilder.h"
+#include "X86InstrInfo.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/RandomNumberGenerator.h"
+#include "llvm/Target/TargetInstrInfo.h"
+
+using namespace llvm;
+
+#if LLVM_ENABLE_RNG
+
+namespace {
+  static cl::opt<unsigned>
+  NOPInsertionPercentage(
+    "nop-insertion-percentage",
+    cl::desc("Percentage of instructions that have NOPs prepended"),
+    cl::init(50));
+
+  static cl::opt<unsigned>
+  MaxNOPsPerInstruction(
+    "max-nops-per-instruction",
+    llvm::cl::desc("Maximum number of NOPs per instruction"),
+    llvm::cl::init(1));
+}
+
+
+STATISTIC(PreNOPFunctionCount,     "Pre-NOP insertion function count");
+STATISTIC(PreNOPBasicBlockCount,   "Pre-NOP insertion basic block count");
+STATISTIC(PreNOPInstructionCount,  "Pre-NOP insertion instruction count");
+STATISTIC(InsertedInstructions,    "Total number of inserted instructions");
+STATISTIC(NumNOPInstructions,      "Number of inserted NOP instructions");
+STATISTIC(NumMovEBPInstructions,   "Number of inserted MOV EBP, EBP instructions");
+STATISTIC(NumMovESPInstructions,   "Number of inserted MOV ESP, ESP instructions");
+STATISTIC(NumLeaESIInstructions,   "Number of inserted LEA ESI, ESI instructions");
+STATISTIC(NumLeaEDIInstructions,   "Number of inserted LEA EDI, EDI instructions");
+
+namespace {
+class NOPInsertionPass : public MachineFunctionPass {
+
+  static char ID;
+
+  bool is64Bit;
+
+  void IncrementCounters(int const code);
+public:
+  NOPInsertionPass(bool is64Bit_) :
+      MachineFunctionPass(ID), is64Bit(is64Bit_) {
+  }
+
+  virtual bool runOnMachineFunction(MachineFunction &MF);
+
+  virtual const char *getPassName() const {
+    return "NOP insertion pass";
+  }
+
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.setPreservesCFG();
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+};
+}
+
+char NOPInsertionPass::ID = 0;
+
+enum { NOP,
+       MOV_EBP, MOV_ESP,
+       LEA_ESI, LEA_EDI,
+       MAX_NOPS };
+
+static const unsigned nopRegs[MAX_NOPS][2] = {
+    { 0, 0 },
+    { X86::EBP, X86::RBP },
+    { X86::ESP, X86::RSP },
+    { X86::ESI, X86::RSI },
+    { X86::EDI, X86::RDI },
+};
+
+void NOPInsertionPass::IncrementCounters(int const code) {
+  ++InsertedInstructions;
+  switch(code) {
+  case NOP:      ++NumNOPInstructions; break;
+  case MOV_EBP:  ++NumMovEBPInstructions; break;
+  case MOV_ESP:  ++NumMovESPInstructions; break;
+  case LEA_ESI:  ++NumLeaESIInstructions; break;
+  case LEA_EDI:  ++NumLeaEDIInstructions; break;
+  }
+}
+
+bool NOPInsertionPass::runOnMachineFunction(MachineFunction &Fn) {
+  const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo();
+  PreNOPFunctionCount++;
+  static int nopsInserted = 0;
+  for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
+    PreNOPBasicBlockCount++;
+    PreNOPInstructionCount += BB->size();
+
+    for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
+      MachineBasicBlock::iterator J = next(I);
+      if (I->isPseudo()) {
+        I = J;
+        continue;
+      }
+      for (unsigned int i = 0; i < MaxNOPsPerInstruction; i++) {
+        unsigned int Roll = RandomNumberGenerator::Generator().Random(100);
+        if (Roll >= NOPInsertionPercentage)
+          continue;
+
+        int NOPCode = RandomNumberGenerator::Generator().Random(MAX_NOPS);
+
+        MachineInstr *NewMI = NULL;
+        unsigned reg = nopRegs[NOPCode][!!is64Bit];
+        switch (NOPCode) {
+        case NOP:
+          NewMI = BuildMI(*BB, I, I->getDebugLoc(), TII->get(X86::NOOP));
+          nopsInserted++;
+          break;
+        case MOV_EBP:
+        case MOV_ESP: {
+          unsigned opc = is64Bit ? X86::MOV64rr : X86::MOV32rr;
+          NewMI = BuildMI(*BB, I, I->getDebugLoc(), TII->get(opc), reg)
+            .addReg(reg);
+          nopsInserted++;
+          break;
+        }
+
+        case LEA_ESI:
+        case LEA_EDI: {
+          unsigned opc = is64Bit ? X86::LEA64r : X86::LEA32r;
+          NewMI = addRegOffset(BuildMI(*BB, I, I->getDebugLoc(),
+                                       TII->get(opc), reg),
+                               reg, false, 0);
+          nopsInserted++;
+          break;
+        }
+        }
+
+        if (NewMI != NULL) {
+          IncrementCounters(NOPCode);
+          NewMI->setFlag(MachineInstr::InsertedNOP);
+        }
+      }
+      I = J;
+    }
+  }
+  return true;
+}
+
+FunctionPass *llvm::createNOPInsertionPass(bool is64Bit) {
+  return new NOPInsertionPass(is64Bit);
+}
+
+#endif // LLVM_ENABLE_RNG
diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h
index 947002f..8a7eaa4 100644
--- a/lib/Target/X86/X86.h
+++ b/lib/Target/X86/X86.h
@@ -52,6 +52,10 @@ FunctionPass *createX86FloatingPointStackifierPass();
 /// AVX and SSE.
 FunctionPass *createX86IssueVZeroUpperPass();
 
+/// createNOPInsertionPass - This pass adds NOPs at random between
+/// instructions.
+FunctionPass *createNOPInsertionPass(bool is64Bit);
+
 /// createX86CodeEmitterPass - Return a pass that emits the collected X86 code
 /// to the specified MCE object.
 FunctionPass *createX86JITCodeEmitterPass(X86TargetMachine &TM,
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index 81423a3..4dc587c 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -223,6 +223,13 @@ bool X86PassConfig::addPreEmitPass() {
     ShouldPrint = true;
   }
 
+#if LLVM_ENABLE_RNG
+  if (TM->Options.NOPInsertion) {
+    addPass(createNOPInsertionPass(getX86Subtarget().is64Bit()));
+    ShouldPrint = true;
+  }
+#endif
+
   return ShouldPrint;
 }
 
diff --git a/test/CodeGen/X86/nop-insert-percentage.ll b/test/CodeGen/X86/nop-insert-percentage.ll
new file mode 100644
index 0000000..62f3bba
--- /dev/null
+++ b/test/CodeGen/X86/nop-insert-percentage.ll
@@ -0,0 +1,46 @@
+; RUN: llc < %s -entropy-data="entropy" -rng-seed=1 -nop-insertion -nop-insertion-percentage=10 \
+; RUN:     | FileCheck %s --check-prefix=PERCENT10
+; RUN: llc < %s -entropy-data="entropy" -rng-seed=1 -nop-insertion -nop-insertion-percentage=50 \
+; RUN:     | FileCheck %s --check-prefix=PERCENT50
+; RUN: llc < %s -entropy-data="entropy" -rng-seed=1 -nop-insertion -nop-insertion-percentage=100 \
+; RUN:     | FileCheck %s --check-prefix=PERCENT100
+; REQUIRES: openssl
+
+; This test case tests NOP insertion at varying percentage levels.
+
+define i32 @test(i32 %x, i32 %y, i32 %z) {
+entry:
+    %t1 = add i32 %x, %y
+    %t2 = mul i32 %t1, %z
+    %t3 = add i32 %t2, %x
+    %t4 = mul i32 %t3, %z
+    %t5 = add i32 %t4, %x
+    %t6 = mul i32 %t5, %z
+    %t7 = add i32 %t6, %x
+    %t8 = mul i32 %t7, %z
+    %t9 = add i32 %t8, %x
+    %t10 = mul i32 %t9, %z
+    %t11 = add i32 %t10, %x
+    ret i32 %t11
+}
+
+; PERCENT10: movq    %rbp, %rbp
+
+; PERCENT50: leaq	(%rdi), %rdi
+; PERCENT50: movq    %rsp, %rsp
+; PERCENT50: movq    %rbp, %rbp
+; PERCENT50: leaq	(%rsi), %rsi
+; PERCENT50: nop
+
+; PERCENT100: leaq	(%rsi), %rsi
+; PERCENT100: nop
+; PERCENT100: leaq	(%rsi), %rsi
+; PERCENT100: movq    %rsp, %rsp
+; PERCENT100: movq    %rsp, %rsp
+; PERCENT100: movq    %rbp, %rbp
+; PERCENT100: leaq	(%rsi), %rsi
+; PERCENT100: leaq	(%rsi), %rsi
+; PERCENT100: movq    %rsp, %rsp
+; PERCENT100: leaq	(%rsi), %rsi
+; PERCENT100: movq    %rbp, %rbp
+; PERCENT100: leaq	(%rsi), %rsi
diff --git a/test/CodeGen/X86/nop-insert.ll b/test/CodeGen/X86/nop-insert.ll
new file mode 100644
index 0000000..222043f
--- /dev/null
+++ b/test/CodeGen/X86/nop-insert.ll
@@ -0,0 +1,27 @@
+; RUN: llc < %s -nop-insertion | FileCheck %s
+; RUN: llc < %s -nop-insertion -entropy-data="test" -rng-seed=10 | FileCheck %s --check-prefix=SEED1
+; RUN: llc < %s -nop-insertion -entropy-data="test" -rng-seed=25 | FileCheck %s --check-prefix=SEED2
+; RUN: llc < %s -nop-insertion -entropy-data="test" -rng-seed=1534 | FileCheck %s --check-prefix=SEED3
+; RUN: llc < %s -nop-insertion -entropy-data="different entropy" -rng-seed=10 | FileCheck %s --check-prefix=ENTROPY
+; REQUIRES: openssl
+
+; This test case checks that NOPs are inserted, and that the RNG seed
+; affects both the placement and choice of these NOPs.
+
+; CHECK: movq    %rbp, %rbp
+; SEED1: nop
+; SEED1-NOT: movq    %rbp, %rbp
+; SEED2-NOT: nop
+; SEED2-NOT: movq    %rbp, %rbp
+; SEED3: movq    %rbp, %rbp
+; SEED3: movq    %rbp, %rbp
+; SEED3: leaq	(%rsi), %rsi
+; SEED3-NOT: nop
+; ENTROPY: movq    %rbp, %rbp
+; ENTROPY: nop
+define i32 @test1(i32 %x, i32 %y, i32 %z) {
+entry:
+    %tmp = mul i32 %x, %y
+    %tmp2 = add i32 %tmp, %z
+    ret i32 %tmp2
+}
diff --git a/test/CodeGen/X86/sched-rnd-test.ll b/test/CodeGen/X86/sched-rnd-test.ll
new file mode 100644
index 0000000..88d7165
--- /dev/null
+++ b/test/CodeGen/X86/sched-rnd-test.ll
@@ -0,0 +1,37 @@
+; RUN: llc < %s -entropy-data="entropy" -rng-seed=1 -sched-randomize -sched-randomize-percentage=100 | FileCheck %s --check-prefix=SEED1
+; RUN: llc < %s -entropy-data="entropy" -rng-seed=3 -sched-randomize -sched-randomize-percentage=100 | FileCheck %s --check-prefix=SEED2
+; RUN: llc < %s -entropy-data="entropy" -rng-seed=1 -sched-randomize -sched-randomize-percentage=50 | FileCheck %s --check-prefix=PERCENTAGE
+; REQUIRES: openssl
+
+; This test case checks that the schedule randomization is changing
+; scheduling decisions, that different seeds result in different
+; schedules, and that the percentage alters the amount of
+; randomization
+
+define i32 @test(i32 %x, i32 %y, i32 %z) {
+entry:
+    %a = add i32 %x, %y
+    %b = add i32 %x, %z
+    %c = add i32 %y, %z
+    %d = mul i32 %a, %b
+    %e = mul i32 %d, %c
+    ret i32 %e
+}
+
+; SEED1: leal	(%rdi,%rsi), %eax
+; SEED1-NEXT: addl	%edx, %edi
+; SEED1-NEXT:	imull	%edi, %eax
+; SEED1-NEXT:	addl	%edx, %esi
+; SEED1-NEXT:	imull	%esi, %eax
+
+; SEED2: leal	(%rdi,%rdx), %ecx
+; SEED2-NEXT:	leal	(%rdi,%rsi), %eax
+; SEED2-NEXT:	addl	%edx, %esi
+; SEED2-NEXT:	imull	%ecx, %eax
+; SEED2-NEXT:	imull	%esi, %eax
+
+; PERCENTAGE: leal	(%rdi,%rdx), %ecx
+; PERCENTAGE-NEXT: leal	(%rdi,%rsi), %eax
+; PERCENTAGE-NEXT: imull	%ecx, %eax
+; PERCENTAGE-NEXT: addl	%edx, %esi
+; PERCENTAGE-NEXT: imull	%esi, %eax
diff --git a/test/Makefile b/test/Makefile
index 33c8a0c..4584128 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -145,6 +145,7 @@ lit.site.cfg: FORCE
 	@$(ECHOPATH) s=@HOST_OS@=$(HOST_OS)=g >> lit.tmp
 	@$(ECHOPATH) s=@HOST_ARCH@=$(HOST_ARCH)=g >> lit.tmp
 	@$(ECHOPATH) s=@HAVE_LIBZ@=$(HAVE_LIBZ)=g >> lit.tmp
+	@$(ECHOPATH) s=@USE_OPENSSL@=$(USE_OPENSSL)=g >> lit.tmp
 	@sed -f lit.tmp $(PROJ_SRC_DIR)/lit.site.cfg.in > $@
 	@-rm -f lit.tmp
 
diff --git a/test/lit.cfg b/test/lit.cfg
index 9e4e0b0..024e095 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -279,6 +279,9 @@ if not 'hexagon' in config.target_triple:
 if config.have_zlib == "1":
     config.available_features.add("zlib")
 
+if config.use_openssl == "1":
+    config.available_features.add("openssl")
+
 # Native compilation: host arch == target arch
 if config.host_arch in config.target_triple:
     config.available_features.add("native")
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
index 6ebdddf..55713ca 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.in
@@ -22,6 +22,7 @@ config.host_arch = "@HOST_ARCH@"
 config.llvm_use_intel_jitevents = "@LLVM_USE_INTEL_JITEVENTS@"
 config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
 config.have_zlib = "@HAVE_LIBZ@"
+config.use_openssl = "@USE_OPENSSL@"
 
 # Support substitution of the tools_dir with user parameters. This is
 # used when we can't determine the tool dir at configuration time.
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 6aac8ff..87fb450 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -33,6 +33,7 @@
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/PluginLoader.h"
 #include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/RandomNumberGenerator.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetRegistry.h"
@@ -191,6 +192,16 @@ int main(int argc, char **argv) {
 
   cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
 
+  // Seed the RNG
+  // If entropy already set (for predictable testing), ignore
+  if (RandomNumberGenerator::EntropyData.empty()) {
+    std::string seeddata;
+    for (int i = 0; i < argc; ++i) {
+      seeddata += argv[i];
+    }
+    RandomNumberGenerator::EntropyData = seeddata;
+  }
+
   // Compile the module TimeCompilations times to give better compile time
   // metrics.
   for (unsigned I = TimeCompilations; I; --I)
@@ -279,6 +290,7 @@ static int compileModule(char **argv, LLVMContext &Context) {
   Options.PositionIndependentExecutable = EnablePIE;
   Options.EnableSegmentedStacks = SegmentedStacks;
   Options.UseInitArray = UseInitArray;
+  Options.NOPInsertion = NOPInsertion;
 
   OwningPtr<TargetMachine>
     target(TheTarget->createTargetMachine(TheTriple.getTriple(),
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index 19e8c4c..6555293 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -35,6 +35,7 @@
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/RandomNumberGenerator.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/TargetSelect.h"
@@ -393,7 +394,20 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
 
   Module *mergedModule = Linker.getModule();
 
-  // Mark which symbols can not be internalized
+  // if options were requested, set them
+  if ( !CodegenOptions.empty() )
+    cl::ParseCommandLineOptions(CodegenOptions.size(),
+                                const_cast<char **>(&CodegenOptions[0]));
+
+  // Seed the RNG
+  std::string seeddata;
+  for (std::vector<char*>::iterator I = CodegenOptions.begin(),
+       E = CodegenOptions.end(); I != E; ++I) {
+    seeddata += *I;
+  }
+  RandomNumberGenerator::EntropyData = seeddata;
+
+  // mark which symbols can not be internalized
   this->applyScopeRestrictions();
 
   // Instantiate the pass manager to organize the passes.
diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp
index 1a9d8f5..9bbd502 100644
--- a/tools/lto/LTOModule.cpp
+++ b/tools/lto/LTOModule.cpp
@@ -33,11 +33,13 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/RandomNumberGenerator.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/system_error.h"
 #include "llvm/Target/TargetRegisterInfo.h"
+
 using namespace llvm;
 
 static cl::opt<bool>
@@ -195,6 +197,7 @@ LTOModule *LTOModule::makeLTOModule(const char *path, std::string &errMsg) {
     errMsg = ec.message();
     return NULL;
   }
+  RandomNumberGenerator::EntropyData.append(path);
   return makeLTOModule(buffer.take(), errMsg);
 }
 
@@ -213,6 +216,7 @@ LTOModule *LTOModule::makeLTOModule(int fd, const char *path,
     errMsg = ec.message();
     return NULL;
   }
+  RandomNumberGenerator::EntropyData.append(path);
   return makeLTOModule(buffer.take(), errMsg);
 }
 
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 94f4cca..2834882 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -36,6 +36,7 @@
 #include "llvm/Support/PassNameParser.h"
 #include "llvm/Support/PluginLoader.h"
 #include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/RandomNumberGenerator.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/SystemUtils.h"
@@ -522,6 +523,7 @@ static TargetOptions GetTargetOptions() {
   Options.PositionIndependentExecutable = EnablePIE;
   Options.EnableSegmentedStacks = SegmentedStacks;
   Options.UseInitArray = UseInitArray;
+  Options.NOPInsertion = NOPInsertion;
   return Options;
 }
 
@@ -594,6 +596,13 @@ int main(int argc, char **argv) {
   cl::ParseCommandLineOptions(argc, argv,
     "llvm .bc -> .bc modular optimizer and analysis printer\n");
 
+  // Seed the RNG
+  std::string seeddata;
+  for (int i = 0; i < argc; ++i) {
+    seeddata += argv[i];
+  }
+  RandomNumberGenerator::EntropyData = seeddata;
+
   if (AnalyzeOnly && NoOutput) {
     errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n";
     return 1;
