From 9cb29d2577f9c90efc327cce8edc8fa9f3ebb5a9 Mon Sep 17 00:00:00 2001
From: Leah Neukirchen <leah@vuxu.org>
Date: Wed, 19 Apr 2017 21:01:07 +0200
Subject: [PATCH] New package: llvm3.9-3.9.1

---
 srcpkgs/libllvm3.9                            |   1 +
 srcpkgs/llvm3.9/files/llvm-Config-config.h    |   9 ++
 .../llvm3.9/files/llvm-Config-llvm-config.h   |   9 ++
 .../patches/cfe/cfe-001-fix-stdint.patch      |  41 +++++
 .../cfe-003-fix-unwind-chain-inclusion.patch  |  45 ++++++
 .../cfe/cfe-004-add-musl-triples.patch        |  47 ++++++
 .../cfe/cfe-007-musl-use-init-array.patch     |  10 ++
 .../compiler-rt-002-musl-no-dlvsym.patch      |  11 ++
 .../llvm3.9/files/patches/lldb/fix-musl.patch |  41 +++++
 .../files/patches/lldb/zzz-aarch64.patch      |  17 +++
 .../files/patches/llvm/llvm-003-musl.patch    |  83 +++++++++++
 ...on-between-WQM-and-polygon-stippling.patch | 140 ++++++++++++++++++
 srcpkgs/llvm3.9/template                      | 112 ++++++++++++++
 srcpkgs/llvm3.9/update                        |   1 +
 14 files changed, 567 insertions(+)
 create mode 120000 srcpkgs/libllvm3.9
 create mode 100644 srcpkgs/llvm3.9/files/llvm-Config-config.h
 create mode 100644 srcpkgs/llvm3.9/files/llvm-Config-llvm-config.h
 create mode 100644 srcpkgs/llvm3.9/files/patches/cfe/cfe-001-fix-stdint.patch
 create mode 100644 srcpkgs/llvm3.9/files/patches/cfe/cfe-003-fix-unwind-chain-inclusion.patch
 create mode 100644 srcpkgs/llvm3.9/files/patches/cfe/cfe-004-add-musl-triples.patch
 create mode 100644 srcpkgs/llvm3.9/files/patches/cfe/cfe-007-musl-use-init-array.patch
 create mode 100644 srcpkgs/llvm3.9/files/patches/compiler-rt/compiler-rt-002-musl-no-dlvsym.patch
 create mode 100644 srcpkgs/llvm3.9/files/patches/lldb/fix-musl.patch
 create mode 100644 srcpkgs/llvm3.9/files/patches/lldb/zzz-aarch64.patch
 create mode 100644 srcpkgs/llvm3.9/files/patches/llvm/llvm-003-musl.patch
 create mode 100644 srcpkgs/llvm3.9/files/patches/llvm/reverse-llvm-AMDGPU-Fix-an-interaction-between-WQM-and-polygon-stippling.patch
 create mode 100644 srcpkgs/llvm3.9/template
 create mode 100644 srcpkgs/llvm3.9/update

