From 6d28b62c8fe61d0ee7915cbb0e209fd8c74efa77 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Mon, 22 Jan 2018 14:23:30 -0800
Subject: [PATCH] rustc: Upgrade to LLVM 6

The following submodules have been updated for a new version of LLVM:

- `src/llvm`
- `src/libcompiler_builtins` - transitively contains compiler-rt
- `src/dlmalloc`

This also updates the docker container for dist-i686-freebsd as the old 16.04
container is no longer capable of building LLVM. The
compiler-rt/compiler-builtins and dlmalloc updates are pretty routine without
much interesting happening, but the LLVM update here is of particular note.
Unlike previous updates I haven't cherry-picked all existing patches we had on
top of our LLVM branch as we have a [huge amount][patches4] and have at this
point forgotten what most of them are for. Instead I started from the current
`release_60` branch in LLVM and only applied patches that were necessary to get
our tests working and building.

The current set of custom rustc-specific patches included in this LLVM update are:

* rust-lang/llvm@1187443 - this is how we actually implement
  `cfg(target_feature)` for now and continues to not be upstreamed. While a
  hazard for SIMD stabilization this commit is otherwise keeping the status
  quo of a small rustc-specific feature.
* rust-lang/llvm@013f2ec - this is a rustc-specific optimization that we haven't
  upstreamed, notably teaching LLVM about our allocation-related routines (which
  aren't malloc/free). Once we stabilize the global allocator routines we will
  likely want to upstream this patch, but for now it seems reasonable to keep it
  on our fork.
* rust-lang/llvm@a65bbfd - I found this necessary to fix compilation of LLVM in
  our 32-bit linux container. I'm not really sure why it's necessary but my
  guess is that it's because of the absolutely ancient glibc that we're using.
  In any case it's only updating pieces we're not actually using in LLVM so I'm
  hoping it'll turn out alright. This doesn't seem like something we'll want to
  upstream.c
* rust-lang/llvm@77ab1f0 - this is what's actually enabling LLVM to build in our
  i686-freebsd container, I'm not really sure what's going on but we for sure
  probably don't want to upstream this and otherwise it seems not too bad for
  now at least.
* rust-lang/llvm@9eb9267 - we currently suffer on MSVC from an [upstream bug]
  which although diagnosed to a particular revision isn't currently fixed
  upstream (and the bug itself doesn't seem too active). This commit is a
  partial revert of the suspected cause of this regression (found via a
  bisection). I'm sort of hoping that this eventually gets fixed upstream with a
  similar fix (which we can replace in our branch), but for now I'm also hoping
  it's a relatively harmless change to have.

After applying these patches (plus one [backport] which should be [backported
upstream][llvm-back]) I believe we should have all tests working on all
platforms in our current test suite. I'm like 99% sure that we'll need some more
backports as issues are reported for LLVM 6 when this propagates through
nightlies, but that's sort of just par for the course nowadays!

In any case though some extra scrutiny of the patches here would definitely be
welcome, along with scrutiny of the "missing patches" like a [change to pass
manager order](rust-lang/llvm@27174447533), [another change to pass manager
order](rust-lang/llvm@c782febb7b9), some [compile fixes for
sparc](rust-lang/llvm@1a83de63c42), and some [fixes for
solaris](rust-lang/llvm@c2bfe0abb).

[patches4]: https://github.com/rust-lang/llvm/compare/5401fdf23...rust-llvm-release-4-0-1
[backport]: https://github.com/rust-lang/llvm/commit/5c54c252db
[llvm-back]: https://bugs.llvm.org/show_bug.cgi?id=36114
[upstream bug]: https://bugs.llvm.org/show_bug.cgi?id=36096

---

The update to LLVM 6 is desirable for a number of reasons, notably:

* This'll allow us to keep up with the upstream wasm backend, picking up new
  features as they start landing.
* Upstream LLVM has fixed a number of SIMD-related compilation errors,
  especially around AVX-512 and such.
* There's a few assorted known bugs which are fixed in LLVM 5 and aren't fixed
  in the LLVM 4 branch we're using.
* Overall it's not a great idea to stagnate with our codegen backend!

This update is mostly powered by #47730 which is allowing us to update LLVM
*independent* of the version of LLVM that Emscripten is locked to. This means
that when compiling code for Emscripten we'll still be using the old LLVM 4
backend, but when compiling code for any other target we'll be using the new
LLVM 6 target. Once Emscripten updates we may no longer need this distinction,
but we're not sure when that will happen!

Closes #43370
Closes #43418
Closes #47015
Closes #47683
Closes rust-lang-nursery/stdsimd#157
Closes rust-lang-nursery/rust-wasm#3
---
 src/ci/docker/dist-i686-freebsd/Dockerfile |  2 +-
 src/dlmalloc                               |  2 +-
 src/libcompiler_builtins                   |  2 +-
 src/llvm                                   |  2 +-
 src/rustllvm/RustWrapper.cpp               |  2 ++
 src/test/run-pass/backtrace-debuginfo.rs   | 34 ++++++++++++++++++----
 6 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/src/ci/docker/dist-i686-freebsd/Dockerfile b/src/ci/docker/dist-i686-freebsd/Dockerfile
index 686afc97289b1..673fa4c0c4bc0 100644
--- a/src/ci/docker/dist-i686-freebsd/Dockerfile
+++ b/src/ci/docker/dist-i686-freebsd/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:16.04
+FROM ubuntu:18.04
 
 RUN apt-get update && apt-get install -y --no-install-recommends \
   clang \
diff --git a/src/dlmalloc b/src/dlmalloc
index d3812c3accaee..a2b424b600235 160000
--- a/src/dlmalloc
+++ b/src/dlmalloc
@@ -1 +1 @@
-Subproject commit d3812c3accaee7ad23068ed4fc089cc05c7a538f
+Subproject commit a2b424b600235af58f453577c2da1b0e1de2ffa5
diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins
index 0a95675bab808..345447948f7a5 160000
--- a/src/libcompiler_builtins
+++ b/src/libcompiler_builtins
@@ -1 +1 @@
-Subproject commit 0a95675bab808c49f86208bacc89c5d9c53ac43f
+Subproject commit 345447948f7a51eca970fa036cefd613d54a4f79
diff --git a/src/llvm b/src/llvm
index bc344d5bc23c6..af0abda2f1984 160000
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit bc344d5bc23c61ff9baf82d268a0edf199933cc3
+Subproject commit af0abda2f19849e6f35364a489664788c456e69b
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 611d63f6a4d14..4dfc4029d75dc 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -552,9 +552,11 @@ static unsigned fromRust(LLVMRustDIFlags Flags) {
   if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
     Result |= DINode::DIFlags::FlagRValueReference;
   }
+#if LLVM_VERSION_LE(4, 0)
   if (isSet(Flags & LLVMRustDIFlags::FlagExternalTypeRef)) {
     Result |= DINode::DIFlags::FlagExternalTypeRef;
   }
+#endif
   if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
     Result |= DINode::DIFlags::FlagIntroducedVirtual;
   }
diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs
index e8b5f3490e50e..2b82a8943636e 100644
--- a/src/test/run-pass/backtrace-debuginfo.rs
+++ b/src/test/run-pass/backtrace-debuginfo.rs
@@ -15,11 +15,14 @@
 // Unfortunately, LLVM has no "disable" option for this, so we have to set
 // "enable" to 0 instead.
 
-// compile-flags:-g -Cllvm-args=-enable-tail-merge=0
+// compile-flags:-g -Cllvm-args=-enable-tail-merge=0 -Cllvm-args=-opt-bisect-limit=0
 // ignore-pretty issue #37195
 // ignore-cloudabi spawning processes is not supported
 // ignore-emscripten spawning processes is not supported
 
+// note that above `-opt-bisect-limit=0` is used to basically disable
+// optimizations
+
 use std::env;
 
 #[path = "backtrace-debuginfo-aux.rs"] mod aux;
@@ -114,18 +117,26 @@ fn outer(mut counter: i32, main_pos: Pos) {
     inner_inlined(&mut counter, main_pos, pos!());
 }
 
-fn check_trace(output: &str, error: &str) {
+fn check_trace(output: &str, error: &str) -> Result<(), String> {
     // reverse the position list so we can start with the last item (which was the first line)
     let mut remaining: Vec<&str> = output.lines().map(|s| s.trim()).rev().collect();
 
-    assert!(error.contains("stack backtrace"), "no backtrace in the error: {}", error);
+    if !error.contains("stack backtrace") {
+        return Err(format!("no backtrace found in stderr:\n{}", error))
+    }
     for line in error.lines() {
         if !remaining.is_empty() && line.contains(remaining.last().unwrap()) {
             remaining.pop();
         }
     }
-    assert!(remaining.is_empty(),
-            "trace does not match position list: {}\n---\n{}", error, output);
+    if !remaining.is_empty() {
+        return Err(format!("trace does not match position list\n\
+            still need to find {:?}\n\n\
+            --- stdout\n{}\n\
+            --- stderr\n{}",
+            remaining, output, error))
+    }
+    Ok(())
 }
 
 fn run_test(me: &str) {
@@ -133,6 +144,7 @@ fn run_test(me: &str) {
     use std::process::Command;
 
     let mut i = 0;
+    let mut errors = Vec::new();
     loop {
         let out = Command::new(me)
                           .env("RUST_BACKTRACE", "full")
@@ -143,10 +155,20 @@ fn run_test(me: &str) {
             assert!(output.contains("done."), "bad output for successful run: {}", output);
             break;
         } else {
-            check_trace(output, error);
+            if let Err(e) = check_trace(output, error) {
+                errors.push(e);
+            }
         }
         i += 1;
     }
+    if errors.len() > 0 {
+        for error in errors {
+            println!("---------------------------------------");
+            println!("{}", error);
+        }
+
+        panic!("found some errors");
+    }
 }
 
 #[inline(never)]