diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 0ba5451bd72f5..618e8b8699fcc 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -29,7 +29,7 @@ use std::fmt;
 use std::fs;
 use std::io;
 use std::path::{Path, PathBuf};
-use std::process::{Output, Stdio};
+use std::process::{Output, Stdio, ExitStatus};
 use std::str;
 use std::env;
 
@@ -510,21 +510,6 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
     sess.abort_if_errors();
 
     // Invoke the system linker
-    //
-    // Note that there's a terribly awful hack that really shouldn't be present
-    // in any compiler. Here an environment variable is supported to
-    // automatically retry the linker invocation if the linker looks like it
-    // segfaulted.
-    //
-    // Gee that seems odd, normally segfaults are things we want to know about!
-    // Unfortunately though in rust-lang/rust#38878 we're experiencing the
-    // linker segfaulting on Travis quite a bit which is causing quite a bit of
-    // pain to land PRs when they spuriously fail due to a segfault.
-    //
-    // The issue #38878 has some more debugging information on it as well, but
-    // this unfortunately looks like it's just a race condition in macOS's linker
-    // with some thread pool working in the background. It seems that no one
-    // currently knows a fix for this so in the meantime we're left with this...
     info!("{:?}", &cmd);
     let retry_on_segfault = env::var("RUSTC_RETRY_LINKER_ON_SEGFAULT").is_ok();
     let mut prog;
@@ -567,21 +552,59 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
             info!("{:?}", &cmd);
             continue;
         }
+
+        // Here's a terribly awful hack that really shouldn't be present in any
+        // compiler. Here an environment variable is supported to automatically
+        // retry the linker invocation if the linker looks like it segfaulted.
+        //
+        // Gee that seems odd, normally segfaults are things we want to know
+        // about!  Unfortunately though in rust-lang/rust#38878 we're
+        // experiencing the linker segfaulting on Travis quite a bit which is
+        // causing quite a bit of pain to land PRs when they spuriously fail
+        // due to a segfault.
+        //
+        // The issue #38878 has some more debugging information on it as well,
+        // but this unfortunately looks like it's just a race condition in
+        // macOS's linker with some thread pool working in the background. It
+        // seems that no one currently knows a fix for this so in the meantime
+        // we're left with this...
         if !retry_on_segfault || i > 3 {
             break
         }
         let msg_segv = "clang: error: unable to execute command: Segmentation fault: 11";
         let msg_bus  = "clang: error: unable to execute command: Bus error: 10";
-        if !(out.contains(msg_segv) || out.contains(msg_bus)) {
-            break
+        if out.contains(msg_segv) || out.contains(msg_bus) {
+            warn!(
+                "looks like the linker segfaulted when we tried to call it, \
+                 automatically retrying again. cmd = {:?}, out = {}.",
+                cmd,
+                out,
+            );
+            continue;
         }
 
-        warn!(
-            "looks like the linker segfaulted when we tried to call it, \
-             automatically retrying again. cmd = {:?}, out = {}.",
-            cmd,
-            out,
-        );
+        if is_illegal_instruction(&output.status) {
+            warn!(
+                "looks like the linker hit an illegal instruction when we \
+                 tried to call it, automatically retrying again. cmd = {:?}, ]\
+                 out = {}, status = {}.",
+                cmd,
+                out,
+                output.status,
+            );
+            continue;
+        }
+
+        #[cfg(unix)]
+        fn is_illegal_instruction(status: &ExitStatus) -> bool {
+            use std::os::unix::prelude::*;
+            status.signal() == Some(libc::SIGILL)
+        }
+
+        #[cfg(windows)]
+        fn is_illegal_instruction(_status: &ExitStatus) -> bool {
+            false
+        }
     }
 
     match prog {