diff --git a/srcpkgs/libllvm3.9 b/srcpkgs/libllvm3.9
new file mode 120000
index 00000000000..e4eeb1deeee
--- /dev/null
+++ b/srcpkgs/libllvm3.9
@@ -0,0 +1 @@
+llvm3.9
\ No newline at end of file
diff --git a/srcpkgs/llvm3.9/files/llvm-Config-config.h b/srcpkgs/llvm3.9/files/llvm-Config-config.h
new file mode 100644
index 00000000000..c369b4551f7
--- /dev/null
+++ b/srcpkgs/llvm3.9/files/llvm-Config-config.h
@@ -0,0 +1,9 @@
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 32
+#include "config-32.h"
+#elif __WORDSIZE == 64
+#include "config-64.h"
+#else
+#error "Unknown word size"
+#endif
diff --git a/srcpkgs/llvm3.9/files/llvm-Config-llvm-config.h b/srcpkgs/llvm3.9/files/llvm-Config-llvm-config.h
new file mode 100644
index 00000000000..2fa08c9be69
--- /dev/null
+++ b/srcpkgs/llvm3.9/files/llvm-Config-llvm-config.h
@@ -0,0 +1,9 @@
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 32
+#include "llvm-config-32.h"
+#elif __WORDSIZE == 64
+#include "llvm-config-64.h"
+#else
+#error "Unknown word size"
+#endif
diff --git a/srcpkgs/llvm3.9/files/patches/cfe/cfe-001-fix-stdint.patch b/srcpkgs/llvm3.9/files/patches/cfe/cfe-001-fix-stdint.patch
new file mode 100644
index 00000000000..17c6989dc8f
--- /dev/null
+++ b/srcpkgs/llvm3.9/files/patches/cfe/cfe-001-fix-stdint.patch
@@ -0,0 +1,41 @@
+From fd3bcfddcdb11757e95bc3a625017cbf234b67ed Mon Sep 17 00:00:00 2001
+From: Andrea Brancaleoni <miwaxe@gmail.com>
+Date: Tue, 8 Sep 2015 22:14:32 +0200
+Subject: [PATCH 1/7] fix stdint
+
+---
+ lib/Headers/stdint.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/lib/Headers/stdint.h b/lib/Headers/stdint.h
+index 0303db9..8ca28df 100644
+--- a/lib/Headers/stdint.h
++++ b/lib/Headers/stdint.h
+@@ -22,8 +22,6 @@
+  *
+ \*===----------------------------------------------------------------------===*/
+ 
+-#ifndef __CLANG_STDINT_H
+-#define __CLANG_STDINT_H
+ 
+ /* If we're hosted, fall back to the system's stdint.h, which might have
+  * additional definitions.
+@@ -72,6 +70,8 @@
+ # endif
+ 
+ #else
++#ifndef __CLANG_STDINT_H
++#define __CLANG_STDINT_H
+ 
+ /* C99 7.18.1.1 Exact-width integer types.
+  * C99 7.18.1.2 Minimum-width integer types.
+@@ -703,5 +703,5 @@ typedef __UINTMAX_TYPE__ uintmax_t;
+ #define INTMAX_C(v)   __INTN_C(__INTMAX_WIDTH__, v)
+ #define UINTMAX_C(v) __UINTN_C(__INTMAX_WIDTH__, v)
+ 
+-#endif /* __STDC_HOSTED__ */
+ #endif /* __CLANG_STDINT_H */
++#endif /* __STDC_HOSTED__ */
+-- 
+2.5.1
+
diff --git a/srcpkgs/llvm3.9/files/patches/cfe/cfe-003-fix-unwind-chain-inclusion.patch b/srcpkgs/llvm3.9/files/patches/cfe/cfe-003-fix-unwind-chain-inclusion.patch
new file mode 100644
index 00000000000..a399ac17a0c
--- /dev/null
+++ b/srcpkgs/llvm3.9/files/patches/cfe/cfe-003-fix-unwind-chain-inclusion.patch
@@ -0,0 +1,45 @@
+From 352974169f0d2b5da3d5321f588f5e3b5941330e Mon Sep 17 00:00:00 2001
+From: Andrea Brancaleoni <miwaxe@gmail.com>
+Date: Tue, 8 Sep 2015 22:14:57 +0200
+Subject: [PATCH 2/7] fix unwind chain inclusion
+
+---
+ lib/Headers/unwind.h | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/lib/Headers/unwind.h b/lib/Headers/unwind.h
+index 303d792..44e10cc 100644
+--- a/lib/Headers/unwind.h
++++ b/lib/Headers/unwind.h
+@@ -23,9 +23,6 @@
+ 
+ /* See "Data Definitions for libgcc_s" in the Linux Standard Base.*/
+ 
+-#ifndef __CLANG_UNWIND_H
+-#define __CLANG_UNWIND_H
+-
+ #if defined(__APPLE__) && __has_include_next(<unwind.h>)
+ /* Darwin (from 11.x on) provide an unwind.h. If that's available,
+  * use it. libunwind wraps some of its definitions in #ifdef _GNU_SOURCE,
+@@ -53,6 +50,9 @@
+ # endif
+ #else
+ 
++#ifndef __CLANG_UNWIND_H
++#define __CLANG_UNWIND_H
++
+ #include <stdint.h>
+ 
+ #ifdef __cplusplus
+@@ -277,6 +277,7 @@ _Unwind_Ptr _Unwind_GetTextRelBase(struct _Unwind_Context *);
+ }
+ #endif
+ 
++#endif /* __CLANG_UNWIND_H */
++
+ #endif
+ 
+-#endif /* __CLANG_UNWIND_H */
+-- 
+2.5.1
+
diff --git a/srcpkgs/llvm3.9/files/patches/cfe/cfe-004-add-musl-triples.patch b/srcpkgs/llvm3.9/files/patches/cfe/cfe-004-add-musl-triples.patch
new file mode 100644
index 00000000000..a96916b74e2
--- /dev/null
+++ b/srcpkgs/llvm3.9/files/patches/cfe/cfe-004-add-musl-triples.patch
@@ -0,0 +1,47 @@
+From 420899503863473ba40ba68a81134dbcb3c330e5 Mon Sep 17 00:00:00 2001
+From: Andrea Brancaleoni <miwaxe@gmail.com>
+Date: Tue, 8 Sep 2015 22:24:52 +0200
+Subject: [PATCH 3/7] add musl triples
+
+---
+ lib/Driver/ToolChains.cpp | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
+index 15e36a1..3cd6dd1 100644
+--- a/lib/Driver/ToolChains.cpp
++++ b/lib/Driver/ToolChains.cpp
+@@ -1275,7 +1275,10 @@ bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
+   static const char *const ARMTriples[] = {"arm-linux-gnueabi",
+                                            "arm-linux-androideabi"};
+   static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf",
+-                                             "armv7hl-redhat-linux-gnueabi"};
++                                             "armv7hl-redhat-linux-gnueabi",
++                                             "armv6-linux-musleabihf", "armv6l-linux-musleabihf",
++                                             "armv7-linux-musleabihf", "armv7l-linux-musleabihf",
++                                             "arm-linux-musleabihf" };
+   static const char *const ARMebLibDirs[] = {"/lib"};
+   static const char *const ARMebTriples[] = {"armeb-linux-gnueabi",
+                                              "armeb-linux-androideabi"};
+@@ -1289,6 +1292,7 @@ bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
+       "x86_64-redhat-linux",    "x86_64-suse-linux",
+       "x86_64-manbo-linux-gnu", "x86_64-linux-gnu",
+       "x86_64-slackware-linux", "x86_64-linux-android",
++      "x86_64-linux-musl",      "x86_64-pc-linux-musl",
+       "x86_64-unknown-linux"};
+   static const char *const X32LibDirs[] = {"/libx32"};
+   static const char *const X86LibDirs[] = {"/lib32", "/lib"};
+@@ -1297,7 +1301,9 @@ bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
+       "i386-linux-gnu",       "i386-redhat-linux6E",   "i686-redhat-linux",
+       "i586-redhat-linux",    "i386-redhat-linux",     "i586-suse-linux",
+       "i486-slackware-linux", "i686-montavista-linux", "i686-linux-android",
+-      "i586-linux-gnu"};
++      "i586-linux-gnu",       "i486-linux-musl",       "i486-pc-linux-musl",
++      "i686-linux-musl",      "i686-pc-linux-musl"
++    };
+ 
+   static const char *const MIPSLibDirs[] = {"/lib"};
+   static const char *const MIPSTriples[] = {
+-- 
+2.5.1
+
diff --git a/srcpkgs/llvm3.9/files/patches/cfe/cfe-007-musl-use-init-array.patch b/srcpkgs/llvm3.9/files/patches/cfe/cfe-007-musl-use-init-array.patch
new file mode 100644
index 00000000000..bab9a293106
--- /dev/null
+++ b/srcpkgs/llvm3.9/files/patches/cfe/cfe-007-musl-use-init-array.patch
@@ -0,0 +1,10 @@
+--- cfe-3.8.0.src/lib/Driver/ToolChains.cpp.orig
++++ cfe-3.8.0.src/lib/Driver/ToolChains.cpp
+@@ -2428,6 +2428,7 @@
+                                         ArgStringList &CC1Args) const {
+   const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
+   bool UseInitArrayDefault =
++      getTriple().getEnvironment() == llvm::Triple::Musl ||
+       getTriple().getArch() == llvm::Triple::aarch64 ||
+       getTriple().getArch() == llvm::Triple::aarch64_be ||
+       (getTriple().getOS() == llvm::Triple::Linux &&
diff --git a/srcpkgs/llvm3.9/files/patches/compiler-rt/compiler-rt-002-musl-no-dlvsym.patch b/srcpkgs/llvm3.9/files/patches/compiler-rt/compiler-rt-002-musl-no-dlvsym.patch
new file mode 100644
index 00000000000..70908618b15
--- /dev/null
+++ b/srcpkgs/llvm3.9/files/patches/compiler-rt/compiler-rt-002-musl-no-dlvsym.patch
@@ -0,0 +1,11 @@
+--- a/lib/interception/interception_linux.cc
++++ b/lib/interception/interception_linux.cc
+@@ -24,7 +24,7 @@ bool GetRealFunctionAddress(const char *func_name, uptr *func_addr,
+   return real == wrapper;
+ }
+ 
+-#if !defined(__ANDROID__)  // android does not have dlvsym
++#if defined(__GLIBC__) // !defined(__ANDROID__)  // android does not have dlvsym
+ void *GetFuncAddrVer(const char *func_name, const char *ver) {
+   return dlvsym(RTLD_NEXT, func_name, ver);
+ }
diff --git a/srcpkgs/llvm3.9/files/patches/lldb/fix-musl.patch b/srcpkgs/llvm3.9/files/patches/lldb/fix-musl.patch
new file mode 100644
index 00000000000..67b8df07495
--- /dev/null
+++ b/srcpkgs/llvm3.9/files/patches/lldb/fix-musl.patch
@@ -0,0 +1,41 @@
+From 13b33959b864e3697e8dad002577321de13f4cc9 Mon Sep 17 00:00:00 2001
+From: Andrea Brancaleoni <miwaxe@gmail.com>
+Date: Tue, 8 Sep 2015 23:00:56 +0200
+Subject: [PATCH] fix musl
+
+---
+ source/Core/ConnectionSharedMemory.cpp | 1 +
+ source/Host/common/FileSpec.cpp        | 1 +
+ source/Host/linux/Host.cpp             | 2 +-
+ source/Host/linux/HostThreadLinux.cpp  | 2 ++
+ source/Plugins/Process/Linux/Procfs.h  | 2 +-
+ 5 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/source/Host/common/FileSpec.cpp b/source/Host/common/FileSpec.cpp
+index ceb094b..a48620d 100644
+--- a/source/Host/common/FileSpec.cpp
++++ b/source/Host/common/FileSpec.cpp
+@@ -14,6 +14,7 @@
+ #include "lldb/Host/windows/windows.h"
+ #endif
+ #include <fcntl.h>
++#include <limits.h>	/* PATH_MAX */
+ #ifndef _MSC_VER
+ #include <libgen.h>
+ #endif
+diff --git a/source/Plugins/Process/Linux/Procfs.h b/source/Plugins/Process/Linux/Procfs.h
+index 1b383fb..4ebe390 100644
+--- a/source/Plugins/Process/Linux/Procfs.h
++++ b/source/Plugins/Process/Linux/Procfs.h
+@@ -12,7 +12,7 @@
+ 
+ #include <sys/ptrace.h>
+ 
+-#ifdef __ANDROID__
++#ifndef __GLIBC__
+ #if defined (__arm64__) || defined (__aarch64__)
+ typedef unsigned long elf_greg_t;
+ typedef elf_greg_t elf_gregset_t[(sizeof (struct user_pt_regs) / sizeof(elf_greg_t))];
+-- 
+2.5.1
+
diff --git a/srcpkgs/llvm3.9/files/patches/lldb/zzz-aarch64.patch b/srcpkgs/llvm3.9/files/patches/lldb/zzz-aarch64.patch
new file mode 100644
index 00000000000..a6979541c68
--- /dev/null
+++ b/srcpkgs/llvm3.9/files/patches/lldb/zzz-aarch64.patch
@@ -0,0 +1,17 @@
+--- lldb/source/Plugins/Process/Linux/Procfs.h.orig
++++ lldb/source/Plugins/Process/Linux/Procfs.h
+@@ -11,12 +11,11 @@
+ // sys/procfs.h on Android/Linux for all supported architectures.
+ 
+ #include <sys/ptrace.h>
++#include <asm/ptrace.h>
+ 
+ #ifndef __GLIBC__
+ #if defined (__arm64__) || defined (__aarch64__)
+-typedef unsigned long elf_greg_t;
+-typedef elf_greg_t elf_gregset_t[(sizeof (struct user_pt_regs) / sizeof(elf_greg_t))];
+-typedef struct user_fpsimd_state elf_fpregset_t;
++#include <sys/procfs.h>
+ #ifndef NT_FPREGSET
+     #define NT_FPREGSET NT_PRFPREG
+ #endif // NT_FPREGSET
diff --git a/srcpkgs/llvm3.9/files/patches/llvm/llvm-003-musl.patch b/srcpkgs/llvm3.9/files/patches/llvm/llvm-003-musl.patch
new file mode 100644
index 00000000000..8fafa570037
--- /dev/null
+++ b/srcpkgs/llvm3.9/files/patches/llvm/llvm-003-musl.patch
@@ -0,0 +1,83 @@
+From faca3fbd15d0c3108493c3c54cd93138e049ac43 Mon Sep 17 00:00:00 2001
+From: Andrea Brancaleoni <miwaxe@gmail.com>
+Date: Tue, 8 Sep 2015 22:03:02 +0200
+Subject: [PATCH 3/3] musl
+
+---
+ include/llvm/Analysis/TargetLibraryInfo.h | 9 +++++++++
+ lib/Analysis/TargetLibraryInfo.cpp        | 5 +++--
+ lib/Support/DynamicLibrary.cpp            | 2 +-
+ lib/Support/Unix/Signals.inc              | 6 +++---
+ utils/unittest/googletest/src/gtest.cc    | 1 +
+ 5 files changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/include/llvm/Analysis/TargetLibraryInfo.h b/include/llvm/Analysis/TargetLibraryInfo.h
+index e0a1ee3..465b65a 100644
+--- a/include/llvm/Analysis/TargetLibraryInfo.h
++++ b/include/llvm/Analysis/TargetLibraryInfo.h
+@@ -18,6 +18,15 @@
+ #include "llvm/IR/Module.h"
+ #include "llvm/Pass.h"
+ 
++#undef fopen64
++#undef fseeko64
++#undef fstat64
++#undef fstatvfs64
++#undef ftello64
++#undef lstat64
++#undef stat64
++#undef tmpfile64
++
+ namespace llvm {
+ /// VecDesc - Describes a possible vectorization of a function.
+ /// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
+diff --git a/lib/Analysis/TargetLibraryInfo.cpp b/lib/Analysis/TargetLibraryInfo.cpp
+index 635c50c..863f4a0 100644
+--- a/lib/Analysis/TargetLibraryInfo.cpp
++++ b/lib/Analysis/TargetLibraryInfo.cpp
+@@ -336,14 +336,15 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
+   }
+ 
+   // The following functions are available on at least Linux:
+-  if (!T.isOSLinux()) {
++  if (!T.isOSLinux())
++    TLI.setUnavailable(LibFunc::memalign);
++  if (1 /*!T.isGlibc()*/) {
+     TLI.setUnavailable(LibFunc::dunder_strdup);
+     TLI.setUnavailable(LibFunc::dunder_strtok_r);
+     TLI.setUnavailable(LibFunc::dunder_isoc99_scanf);
+     TLI.setUnavailable(LibFunc::dunder_isoc99_sscanf);
+     TLI.setUnavailable(LibFunc::under_IO_getc);
+     TLI.setUnavailable(LibFunc::under_IO_putc);
+-    TLI.setUnavailable(LibFunc::memalign);
+     TLI.setUnavailable(LibFunc::fopen64);
+     TLI.setUnavailable(LibFunc::fseeko64);
+     TLI.setUnavailable(LibFunc::fstat64);
+diff --git a/lib/Support/DynamicLibrary.cpp b/lib/Support/DynamicLibrary.cpp
+index 9a7aeb5..e21750d 100644
+--- a/lib/Support/DynamicLibrary.cpp
++++ b/lib/Support/DynamicLibrary.cpp
+@@ -138,7 +138,7 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
+ 
+ // This macro returns the address of a well-known, explicit symbol
+ #define EXPLICIT_SYMBOL(SYM) \
+-   if (!strcmp(symbolName, #SYM)) return &SYM
++   if (!strcmp(symbolName, #SYM)) return (void *) &SYM
+ 
+ // On linux we have a weird situation. The stderr/out/in symbols are both
+ // macros and global variables because of standards requirements. So, we
+diff --git a/utils/unittest/googletest/src/gtest.cc b/utils/unittest/googletest/src/gtest.cc
+index 5780764..1d548c1 100644
+--- a/utils/unittest/googletest/src/gtest.cc
++++ b/utils/unittest/googletest/src/gtest.cc
+@@ -120,6 +120,7 @@
+ 
+ #if GTEST_CAN_STREAM_RESULTS_
+ # include <arpa/inet.h>  // NOLINT
++# include <sys/socket.h>  // NOLINT
+ # include <netdb.h>  // NOLINT
+ #endif
+ 
+-- 
+2.5.1
+
diff --git a/srcpkgs/llvm3.9/files/patches/llvm/reverse-llvm-AMDGPU-Fix-an-interaction-between-WQM-and-polygon-stippling.patch b/srcpkgs/llvm3.9/files/patches/llvm/reverse-llvm-AMDGPU-Fix-an-interaction-between-WQM-and-polygon-stippling.patch
new file mode 100644
index 00000000000..f23b9168286
--- /dev/null
+++ b/srcpkgs/llvm3.9/files/patches/llvm/reverse-llvm-AMDGPU-Fix-an-interaction-between-WQM-and-polygon-stippling.patch
@@ -0,0 +1,140 @@
+From 25e2616626caafb896517e18cd8aa724fba2b200 Mon Sep 17 00:00:00 2001
+From: Tom Stellard <thomas.stellard@amd.com>
+Date: Tue, 29 Nov 2016 03:41:28 +0000
+Subject: [PATCH] Merging r280589:
+
+------------------------------------------------------------------------
+r280589 | nhaehnle | 2016-09-03 05:26:32 -0700 (Sat, 03 Sep 2016) | 19 lines
+
+AMDGPU: Fix an interaction between WQM and polygon stippling
+
+Summary:
+This fixes a rare bug in polygon stippling with non-monolithic pixel shaders.
+
+The underlying problem is as follows: the prolog part contains the polygon
+stippling sequence, i.e. a kill. The main part then enables WQM based on the
+_reduced_ exec mask, effectively undoing most of the polygon stippling.
+
+Since we cannot know whether polygon stippling will be used, the main part
+of a non-monolithic shader must always return to exact mode to fix this
+problem.
+
+Reviewers: arsenm, tstellarAMD, mareko
+
+Subscribers: arsenm, llvm-commits, kzhuravl
+
+Differential Revision: https://reviews.llvm.org/D23131
+
+------------------------------------------------------------------------
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_39@288105 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ lib/Target/AMDGPU/SIInstructions.td   |  1 +
+ lib/Target/AMDGPU/SIWholeQuadMode.cpp |  7 -----
+ test/CodeGen/AMDGPU/wqm.ll            | 49 ++++++++++++++++++++++++++++++++---
+ 3 files changed, 46 insertions(+), 11 deletions(-)
+
+diff --git a/lib/Target/AMDGPU/SIInstructions.td b/lib/Target/AMDGPU/SIInstructions.td
+index 18b7d5d..dde5f2f 100644
+--- a/lib/Target/AMDGPU/SIInstructions.td
++++ b/lib/Target/AMDGPU/SIInstructions.td
+@@ -2029,6 +2029,7 @@ def SI_RETURN : PseudoInstSI <
+   let hasSideEffects = 1;
+   let SALU = 1;
+   let hasNoSchedulingInfo = 1;
++  let DisableWQM = 1;
+ }
+ 
+ let Uses = [EXEC], Defs = [EXEC, VCC, M0],
+diff --git a/lib/Target/AMDGPU/SIWholeQuadMode.cpp b/lib/Target/AMDGPU/SIWholeQuadMode.cpp
+index b200c15..1534d58 100644
+--- a/lib/Target/AMDGPU/SIWholeQuadMode.cpp
++++ b/lib/Target/AMDGPU/SIWholeQuadMode.cpp
+@@ -219,13 +219,6 @@ char SIWholeQuadMode::scanInstructions(MachineFunction &MF,
+       markInstruction(MI, Flags, Worklist);
+       GlobalFlags |= Flags;
+     }
+-
+-    if (WQMOutputs && MBB.succ_empty()) {
+-      // This is a prolog shader. Make sure we go back to exact mode at the end.
+-      Blocks[&MBB].OutNeeds = StateExact;
+-      Worklist.push_back(&MBB);
+-      GlobalFlags |= StateExact;
+-    }
+   }
+ 
+   return GlobalFlags;
+diff --git a/test/CodeGen/AMDGPU/wqm.ll b/test/CodeGen/AMDGPU/wqm.ll
+index 809a7ba..41e4264 100644
+--- a/test/CodeGen/AMDGPU/wqm.ll
++++ b/test/CodeGen/AMDGPU/wqm.ll
+@@ -17,17 +17,18 @@ main_body:
+ ;CHECK-LABEL: {{^}}test2:
+ ;CHECK-NEXT: ; %main_body
+ ;CHECK-NEXT: s_wqm_b64 exec, exec
+-;CHECK: image_sample
+ ;CHECK-NOT: exec
+-;CHECK: _load_dword v0,
+-define amdgpu_ps float @test2(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, float addrspace(1)* inreg %ptr, <4 x i32> %c) {
++define amdgpu_ps void @test2(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, float addrspace(1)* inreg %ptr, <4 x i32> %c) {
+ main_body:
+   %c.1 = call <4 x float> @llvm.SI.image.sample.v4i32(<4 x i32> %c, <8 x i32> %rsrc, <4 x i32> %sampler, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
+   %c.2 = bitcast <4 x float> %c.1 to <4 x i32>
+   %c.3 = extractelement <4 x i32> %c.2, i32 0
+   %gep = getelementptr float, float addrspace(1)* %ptr, i32 %c.3
+   %data = load float, float addrspace(1)* %gep
+-  ret float %data
++
++  call void @llvm.SI.export(i32 15, i32 1, i32 1, i32 0, i32 1, float %data, float undef, float undef, float undef)
++
++  ret void
+ }
+ 
+ ; ... but disabled for stores (and, in this simple case, not re-enabled).
+@@ -414,6 +415,46 @@ entry:
+   ret void
+ }
+ 
++; Must return to exact at the end of a non-void returning shader,
++; otherwise the EXEC mask exported by the epilog will be wrong. This is true
++; even if the shader has no kills, because a kill could have happened in a
++; previous shader fragment.
++;
++; CHECK-LABEL: {{^}}test_nonvoid_return:
++; CHECK: s_mov_b64 [[LIVE:s\[[0-9]+:[0-9]+\]]], exec
++; CHECK: s_wqm_b64 exec, exec
++;
++; CHECK: s_and_b64 exec, exec, [[LIVE]]
++; CHECK-NOT: exec
++define amdgpu_ps <4 x float> @test_nonvoid_return() nounwind {
++  %tex = call <4 x float> @llvm.SI.image.sample.v4i32(<4 x i32> undef, <8 x i32> undef, <4 x i32> undef, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
++  %tex.i = bitcast <4 x float> %tex to <4 x i32>
++  %dtex = call <4 x float> @llvm.SI.image.sample.v4i32(<4 x i32> %tex.i, <8 x i32> undef, <4 x i32> undef, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
++  ret <4 x float> %dtex
++}
++
++; CHECK-LABEL: {{^}}test_nonvoid_return_unreachable:
++; CHECK: s_mov_b64 [[LIVE:s\[[0-9]+:[0-9]+\]]], exec
++; CHECK: s_wqm_b64 exec, exec
++;
++; CHECK: s_and_b64 exec, exec, [[LIVE]]
++; CHECK-NOT: exec
++define amdgpu_ps <4 x float> @test_nonvoid_return_unreachable(i32 inreg %c) nounwind {
++entry:
++  %tex = call <4 x float> @llvm.SI.image.sample.v4i32(<4 x i32> undef, <8 x i32> undef, <4 x i32> undef, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
++  %tex.i = bitcast <4 x float> %tex to <4 x i32>
++  %dtex = call <4 x float> @llvm.SI.image.sample.v4i32(<4 x i32> %tex.i, <8 x i32> undef, <4 x i32> undef, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
++
++  %cc = icmp sgt i32 %c, 0
++  br i1 %cc, label %if, label %else
++
++if:
++  store volatile <4 x float> %dtex, <4 x float>* undef
++  unreachable
++
++else:
++  ret <4 x float> %dtex
++}
+ 
+ declare void @llvm.amdgcn.image.store.v4i32(<4 x float>, <4 x i32>, <8 x i32>, i32, i1, i1, i1, i1) #1
+ declare void @llvm.amdgcn.buffer.store.f32(float, <4 x i32>, i32, i32, i1, i1) #1
diff --git a/srcpkgs/llvm3.9/template b/srcpkgs/llvm3.9/template
new file mode 100644
index 00000000000..86a14c13001
--- /dev/null
+++ b/srcpkgs/llvm3.9/template
@@ -0,0 +1,112 @@
+# Template file for 'llvm3.9'
+# Only a transitional package until Rust works with LLVM 4.0.
+pkgname=llvm3.9
+version=3.9.1
+revision=2
+wrksrc="llvm-${version}.src"
+lib32disabled=yes
+build_style=cmake
+configure_args="
+ -Wno-dev
+ -DCMAKE_BUILD_TYPE=Release
+ -DLLVM_BUILD_LLVM_DYLIB=ON
+ -DLLVM_LINK_LLVM_DYLIB=OFF
+ -DLLVM_DYLIB_EXPORT_ALL=ON
+ -DLLVM_ENABLE_RTTI=ON
+ -DLLVM_ENABLE_FFI=ON
+ -DLLVM_BUILD_TESTS=OFF
+ -DLLVM_BINUTILS_INCDIR=/usr/include
+ -DCMAKE_INSTALL_DO_STRIP=0"
+nodebug=yes  # while -DLLVM_LINK_LLVM_DYLIB=OFF
+short_desc="Low Level Virtual Machine (3.9.x series)"
+maintainer="Leah Neukirchen <leah@vuxu.org>"
+homepage="http://www.llvm.org"
+license="BSD"
+distfiles="http://www.llvm.org/releases/${version}/llvm-${version}.src.tar.xz"
+checksum=1fd90354b9cf19232e8f168faf2220e79be555df3aa743242700879e8fd329ee
+
+# XXX Investigate ocaml bindings.
+hostmakedepends="groff perl python zlib-devel libffi-devel swig"
+makedepends="python-devel zlib-devel libffi-devel libedit-devel libxml2-devel binutils-devel"
+depends="libllvm3.9"
+conflicts="llvm>=0"
+
+subpackages="libllvm3.9"
+
+post_extract() {
+	# patches
+	cd ${XBPS_BUILDDIR}/llvm-${version}.src
+	for i in ${FILESDIR}/patches/llvm/llvm-*.patch; do
+		msg_normal "Applying $i to llvm\n"
+		patch -sNp1 -i ${i}
+	done
+
+	# https://bugs.freedesktop.org/show_bug.cgi?id=99078
+	patch -RsNp1 -i ${FILESDIR}/patches/llvm/reverse-llvm-AMDGPU-Fix-an-interaction-between-WQM-and-polygon-stippling.patch
+
+	# Move compiler-rt files into the llvm source.
+	if [ -d ${XBPS_BUILDDIR}/compiler-rt-${version}.src ]; then
+		mv ${XBPS_BUILDDIR}/compiler-rt-${version}.src ${wrksrc}/projects/compiler-rt
+	fi
+}
+
+pre_configure() {
+	if [ "$CROSS_BUILD" ]; then
+		msg_normal "Building host tblgen\n"
+		mkdir -p build/HOST
+		cd build/HOST
+		CC="$BUILD_CC" CXX="$BUILD_CXX" CFLAGS="$BUILD_CFLAGS" \
+			CXXFLAGS="$BUILD_CXXFLAGS" LDFLAGS="$BUILD_LDFLAGS" \
+			cmake ../.. -DCMAKE_BUILD_TYPE=Release
+		make ${makejobs} -C utils/TableGen
+		make ${makejobs} -C tools/clang/utils/TableGen
+		configure_args+=" -DLLVM_TABLEGEN=${wrksrc}/build/HOST/bin/llvm-tblgen"
+		configure_args+=" -DCLANG_TABLEGEN=${wrksrc}/build/HOST/bin/clang-tblgen"
+		cd ../..
+	fi
+
+	case "$XBPS_TARGET_MACHINE" in
+		i686*) _arch="X86";;
+		x86_64*) _arch="X86";;
+		arm*) _arch="ARM";;
+		aarch64*) _arch="AArch64";;
+		mips*) _arch="Mips";;
+	esac
+	configure_args+=" -DLLVM_TARGET_ARCH=${_arch}"
+	configure_args+=" -DLLVM_DEFAULT_TARGET_TRIPLE=${XBPS_CROSS_TRIPLET:-$XBPS_TRIPLET}"
+}
+post_configure() {
+	# Don't leak CFLAGS into llvm-config.
+        sed -i -e "s|\(-specs=.*hardened-ld\)||g" -e "s|\(-specs=.*hardened-cc1\)||g" tools/llvm-config/BuildVariables.inc
+}
+
+do_install() {
+	vlicense LICENSE.TXT
+
+	cd build
+	cmake -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr -P cmake_install.cmake
+
+	# Fix permissions of static libs
+	chmod -x ${DESTDIR}/usr/lib/*.a
+
+	# Required for multilib.
+	if [ "$XBPS_TARGET_MACHINE" = "x86_64" ]; then
+		for _header in llvm-config; do
+			mv ${DESTDIR}/usr/include/llvm/Config/${_header}{,-64}.h
+			vinstall ${FILESDIR}/llvm-Config-${_header}.h 644 \
+				usr/include/llvm/Config ${_header}.h
+		done
+	fi
+
+	# Remove llvm-config-host in cross builds.
+	if [ "$CROSS_BUILD" ]; then
+		rm -f ${DESTDIR}/usr/bin/llvm-config-host
+	fi
+}
+
+libllvm3.9_package() {
+	short_desc+=" - runtime library"
+	pkg_install() {
+		vmove "usr/lib/libLLVM-*.so*"
+	}
+}
diff --git a/srcpkgs/llvm3.9/update b/srcpkgs/llvm3.9/update
new file mode 100644
index 00000000000..49e4f464a96
--- /dev/null
+++ b/srcpkgs/llvm3.9/update
@@ -0,0 +1 @@
+site="http://www.llvm.org/releases/download.html"