Blob Blame History Raw
From b932e8a10ee82b66bacef6cab4599a2858ac10ac Mon Sep 17 00:00:00 2001
From: Ville Korhonen <ville.t.korhonen@tut.fi>
Date: Tue, 6 Sep 2016 17:31:22 +0300
Subject: [PATCH 3/6] LLVM 3.9 fixes - Clang now uses function metadata istead
 of module metadata for presenting OpenCL kernel info   - Now there are two
 versions of "pocl_llvm_get_kernel_arg_metadata()" for llvm 3.9 and <3.9   -
 SPIR examples still use module meta

- Something changed in function mangling
  - Volatile is has changed place in the mangled name
  - New svm_atomics_x86_64_llvm3_9.ll to address this issue

- Clang likes to put string literals to the constant AS
  - a bit questionable fix in kernel/printf.c

- Nice "__builtin_astype()" function for casting opaque built in types to actual implementation types
---
 cmake/LLVM.cmake                         |    8 +-
 configure.ac                             |   90 +-
 include/_kernel_c.h                      |   24 +-
 lib/CL/pocl_llvm_api.cc                  |  270 +-
 lib/kernel/get_image_depth.cl            |   10 +-
 lib/kernel/get_image_dim.cl              |   15 +-
 lib/kernel/get_image_height.cl           |   10 +-
 lib/kernel/get_image_width.cl            |   10 +-
 lib/kernel/host/CMakeLists.txt           |   10 +-
 lib/kernel/host/Makefile.am              |    6 +
 lib/kernel/printf.c                      |   47 +-
 lib/kernel/read_image.cl                 |    7 +-
 lib/kernel/svm_atomics_x86_64_llvm3_9.ll | 8075 ++++++++++++++++++++++++++++++
 lib/kernel/write_image.cl                |   17 +-
 lib/llvmopencl/AutomaticLocals.cc        |   12 +-
 lib/llvmopencl/BarrierTailReplication.cc |    4 +-
 lib/llvmopencl/LLVMUtils.h               |    4 +-
 lib/llvmopencl/Workgroup.cc              |   11 +-
 tests/kernel/test_bitselect.cl           |    2 +-
 19 files changed, 8506 insertions(+), 126 deletions(-)
 create mode 100644 lib/kernel/svm_atomics_x86_64_llvm3_9.ll

diff --git a/cmake/LLVM.cmake b/cmake/LLVM.cmake
index 1ab1a01..57a6230 100644
--- a/cmake/LLVM.cmake
+++ b/cmake/LLVM.cmake
@@ -38,6 +38,7 @@ else()
     NAMES "llvm-config"
       "llvm-config-mp-3.8" "llvm-config-3.8" "llvm-config38"
       "llvm-config-mp-3.7" "llvm-config-3.7" "llvm-config37"
+      "llvm-config-mp-3.9" "llvm-config-3.9" "llvm-config39"
     DOC "llvm-config executable")
 endif()
 
@@ -147,10 +148,15 @@ if(LLVM_VERSION MATCHES "3[.]([0-9]+)")
   set(LLVM_MAJOR 3)
   string(STRIP "${CMAKE_MATCH_1}" LLVM_MINOR)
   message(STATUS "Minor llvm version: ${LLVM_MINOR}")
-  if(LLVM_MINOR STREQUAL "7")
+  if(LLVM_MINOR STREQUAL "6")
+    set(LLVM_3_6 1)
+    set(LLVM_OLDER_THAN_3_9 1)
+  elseif(LLVM_MINOR STREQUAL "7")
     set(LLVM_3_7 1)
+    set(LLVM_OLDER_THAN_3_9 1)
   elseif(LLVM_MINOR STREQUAL "8")
     set(LLVM_3_8 1)
+    set(LLVM_OLDER_THAN_3_9 1)
   elseif(LLVM_MINOR STREQUAL "9")
     set(LLVM_3_9 1)
   else()
diff --git a/configure.ac b/configure.ac
index 13ffe7d..4f98133 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,37 +78,67 @@ LD_FLAGS_BIN=""
 ###################################################
 # LLVM configuration
 #
-AC_ARG_VAR([LLVM_CONFIG], [Program used to retrieve LLVM options and binaries])
-AC_PATH_PROGS([LLVM_CONFIG], [llvm-config llvm-config-mp-3.7 llvm-config-3.7 llvm-config37 llvm-config-mp-3.6 llvm-config-3.6 llvm-config36])
-test -z "$LLVM_CONFIG" && AC_MSG_FAILURE([no llvm-config found in \$PATH])
-
-LLVM_VERSION=`$LLVM_CONFIG --version`
-LLVM_BINDIR=`$LLVM_CONFIG --bindir`
-LLVM_LIBDIR=`$LLVM_CONFIG --libdir`
-LLVM_LDFLAGS=`$LLVM_CONFIG --ldflags`
-
-AC_SUBST([LLVM_VERSION], [$LLVM_VERSION])
-AC_DEFINE_UNQUOTED([LLVM_VERSION], ["$LLVM_VERSION"], "LLVM version as a string.")
-
-case "$LLVM_VERSION" in
-     3.7*)
-     AC_DEFINE([LLVM_3_7], [], "Using LLVM 3.7")
-     LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVM_CONFIG --system-libs`"
-   ;;
-     3.8*)
-     AC_DEFINE([LLVM_3_8], [], "Using LLVM 3.8")
-     LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVM_CONFIG --system-libs`"
-   ;;
-     *)
-   AC_MSG_ERROR(
-   [
-Unsupported LLVM version. Please use LLVM version 3.7 or 3.8.
-   ])
-   LLVM_VERSION=
-   ;;
-esac
+AC_ARG_ENABLE([ocs],
+              [AS_HELP_STRING([--enable-ocs], [Build pocl with online compiler support (default yes)])],
+              [ocs="$enableval"],
+              [ocs="yes"])
+AC_ARG_VAR([HOST_DEVICE_BUILD_HASH], [Program used to retrieve LLVM options and binaries])
+
+OCS_available=no
+if test x"$ocs" != x"no"; then :
+  
+  OCS_available=yes
+  AC_DEFINE([OCS_AVAILABLE], [1], [Defined to 1 if compiling with online compiler support])
+
+  AC_ARG_VAR([LLVM_CONFIG], [Program used to retrieve LLVM options and binaries])
+  AC_PATH_PROGS([LLVM_CONFIG], [llvm-config llvm-config-mp-3.9 llvm-config-3.9 llvm-config39 llvm-config-mp-3.8 llvm-config-3.8 llvm-config38 llvm-config-mp-3.7 llvm-config-3.7 llvm-config37])
+  test -z "$LLVM_CONFIG" && AC_MSG_FAILURE([no llvm-config found in \$PATH])
+
+  LLVM_VERSION=`$LLVM_CONFIG --version`
+  LLVM_BINDIR=`$LLVM_CONFIG --bindir`
+  LLVM_LIBDIR=`$LLVM_CONFIG --libdir`
+  LLVM_LDFLAGS=`$LLVM_CONFIG --ldflags`
+
+  AC_SUBST([LLVM_VERSION], [$LLVM_VERSION])
+  AC_DEFINE_UNQUOTED([LLVM_VERSION], ["$LLVM_VERSION"], "LLVM version as a string.")
+
+  LLVM_3_6=false
+  LLVM_3_9=false
+  LLVM_OLDER_THAN_3_9=true
+
+  case "$LLVM_VERSION" in
+       3.6*)
+       AC_DEFINE([LLVM_3_6], [], "Using LLVM 3.6")
+       LLVM_3_6=true
+       LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVM_CONFIG --system-libs`"
+     ;;
+       3.7*)
+       AC_DEFINE([LLVM_3_7], [], "Using LLVM 3.7")
+       LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVM_CONFIG --system-libs`"
+     ;;
+       3.8*)
+       AC_DEFINE([LLVM_3_8], [], "Using LLVM 3.8")
+       LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVM_CONFIG --system-libs`"
+     ;;
+       3.9*)
+       AC_DEFINE([LLVM_3_9], [], "Using LLVM 3.9")
+       LLVM_3_9=true
+       LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVM_CONFIG --system-libs`"
+     ;;
+       *)
+     AC_MSG_ERROR(
+     [
+  Unsupported LLVM version. Please use LLVM version 3.7, 3.8 or 3.9.
+     ])
+     LLVM_VERSION=
+     ;;
+  esac
 
-AC_SUBST([LLVM_LDFLAGS], [$LLVM_LDFLAGS], [llvm-config returned ldflags])
+  AM_CONDITIONAL([LLVM_3_6], [test "x$LLVM_3_6" = "xtrue"])
+  AM_CONDITIONAL([LLVM_3_9], [test "x$LLVM_3_9" = "xtrue"])
+  AM_CONDITIONAL([LLVM_OLDER_THAN_3_9], [test "x$LLVM_3_9" = "xfalse"])
+  AC_SUBST([LLVM_LDFLAGS], [$LLVM_LDFLAGS], [llvm-config returned ldflags])
+fi
 
 # When building with API linking, clang is always linked statically, so user might want to link llvm static to libpocl too
 # or risk causing version mismatches. Also useful when other platform libraries use LLVM too, see issue #46.
diff --git a/include/_kernel_c.h b/include/_kernel_c.h
index 1d3d1b8..5aa3c27 100644
--- a/include/_kernel_c.h
+++ b/include/_kernel_c.h
@@ -69,6 +69,10 @@
 #  define _CL_UNAVAILABLE
 #endif
 
+#if !((__clang_major__ == 3) && (__clang_minor__ == 9)) && !(__clang_major__ == 4)
+#define CLANG_OLDER_THAN_3_9
+#endif
+
 typedef char char2  __attribute__((__ext_vector_type__(2)));
 typedef char char3  __attribute__((__ext_vector_type__(3)));
 typedef char char4  __attribute__((__ext_vector_type__(4)));
@@ -105,7 +109,7 @@ typedef uint uint4  __attribute__((__ext_vector_type__(4)));
 typedef uint uint8  __attribute__((__ext_vector_type__(8)));
 typedef uint uint16 __attribute__((__ext_vector_type__(16)));
 
-#if defined(__CBUILD__) && defined(cl_khr_fp16)
+#if defined(__CBUILD__) && defined(cl_khr_fp16) && defined(CLANG_OLDER_THAN_3_9)
 /* NOTE: the Clang's __fp16 does not work robustly in C mode, 
    it might produce invalid code at least with half vectors.
    Using the native 'half' type in OpenCL C mode works better. */
@@ -158,7 +162,7 @@ typedef ulong ulong16 __attribute__((__ext_vector_type__(16)));
    the default builtins we use C functions which require
    the typedefs to the actual underlying types.
 */
-#if defined(__CBUILD__)
+#if defined(__CBUILD__) && defined(CLANG_OLDER_THAN_3_9)
 typedef int sampler_t;
 
 /* Since some built-ins have different return types
@@ -169,6 +173,7 @@ typedef int sampler_t;
  * dev_image_t. The structs are not anonymous to allow identification
  * by name.
  */
+
 typedef struct _pocl_image2d_t { dev_image_t base; }* image2d_t;
 typedef struct _pocl_image3d_t { dev_image_t base; }* image3d_t;
 typedef struct _pocl_image1d_t { dev_image_t base; }* image1d_t;
@@ -177,6 +182,13 @@ typedef struct _pocl_image2d_array_t { dev_image_t base; }* image2d_array_t;
 typedef struct _pocl_image1d_array_t { dev_image_t base; }* image1d_array_t;
 #endif
 
+// 3.9 needs access qualifier
+// TODO: rw images
+#ifdef CLANG_OLDER_THAN_3_9
+#define IMG_WRITE_AQ
+#else
+#define IMG_WRITE_AQ __write_only
+#endif
 
 float4 _CL_OVERLOADABLE read_imagef (image2d_t image, sampler_t sampler,
                                      int2 coord);
@@ -203,16 +215,16 @@ int4 _CL_OVERLOADABLE read_imagei (image2d_t image, sampler_t sampler,
                                    int2 coord);
 
 
-void _CL_OVERLOADABLE write_imagei (image2d_t image, int2 coord, int4 color);
+void _CL_OVERLOADABLE write_imagei (IMG_WRITE_AQ image2d_t image, int2 coord, int4 color);
 
-void _CL_OVERLOADABLE write_imageui (image2d_t image, int2 coord, uint4 color);
+void _CL_OVERLOADABLE write_imageui (IMG_WRITE_AQ image2d_t image, int2 coord, uint4 color);
 
 
 
-void _CL_OVERLOADABLE write_imagef (image2d_t image, int2 coord,
+void _CL_OVERLOADABLE write_imagef (IMG_WRITE_AQ image2d_t image, int2 coord,
                                     float4 color);
 
-void _CL_OVERLOADABLE write_imagef (image3d_t image, int4 coord,
+void _CL_OVERLOADABLE write_imagef (IMG_WRITE_AQ image3d_t image, int4 coord,
                                     float4 color);
 
 /* not implemented 
diff --git a/lib/CL/pocl_llvm_api.cc b/lib/CL/pocl_llvm_api.cc
index ac4ec4b..7626993 100644
--- a/lib/CL/pocl_llvm_api.cc
+++ b/lib/CL/pocl_llvm_api.cc
@@ -365,8 +365,16 @@ int pocl_llvm_build_program(cl_program program,
     }
   
   LangOptions *la = pocl_build.getLangOpts();
+  PreprocessorOptions &po = pocl_build.getPreprocessorOpts();
+
+#ifdef LLVM_OLDER_THAN_3_9
   pocl_build.setLangDefaults
     (*la, clang::IK_OpenCL, clang::LangStandard::lang_opencl12);
+#else
+  llvm::Triple triple(device->llvm_target_triplet);
+  pocl_build.setLangDefaults
+    (*la, clang::IK_OpenCL, triple, po, clang::LangStandard::lang_opencl12);
+#endif
   
   // LLVM 3.3 and older do not set that char is signed which is
   // defined by the OpenCL C specs (but not by C specs).
@@ -380,8 +388,6 @@ int pocl_llvm_build_program(cl_program program,
   la->NoBuiltin = true;  // -fno-builtin
   la->AsmBlocks = true;  // -fasm (?)
 
-  PreprocessorOptions &po = pocl_build.getPreprocessorOpts();
-
   std::string kernelh;
   if (pocl_get_bool_option("POCL_BUILDING", 0))
     { 
@@ -515,24 +521,24 @@ ERROR_BUILDLOG:
 
 }
 
-int pocl_llvm_get_kernel_arg_metadata(const char* kernel_name,
-                                      llvm::Module *input,
-                                      cl_kernel kernel)
+// The old way of getting kernel metadata from "opencl.kernels" module meta.
+// LLVM < 3.9 and SPIR
+static int pocl_get_kernel_arg_module_metadata(const char* kernel_name,
+                                               llvm::Module *input,
+                                               cl_kernel kernel)
 {
-
   // find the right kernel in "opencl.kernels" metadata
   llvm::NamedMDNode *opencl_kernels = input->getNamedMetadata("opencl.kernels");
   llvm::MDNode *kernel_metadata = NULL;
 
-  // Not sure what to do in this case
-  if (!opencl_kernels || opencl_kernels->getNumOperands() == 0) return -1;
+  assert(opencl_kernels && opencl_kernels->getNumOperands());
 
   for (unsigned i = 0, e = opencl_kernels->getNumOperands(); i != e; ++i) {
     llvm::MDNode *kernel_iter = opencl_kernels->getOperand(i);
 
-    llvm::Function *kernel_prototype = 
-      llvm::cast<llvm::Function>(
-        dyn_cast<llvm::ValueAsMetadata>(kernel_iter->getOperand(0))->getValue());
+    llvm::Value *meta =
+      dyn_cast<llvm::ValueAsMetadata>(kernel_iter->getOperand(0))->getValue();
+    llvm::Function *kernel_prototype = llvm::cast<llvm::Function>(meta);
     std::string name = kernel_prototype->getName().str();
     if (name == kernel_name) {
       kernel_metadata = kernel_iter;
@@ -653,6 +659,177 @@ int pocl_llvm_get_kernel_arg_metadata(const char* kernel_name,
   return 0;
 }
 
+// Clang 3.9 uses function metadata instead of module metadata for presenting
+// OpenCL kernel information.
+static int pocl_get_kernel_arg_function_metadata(const char* kernel_name,
+                                                 llvm::Module *input,
+                                                 cl_kernel kernel)
+{
+  llvm::Function* Kernel = NULL;
+  int bitcode_is_spir = input->getTargetTriple().find("spir") == 0;
+
+  // SPIR still uses "opencl.kernels" meta
+  if(bitcode_is_spir)
+    return pocl_get_kernel_arg_module_metadata(kernel_name, input, kernel);
+
+  for (llvm::Module::iterator i = input->begin(), e = input->end();
+       i != e; ++i) {
+    if (i->getMetadata("kernel_arg_access_qual")
+        && i->getName() == kernel_name)
+      {
+        Kernel = &*i;
+        break;
+      }
+  }
+  assert(Kernel);
+  kernel->has_arg_metadata = 0;
+
+  llvm::MDNode *meta_node;
+  llvm::Value *meta_arg_value = NULL;
+  struct pocl_argument_info* current_arg = NULL;
+
+  // kernel_arg_addr_space
+  meta_node = Kernel->getMetadata("kernel_arg_addr_space");
+  unsigned arg_num = meta_node->getNumOperands();
+#ifndef NDEBUG
+  int has_meta_for_every_arg = (arg_num == kernel->num_args);
+#endif
+  for (unsigned j = 0; j < arg_num; ++j) {
+    assert(has_meta_for_every_arg && "kernel_arg_addr_space meta incomplete");
+
+    current_arg = &kernel->arg_info[j];
+    kernel->has_arg_metadata |= POCL_HAS_KERNEL_ARG_ADDRESS_QUALIFIER;
+    //std::cout << "is ConstantInt /  kernel_arg_addr_space" << std::endl;
+     meta_arg_value =
+          dyn_cast<ConstantAsMetadata>(meta_node->getOperand(j))->getValue();
+    llvm::ConstantInt *m = llvm::cast<ConstantInt>(meta_arg_value);
+    uint64_t val = m->getLimitedValue(UINT_MAX);
+    //std::cout << "with value: " << val << std::endl;
+    if (bitcode_is_spir) {
+      switch(val) {
+      case 0:
+        current_arg->address_qualifier = CL_KERNEL_ARG_ADDRESS_PRIVATE; break;
+      case 1:
+        current_arg->address_qualifier = CL_KERNEL_ARG_ADDRESS_GLOBAL; break;
+      case 3:
+        current_arg->address_qualifier = CL_KERNEL_ARG_ADDRESS_LOCAL; break;
+      case 2:
+        current_arg->address_qualifier = CL_KERNEL_ARG_ADDRESS_CONSTANT; break;
+      }
+    } else {
+      switch(val) {
+      case POCL_ADDRESS_SPACE_PRIVATE:
+        current_arg->address_qualifier = CL_KERNEL_ARG_ADDRESS_PRIVATE; break;
+      case POCL_ADDRESS_SPACE_GLOBAL:
+        current_arg->address_qualifier = CL_KERNEL_ARG_ADDRESS_GLOBAL; break;
+      case POCL_ADDRESS_SPACE_LOCAL:
+        current_arg->address_qualifier = CL_KERNEL_ARG_ADDRESS_LOCAL; break;
+      case POCL_ADDRESS_SPACE_CONSTANT:
+        current_arg->address_qualifier = CL_KERNEL_ARG_ADDRESS_CONSTANT; break;
+      case POCL_ADDRESS_SPACE_GENERIC:
+        current_arg->address_qualifier = CL_KERNEL_ARG_ADDRESS_PRIVATE; break;
+      }
+    }
+  }
+
+  // kernel_arg_access_qual
+  meta_node = Kernel->getMetadata("kernel_arg_access_qual");
+  arg_num = meta_node->getNumOperands();
+#ifndef NDEBUG
+  has_meta_for_every_arg = (arg_num == kernel->num_args);
+#endif
+  assert(has_meta_for_every_arg && "kernel_arg_access_qual meta incomplete");
+
+  for (unsigned j= 0; j < meta_node->getNumOperands(); ++j) {
+    current_arg = &kernel->arg_info[j];
+    //std::cout << "is MDString" << std::endl;
+    llvm::MDString *m = llvm::cast<MDString>(meta_node->getOperand(j));
+    std::string val = m->getString().str();
+    //std::cout << "with value: " << val << std::endl;
+    assert(has_meta_for_every_arg && "kernel_arg_access_qual meta incomplete");
+    kernel->has_arg_metadata |= POCL_HAS_KERNEL_ARG_ACCESS_QUALIFIER;
+    if (val == "read_write")
+      current_arg->access_qualifier = CL_KERNEL_ARG_ACCESS_READ_WRITE;
+    else if (val == "read_only")
+      current_arg->access_qualifier = CL_KERNEL_ARG_ACCESS_READ_ONLY;
+    else if (val == "write_only")
+      current_arg->access_qualifier = CL_KERNEL_ARG_ACCESS_WRITE_ONLY;
+    else if (val == "none")
+      current_arg->access_qualifier = CL_KERNEL_ARG_ACCESS_NONE;
+    else
+      std::cout << "UNKNOWN kernel_arg_access_qual value: " << val << std::endl;
+  }
+
+  // kernel_arg_type
+  meta_node = Kernel->getMetadata("kernel_arg_type");
+  arg_num = meta_node->getNumOperands();
+#ifndef NDEBUG
+  has_meta_for_every_arg = (arg_num == kernel->num_args);
+#endif
+  assert(has_meta_for_every_arg && "kernel_arg_type meta incomplete");
+
+  for (unsigned j= 0; j < meta_node->getNumOperands(); ++j) {
+    llvm::MDString *m = llvm::cast<MDString>(meta_node->getOperand(j));
+    std::string val = m->getString().str();
+
+    current_arg = &kernel->arg_info[j];
+    kernel->has_arg_metadata |= POCL_HAS_KERNEL_ARG_TYPE_NAME;
+    current_arg->type_name = new char[val.size() + 1];
+    std::strcpy(current_arg->type_name, val.c_str());
+  }
+
+  // kernel_arg_base_type
+  meta_node = Kernel->getMetadata("kernel_arg_base type");
+  arg_num = meta_node->getNumOperands();
+  for (unsigned j= 0; j < meta_node->getNumOperands(); ++j) {
+    // may or may not be present even in SPIR
+    // apparently there is no use for this meta atm.
+  }
+
+  // kernel_arg_type_qual
+  meta_node = Kernel->getMetadata("kernel_arg_type_qual");
+  arg_num = meta_node->getNumOperands();
+#ifndef NDEBUG
+  has_meta_for_every_arg = (arg_num == kernel->num_args);
+#endif
+  assert(has_meta_for_every_arg && "kernel_arg_type_qual meta incomplete");
+  for (unsigned j= 0; j < meta_node->getNumOperands(); ++j) {
+    llvm::MDString *m = llvm::cast<MDString>(meta_node->getOperand(j));
+    std::string val = m->getString().str();
+
+    current_arg = &kernel->arg_info[j];
+    assert(has_meta_for_every_arg && "kernel_arg_type_qual meta incomplete");
+    kernel->has_arg_metadata |= POCL_HAS_KERNEL_ARG_TYPE_QUALIFIER;
+    current_arg->type_qualifier = 0;
+    if (val.find("const") != std::string::npos)
+      current_arg->type_qualifier |= CL_KERNEL_ARG_TYPE_CONST;
+    if (val.find("restrict") != std::string::npos)
+      current_arg->type_qualifier |= CL_KERNEL_ARG_TYPE_RESTRICT;
+    if (val.find("volatile") != std::string::npos)
+      current_arg->type_qualifier |= CL_KERNEL_ARG_TYPE_VOLATILE;
+  }
+
+  //kernel_arg_name
+  meta_node = Kernel->getMetadata("kernel_arg_name");
+  arg_num = meta_node->getNumOperands();
+#ifndef NDEBUG
+  has_meta_for_every_arg = (arg_num == kernel->num_args);
+#endif
+  assert(has_meta_for_every_arg && "kernel_arg_name meta incomplete");
+  for (unsigned j= 0; j < meta_node->getNumOperands(); ++j) {
+    llvm::MDString *m = llvm::cast<MDString>(meta_node->getOperand(j));
+    std::string val = m->getString().str();
+
+    current_arg = &kernel->arg_info[j];
+    kernel->has_arg_metadata |= POCL_HAS_KERNEL_ARG_NAME;
+    current_arg->name = new char[val.size() + 1];
+    std::strcpy(current_arg->name, val.c_str());
+  }
+
+  return 0;
+}
+
+
 int pocl_llvm_get_kernel_metadata(cl_program program, 
                                   cl_kernel kernel,
                                   int device_i,     
@@ -842,10 +1019,18 @@ int pocl_llvm_get_kernel_metadata(cl_program program,
                               content.str().size());
 #endif
 
-  if (pocl_llvm_get_kernel_arg_metadata(kernel_name, input, kernel)) {
+#if defined(LLVM_OLDER_THAN_3_9)
+  if (pocl_get_kernel_arg_module_metadata(kernel_name, input, kernel)) {
+    *errcode = CL_INVALID_KERNEL;
+    return 1;
+  };
+#else
+  if (pocl_get_kernel_arg_function_metadata(kernel_name, input, kernel)) {
     *errcode = CL_INVALID_KERNEL;
     return 1;
   };
+#endif
+
 
   *errcode = CL_SUCCESS;
   return 0;
@@ -1533,8 +1718,9 @@ void pocl_llvm_update_binaries (cl_program program) {
 /* This is the implementation of the public pocl_llvm_get_kernel_count(),
  * and is used internally also by pocl_llvm_get_kernel_names to
  */
-unsigned
-pocl_llvm_get_kernel_count(cl_program program, llvm::NamedMDNode **md_ret)
+static unsigned
+pocl_llvm_get_kernel_count(cl_program program, char **knames,
+                           unsigned max_num_krn)
 {
   llvm::MutexGuard lockHolder(kernelCompilerLock);
   InitializeLLVM();
@@ -1542,38 +1728,50 @@ pocl_llvm_get_kernel_count(cl_program program, llvm::NamedMDNode **md_ret)
   // TODO: is it safe to assume every device (i.e. the index 0 here)
   // has the same set of programs & kernels?
   llvm::Module *mod = (llvm::Module *) program->llvm_irs[0];
-  llvm::NamedMDNode *md = mod->getNamedMetadata("opencl.kernels");
 
-  if (md_ret)
-    *md_ret = md;
-
-  if (md == NULL)
-    return 0;
-
-  return md->getNumOperands();
+  llvm::NamedMDNode *md = mod->getNamedMetadata("opencl.kernels");
+  if (md) {
+
+    if (knames) {
+      for (unsigned i=0; i<max_num_krn; i++) {
+        assert( md->getOperand(i)->getOperand(0) != NULL);
+        llvm::ValueAsMetadata *value =
+          dyn_cast<llvm::ValueAsMetadata>(md->getOperand(i)->getOperand(0));
+        llvm::Function *k = cast<Function>(value->getValue());
+        knames[i] = strdup(k->getName().data());
+      }
+    }
+    return md->getNumOperands();
+  }
+  // LLVM 3.9 does not use opencl.kernels meta, but kernel_arg_* function meta
+  else {
+    unsigned kernel_count = 0;
+    for (llvm::Module::iterator i = mod->begin(), e = mod->end();
+           i != e; ++i) {
+      if (i->getMetadata("kernel_arg_access_qual")) {
+        if (knames && kernel_count < max_num_krn) {
+          knames[kernel_count] = strdup(i->getName().str().c_str());
+        }
+        ++kernel_count;
+      }
+    }
+    return kernel_count;
+  }
 }
 
 unsigned
 pocl_llvm_get_kernel_count(cl_program program)
 {
-  return pocl_llvm_get_kernel_count(program, NULL);
+  return pocl_llvm_get_kernel_count(program, NULL, 0);
 }
 
 unsigned
-pocl_llvm_get_kernel_names( cl_program program, const char **knames, unsigned max_num_krn )
+pocl_llvm_get_kernel_names(cl_program program, char **knames,
+                           unsigned max_num_krn)
 {
-  llvm::NamedMDNode *md;
-  unsigned i, n = pocl_llvm_get_kernel_count(program, &md);
-
-  for (i=0; i<n; i++) {
-    assert( md->getOperand(i)->getOperand(0) != NULL);
-    llvm::Function *k = 
-      cast<Function>(
-        dyn_cast<llvm::ValueAsMetadata>(md->getOperand(i)->getOperand(0))->getValue());
-    if (i < max_num_krn)
-      knames[i]= k->getName().data();
-  }
-  return i;
+  unsigned n = pocl_llvm_get_kernel_count(program, knames, max_num_krn);
+
+  return n;
 }
 
 /* Run LLVM codegen on input file (parallel-optimized).
diff --git a/lib/kernel/get_image_depth.cl b/lib/kernel/get_image_depth.cl
index 365f9fb..62f1977 100644
--- a/lib/kernel/get_image_depth.cl
+++ b/lib/kernel/get_image_depth.cl
@@ -33,10 +33,12 @@
 #define ADDRESS_SPACE
 #endif
 
-#define IMPLEMENT_GET_IMAGE_DEPTH(__IMGTYPE__)              \
-  int _CL_OVERLOADABLE get_image_depth(__IMGTYPE__ image){  \
-    return (*(ADDRESS_SPACE dev_image_t**)&image)->depth;   \
-  }                                                         \
+#define IMPLEMENT_GET_IMAGE_DEPTH(__IMGTYPE__)                \
+  int _CL_OVERLOADABLE get_image_depth(__IMGTYPE__ image){    \
+    ADDRESS_SPACE dev_image_t* ptr =                          \
+      __builtin_astype(image, ADDRESS_SPACE dev_image_t*);    \
+    return ptr->depth;                                       \
+  }                                                           \
 
 IMPLEMENT_GET_IMAGE_DEPTH(image1d_t)
 IMPLEMENT_GET_IMAGE_DEPTH(image2d_t)
diff --git a/lib/kernel/get_image_dim.cl b/lib/kernel/get_image_dim.cl
index 2648afb..9e5ae1e 100644
--- a/lib/kernel/get_image_dim.cl
+++ b/lib/kernel/get_image_dim.cl
@@ -36,18 +36,21 @@
 
 int2 _CL_OVERLOADABLE get_image_dim(image2d_t image)
 {
-  ADDRESS_SPACE dev_image_t* img = *(ADDRESS_SPACE dev_image_t**)&image;
-  return (int2)(img->width, img->height);
+  ADDRESS_SPACE dev_image_t* img =
+    __builtin_astype(image, ADDRESS_SPACE dev_image_t*);
+  return (int2)(img->width, img->height);
 }
 
 int2 _CL_OVERLOADABLE get_image_dim(image2d_array_t image)
 {
-  ADDRESS_SPACE dev_image_t* img = *(ADDRESS_SPACE dev_image_t**)&image;
-  return (int2)(img->width, img->height);
+  ADDRESS_SPACE dev_image_t* img =
+    __builtin_astype (image, ADDRESS_SPACE dev_image_t*);
+  return (int2)(img->width, img->height);
 }
 
 int4 _CL_OVERLOADABLE get_image_dim(image3d_t image)
 {
-  ADDRESS_SPACE dev_image_t* img = *(ADDRESS_SPACE dev_image_t**)&image;
-  return (int4)(img->width, img->height, img->depth, 0);
+  ADDRESS_SPACE dev_image_t* img =
+    __builtin_astype (image, ADDRESS_SPACE dev_image_t*);
+  return (int4)(img->width, img->height, img->depth, 0);
 }
diff --git a/lib/kernel/get_image_height.cl b/lib/kernel/get_image_height.cl
index da519ae..4d8e5a3 100644
--- a/lib/kernel/get_image_height.cl
+++ b/lib/kernel/get_image_height.cl
@@ -33,10 +33,12 @@
 #define ADDRESS_SPACE
 #endif
 
-#define IMPLEMENT_GET_IMAGE_HEIGHT(__IMGTYPE__)                   \
-  int _CL_OVERLOADABLE get_image_height(__IMGTYPE__ image){       \
-    return (*(ADDRESS_SPACE dev_image_t**)&image)->height;               \
-  }                                                               \
+#define IMPLEMENT_GET_IMAGE_HEIGHT(__IMGTYPE__)                              \
+  int _CL_OVERLOADABLE get_image_height(__IMGTYPE__ image){                  \
+    ADDRESS_SPACE dev_image_t* ptr =                                         \
+      __builtin_astype(image, ADDRESS_SPACE dev_image_t*);                   \
+    return ptr->height;                                                     \
+  }                                                                          \
 
 
 IMPLEMENT_GET_IMAGE_HEIGHT(image1d_t)
diff --git a/lib/kernel/get_image_width.cl b/lib/kernel/get_image_width.cl
index f68c2de..0a8b47c 100644
--- a/lib/kernel/get_image_width.cl
+++ b/lib/kernel/get_image_width.cl
@@ -33,10 +33,12 @@
 #define ADDRESS_SPACE
 #endif
 
-#define IMPLEMENT_GET_IMAGE_WIDTH(__IMGTYPE__)               \
-  int _CL_OVERLOADABLE get_image_width(__IMGTYPE__ image){   \
-    return (*(ADDRESS_SPACE dev_image_t**)&image)->width;           \
-  }                                                          \
+#define IMPLEMENT_GET_IMAGE_WIDTH(__IMGTYPE__)                  \
+  int _CL_OVERLOADABLE get_image_width(__IMGTYPE__ image){      \
+    ADDRESS_SPACE dev_image_t* ptr =                            \
+      __builtin_astype(image, ADDRESS_SPACE dev_image_t*);      \
+    return ptr->width;                                         \
+  }                                                             \
 
 IMPLEMENT_GET_IMAGE_WIDTH(image1d_t)
 IMPLEMENT_GET_IMAGE_WIDTH(image2d_t)
diff --git a/lib/kernel/host/CMakeLists.txt b/lib/kernel/host/CMakeLists.txt
index b08e789..3fcdaa9 100644
--- a/lib/kernel/host/CMakeLists.txt
+++ b/lib/kernel/host/CMakeLists.txt
@@ -31,8 +31,14 @@ else()
   set(KERNEL_SOURCES ${SOURCES_WITHOUT_VML})
 endif()
 
-if(X86_64 OR I386)
-  list(APPEND KERNEL_SOURCES svm_atomics_x86_64.ll svm_atomics.cl)
+if(X86_64 OR I386)
+  if(LLVM_3_6)
+    message(STATUS "OpenCL 2.0 atomics only works with LLVM >= 3.7")
+  elseif(LLVM_OLDER_THAN_3_9)
+    list(APPEND KERNEL_SOURCES svm_atomics_x86_64.ll svm_atomics.cl)
+  else()
+    list(APPEND KERNEL_SOURCES svm_atomics_x86_64_llvm3_9.ll svm_atomics.cl)
+  endif()
 elseif(MIPS)
   message(STATUS "OpenCL 2.0 atomics are currently broken on MIPS")
 else()
diff --git a/lib/kernel/host/Makefile.am b/lib/kernel/host/Makefile.am
index 04ec347..a1197f0 100644
--- a/lib/kernel/host/Makefile.am
+++ b/lib/kernel/host/Makefile.am
@@ -37,8 +37,14 @@ include ../sources-vml.mk
 endif
 
 if HOST_CPU_IS_X86_64
+# clang 3.9 has different mangling,
+# thus new ir file until better implementation is provided
+if LLVM_OLDER_THAN_3_9
   LKERNEL_SRCS_EXTRA2 = svm_atomics_x86_64.ll svm_atomics.cl
 else
+  LKERNEL_SRCS_EXTRA2 = svm_atomics_x86_64_llvm3_9.ll svm_atomics.cl
+endif
+else
   LKERNEL_SRCS_EXTRA2 = svm_atomics_host.cl svm_atomics.cl
 endif
 
diff --git a/lib/kernel/printf.c b/lib/kernel/printf.c
index 4d99e48..03728af 100644
--- a/lib/kernel/printf.c
+++ b/lib/kernel/printf.c
@@ -22,6 +22,9 @@
    THE SOFTWARE.
 */
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-security"
+
 #include <limits.h>
 #include <stdarg.h>
 #include <stdbool.h>
@@ -30,7 +33,8 @@
 // not very efficient, but is easy to implement.
 #define OCL_C_AS __attribute__((address_space(0)))
 int printf(OCL_C_AS const char* restrict fmt, ...);
-int snprintf(OCL_C_AS char* restrict str, size_t size, OCL_C_AS const char* restrict fmt, ...);
+int snprintf(OCL_C_AS char* restrict str, size_t size,
+             OCL_C_AS const char* restrict fmt, ...);
 
 // For debugging
 // Use as: DEBUG_PRINTF((fmt, args...)) -- note double parentheses!
@@ -57,12 +61,13 @@ typedef struct {
 
 #define DEFINE_PRINT_INTS(WIDTH)                                        \
   void _cl_print_ints_##WIDTH(flags_t flags, int field_width, int precision, \
-                              char conv, OCL_C_AS const void* vals, int n)       \
+                              char conv, OCL_C_AS const void* vals, int n) \
   {                                                                     \
     DEBUG_PRINTF(("[printf:ints:n=%df]\n", n));                         \
     char outfmt[1000];                                                  \
+    OCL_C_AS char str[] = "%%%s%s%s%s%s%.0d%s%.0d" INT_CONV_##WIDTH "%c"; \
     snprintf(outfmt, sizeof outfmt,                                     \
-             "%%%s%s%s%s%s%.0d%s%.0d" INT_CONV_##WIDTH "%c",            \
+             str,                                                       \
              flags.left ? "-" : "",                                     \
              flags.plus ? "+" : "",                                     \
              flags.space ? " " : "",                                    \
@@ -73,10 +78,11 @@ typedef struct {
              precision != -1 ? precision : 0,                           \
              conv);                                                     \
     DEBUG_PRINTF(("[printf:ints:outfmt=%s]\n", outfmt));                \
+    OCL_C_AS char comma[] = ",";                                        \
     for (int d=0; d<n; ++d) {                                           \
       DEBUG_PRINTF(("[printf:ints:d=%d]\n", d));                        \
-      if (d != 0) printf(",");                                          \
-      printf(outfmt, ((OCL_C_AS const WIDTH*)vals)[d]);                          \
+      if (d != 0) printf(comma);                                        \
+      printf(outfmt, ((OCL_C_AS const WIDTH*)vals)[d]);                 \
     }                                                                   \
     DEBUG_PRINTF(("[printf:ints:done]\n"));                             \
   }
@@ -95,7 +101,8 @@ DEFINE_PRINT_INTS(long)
 // Helper routines to output floats
 
 // Defined in OpenCL
-float __attribute__((overloadable)) vload_half(size_t offset, const half *p);
+float __attribute__((overloadable)) vload_half(size_t offset,
+                                               OCL_C_AS const half *p);
 
 // Note: To simplify implementation, we print double values with %lf,
 // although %f would suffice as well
@@ -112,8 +119,9 @@ float __attribute__((overloadable)) vload_half(size_t offset, const half *p);
   {                                                                     \
     DEBUG_PRINTF(("[printf:floats:n=%dd]\n", n));                       \
     char outfmt[1000];                                                  \
+    OCL_C_AS char str[] = "%%%s%s%s%s%s%.0d%s%.0d" FLOAT_CONV_##WIDTH "%c"; \
     snprintf(outfmt, sizeof outfmt,                                     \
-             "%%%s%s%s%s%s%.0d%s%.0d" FLOAT_CONV_##WIDTH "%c",          \
+             str,                                                       \
              flags.left ? "-" : "",                                     \
              flags.plus ? "+" : "",                                     \
              flags.space ? " " : "",                                    \
@@ -124,10 +132,11 @@ float __attribute__((overloadable)) vload_half(size_t offset, const half *p);
              precision != -1 ? precision : 0,                           \
              conv);                                                     \
     DEBUG_PRINTF(("[printf:floats:outfmt=%s]\n", outfmt));              \
+    OCL_C_AS char comma[] = ",";                                        \
     for (int d=0; d<n; ++d) {                                           \
       DEBUG_PRINTF(("[printf:floats:d=%d]\n", d));                      \
-      if (d != 0) printf(",");                                          \
-      printf(outfmt, FLOAT_GET_##WIDTH((OCL_C_AS const WIDTH*)vals+d));          \
+      if (d != 0) printf(comma);                                        \
+      printf(outfmt, FLOAT_GET_##WIDTH((OCL_C_AS const WIDTH*)vals+d)); \
     }                                                                   \
     DEBUG_PRINTF(("[printf:floats:done]\n"));                           \
   }
@@ -150,8 +159,9 @@ void _cl_print_char(flags_t flags, int field_width, int val)
 {
   DEBUG_PRINTF(("[printf:char]\n"));
   char outfmt[1000];
+  char string[] = "%%%s%.0dc";
   snprintf(outfmt, sizeof outfmt,
-           "%%%s%.0dc",
+           string,
            flags.left ? "-" : "",
            field_width);
   DEBUG_PRINTF(("[printf:char:outfmt=%s]\n", outfmt));
@@ -163,8 +173,9 @@ void _cl_print_string(flags_t flags, int field_width, OCL_C_AS const char* val)
 {
   DEBUG_PRINTF(("[printf:char]\n"));
   char outfmt[1000];
+  char string[] = "%%%s%.0ds";
   snprintf(outfmt, sizeof outfmt,
-           "%%%s%.0ds",
+           string,
            flags.left ? "-" : "",
            field_width);
   DEBUG_PRINTF(("[printf:char:outfmt=%s]\n", outfmt));
@@ -176,8 +187,9 @@ void _cl_print_pointer(flags_t flags, int field_width, OCL_C_AS const void* val)
 {
   DEBUG_PRINTF(("[printf:char]\n"));
   char outfmt[1000];
+  char string[] = "%%%s%.0dp";
   snprintf(outfmt, sizeof outfmt,
-           "%%%s%.0dp",
+           string,
            flags.left ? "-" : "",
            field_width);
   DEBUG_PRINTF(("[printf:char:outfmt=%s]\n", outfmt));
@@ -213,7 +225,8 @@ int _cl_printf(const OCL_CONSTANT_AS char* restrict format, ...)
       
       if (ch == '%') {
         DEBUG_PRINTF(("[printf:%%]\n"));
-        printf("%%");           // literal %
+        char s[] = "%%";
+        printf(s);           // literal %
         ch = *++format;
       } else {
         DEBUG_PRINTF(("[printf:arg]\n"));
@@ -439,7 +452,8 @@ int _cl_printf(const OCL_CONSTANT_AS char* restrict format, ...)
 
     } else {
       DEBUG_PRINTF(("[printf:literal]\n"));
-      printf("%c", ch);
+      char literal[] = "%c";
+      printf(literal, ch);
       ch = *++format;
     }
   }
@@ -451,6 +465,9 @@ int _cl_printf(const OCL_CONSTANT_AS char* restrict format, ...)
  error:;
   va_end(ap);
   DEBUG_PRINTF(("[printf:error]\n"));
-  printf("(printf format string error)");
+  char string [] = "(printf format string error)";
+  printf(string);
   return -1;
 }
+
+#pragma clang diagnostic pop
diff --git a/lib/kernel/read_image.cl b/lib/kernel/read_image.cl
index a01f564..23dc9e0 100644
--- a/lib/kernel/read_image.cl
+++ b/lib/kernel/read_image.cl
@@ -181,11 +181,14 @@ void __pocl_read_pixel (void* color, ADDRESS_SPACE dev_image_t* dev_image, int4
     __RETVAL__ color;                                                   \
     int4 coord4;                                                        \
     INITCOORD##__COORD__(coord4, coord);                                \
-    if (__pocl_is_out_of_bounds (*(ADDRESS_SPACE dev_image_t**)&image, coord4, (dev_sampler_t*)&sampler, &color)) \
+    ADDRESS_SPACE dev_image_t* i_ptr =                                  \
+      __builtin_astype (image, ADDRESS_SPACE dev_image_t*);             \
+    dev_sampler_t s = __builtin_astype(sampler, dev_sampler_t);         \
+    if (__pocl_is_out_of_bounds (i_ptr, coord4, &s, &color))            \
       {                                                                 \
         return color;                                                   \
       }                                                                 \
-    __pocl_read_pixel (&color, (*(ADDRESS_SPACE dev_image_t**)&image), coord4); \
+    __pocl_read_pixel (&color, i_ptr, coord4); \
                                                                         \
     return color;                                                       \
   }                                                                     \
diff --git a/lib/kernel/svm_atomics_x86_64_llvm3_9.ll b/lib/kernel/svm_atomics_x86_64_llvm3_9.ll
new file mode 100644
index 0000000..8a7eb7b
--- /dev/null
+++ b/lib/kernel/svm_atomics_x86_64_llvm3_9.ll
@@ -0,0 +1,8075 @@
+; ModuleID = 'svm_atomics_host.cl.bc'
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z37pocl_atomic_flag_test_and_set__globalPU8CLglobalVU7_Atomici12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 1 monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 1 acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 1 release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 1 acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 1 seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  %9 = icmp ne i32 %.0, 0
+  ret i1 %9
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z30pocl_atomic_flag_clear__globalPU8CLglobalVU7_Atomici12memory_order12memory_scope(i32 addrspace(1)* nocapture %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %1 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  store atomic volatile i32 0, i32 addrspace(1)* %object monotonic, align 4
+  br label %2
+
+.thread1:                                         ; preds = %0
+  store atomic volatile i32 0, i32 addrspace(1)* %object release, align 4
+  br label %2
+
+; <label>:1                                       ; preds = %0
+  store atomic volatile i32 0, i32 addrspace(1)* %object seq_cst, align 4
+  br label %2
+
+; <label>:2                                       ; preds = %1, %.thread1, %.thread
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z25pocl_atomic_store__globalPU8CLglobalVU7_Atomicii12memory_order12memory_scope(i32 addrspace(1)* nocapture %object, i32 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %1 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  store atomic volatile i32 %desired, i32 addrspace(1)* %object monotonic, align 4
+  br label %2
+
+.thread1:                                         ; preds = %0
+  store atomic volatile i32 %desired, i32 addrspace(1)* %object release, align 4
+  br label %2
+
+; <label>:1                                       ; preds = %0
+  store atomic volatile i32 %desired, i32 addrspace(1)* %object seq_cst, align 4
+  br label %2
+
+; <label>:2                                       ; preds = %1, %.thread1, %.thread
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z24pocl_atomic_load__globalPU8CLglobalVU7_Atomici12memory_order12memory_scope(i32 addrspace(1)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %3 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  %1 = load atomic volatile i32, i32 addrspace(1)* %object monotonic, align 4
+  br label %5
+
+.thread1:                                         ; preds = %0
+  %2 = load atomic volatile i32, i32 addrspace(1)* %object acquire, align 4
+  br label %5
+
+; <label>:3                                       ; preds = %0
+  %4 = load atomic volatile i32, i32 addrspace(1)* %object seq_cst, align 4
+  br label %5
+
+; <label>:5                                       ; preds = %3, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %4, %3 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_exchange__globalPU8CLglobalVU7_Atomicii12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 %desired monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 %desired acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 %desired release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 %desired acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 %desired seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z43pocl_atomic_compare_exchange_strong__globalPU8CLglobalVU7_AtomiciPii12memory_orderS3_12memory_scope(i32 addrspace(1)* %object, i32* nocapture %expected, i32 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i32, i32* %expected, align 4
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i32, i32* %expected, align 4
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i32, i32* %expected, align 4
+  %30 = cmpxchg volatile i32 addrspace(1)* %object, i32 %29, i32 %desired monotonic monotonic
+  %31 = extractvalue { i32, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i32, i1 } %30, 0
+  store i32 %33, i32* %expected, align 4
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg volatile i32 addrspace(1)* %object, i32 %22, i32 %desired acquire monotonic
+  %38 = extractvalue { i32, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg volatile i32 addrspace(1)* %object, i32 %22, i32 %desired acquire acquire
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i32, i1 } %37, 0
+  store i32 %43, i32* %expected, align 4
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i32, i1 } %40, 0
+  store i32 %47, i32* %expected, align 4
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i32, i32* %expected, align 4
+  %52 = cmpxchg volatile i32 addrspace(1)* %object, i32 %51, i32 %desired release monotonic
+  %53 = extractvalue { i32, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i32, i1 } %52, 0
+  store i32 %55, i32* %expected, align 4
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg volatile i32 addrspace(1)* %object, i32 %24, i32 %desired acq_rel monotonic
+  %60 = extractvalue { i32, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg volatile i32 addrspace(1)* %object, i32 %24, i32 %desired acq_rel acquire
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i32, i1 } %59, 0
+  store i32 %65, i32* %expected, align 4
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i32, i1 } %62, 0
+  store i32 %69, i32* %expected, align 4
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i32, i32* %expected, align 4
+  %74 = cmpxchg volatile i32 addrspace(1)* %object, i32 %73, i32 %desired seq_cst monotonic
+  %75 = extractvalue { i32, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i32, i32* %expected, align 4
+  %78 = cmpxchg volatile i32 addrspace(1)* %object, i32 %77, i32 %desired seq_cst acquire
+  %79 = extractvalue { i32, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i32, i32* %expected, align 4
+  %82 = cmpxchg volatile i32 addrspace(1)* %object, i32 %81, i32 %desired seq_cst seq_cst
+  %83 = extractvalue { i32, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i32, i1 } %74, 0
+  store i32 %85, i32* %expected, align 4
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i32, i1 } %78, 0
+  store i32 %89, i32* %expected, align 4
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i32, i1 } %82, 0
+  store i32 %93, i32* %expected, align 4
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z41pocl_atomic_compare_exchange_weak__globalPU8CLglobalVU7_AtomiciPii12memory_orderS3_12memory_scope(i32 addrspace(1)* %object, i32* nocapture %expected, i32 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i32, i32* %expected, align 4
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i32, i32* %expected, align 4
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i32, i32* %expected, align 4
+  %30 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %29, i32 %desired monotonic monotonic
+  %31 = extractvalue { i32, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i32, i1 } %30, 0
+  store i32 %33, i32* %expected, align 4
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %22, i32 %desired acquire monotonic
+  %38 = extractvalue { i32, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %22, i32 %desired acquire acquire
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i32, i1 } %37, 0
+  store i32 %43, i32* %expected, align 4
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i32, i1 } %40, 0
+  store i32 %47, i32* %expected, align 4
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i32, i32* %expected, align 4
+  %52 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %51, i32 %desired release monotonic
+  %53 = extractvalue { i32, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i32, i1 } %52, 0
+  store i32 %55, i32* %expected, align 4
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %24, i32 %desired acq_rel monotonic
+  %60 = extractvalue { i32, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %24, i32 %desired acq_rel acquire
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i32, i1 } %59, 0
+  store i32 %65, i32* %expected, align 4
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i32, i1 } %62, 0
+  store i32 %69, i32* %expected, align 4
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i32, i32* %expected, align 4
+  %74 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %73, i32 %desired seq_cst monotonic
+  %75 = extractvalue { i32, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i32, i32* %expected, align 4
+  %78 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %77, i32 %desired seq_cst acquire
+  %79 = extractvalue { i32, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i32, i32* %expected, align 4
+  %82 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %81, i32 %desired seq_cst seq_cst
+  %83 = extractvalue { i32, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i32, i1 } %74, 0
+  store i32 %85, i32* %expected, align 4
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i32, i1 } %78, 0
+  store i32 %89, i32* %expected, align 4
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i32, i1 } %82, 0
+  store i32 %93, i32* %expected, align 4
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_add__globalPU8CLglobalVU7_Atomicii12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile add i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile add i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile add i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile add i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile add i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_sub__globalPU8CLglobalVU7_Atomicii12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile sub i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile sub i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile sub i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile sub i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile sub i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_or__globalPU8CLglobalVU7_Atomicii12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile or i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile or i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile or i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile or i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile or i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_xor__globalPU8CLglobalVU7_Atomicii12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xor i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xor i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xor i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xor i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xor i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_and__globalPU8CLglobalVU7_Atomicii12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile and i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile and i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile and i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile and i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile and i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_min__globalPU8CLglobalVU7_Atomicii12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile min i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile min i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile min i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile min i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile min i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_max__globalPU8CLglobalVU7_Atomicii12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile max i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile max i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile max i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile max i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile max i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z25pocl_atomic_store__globalPU8CLglobalVU7_Atomicjj12memory_order12memory_scope(i32 addrspace(1)* nocapture %object, i32 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %1 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  store atomic volatile i32 %desired, i32 addrspace(1)* %object monotonic, align 4
+  br label %2
+
+.thread1:                                         ; preds = %0
+  store atomic volatile i32 %desired, i32 addrspace(1)* %object release, align 4
+  br label %2
+
+; <label>:1                                       ; preds = %0
+  store atomic volatile i32 %desired, i32 addrspace(1)* %object seq_cst, align 4
+  br label %2
+
+; <label>:2                                       ; preds = %1, %.thread1, %.thread
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z24pocl_atomic_load__globalPU8CLglobalVU7_Atomicj12memory_order12memory_scope(i32 addrspace(1)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %3 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  %1 = load atomic volatile i32, i32 addrspace(1)* %object monotonic, align 4
+  br label %5
+
+.thread1:                                         ; preds = %0
+  %2 = load atomic volatile i32, i32 addrspace(1)* %object acquire, align 4
+  br label %5
+
+; <label>:3                                       ; preds = %0
+  %4 = load atomic volatile i32, i32 addrspace(1)* %object seq_cst, align 4
+  br label %5
+
+; <label>:5                                       ; preds = %3, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %4, %3 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_exchange__globalPU8CLglobalVU7_Atomicjj12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 %desired monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 %desired acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 %desired release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 %desired acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xchg i32 addrspace(1)* %object, i32 %desired seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z43pocl_atomic_compare_exchange_strong__globalPU8CLglobalVU7_AtomicjPjj12memory_orderS3_12memory_scope(i32 addrspace(1)* %object, i32* nocapture %expected, i32 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i32, i32* %expected, align 4
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i32, i32* %expected, align 4
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i32, i32* %expected, align 4
+  %30 = cmpxchg volatile i32 addrspace(1)* %object, i32 %29, i32 %desired monotonic monotonic
+  %31 = extractvalue { i32, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i32, i1 } %30, 0
+  store i32 %33, i32* %expected, align 4
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg volatile i32 addrspace(1)* %object, i32 %22, i32 %desired acquire monotonic
+  %38 = extractvalue { i32, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg volatile i32 addrspace(1)* %object, i32 %22, i32 %desired acquire acquire
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i32, i1 } %37, 0
+  store i32 %43, i32* %expected, align 4
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i32, i1 } %40, 0
+  store i32 %47, i32* %expected, align 4
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i32, i32* %expected, align 4
+  %52 = cmpxchg volatile i32 addrspace(1)* %object, i32 %51, i32 %desired release monotonic
+  %53 = extractvalue { i32, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i32, i1 } %52, 0
+  store i32 %55, i32* %expected, align 4
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg volatile i32 addrspace(1)* %object, i32 %24, i32 %desired acq_rel monotonic
+  %60 = extractvalue { i32, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg volatile i32 addrspace(1)* %object, i32 %24, i32 %desired acq_rel acquire
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i32, i1 } %59, 0
+  store i32 %65, i32* %expected, align 4
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i32, i1 } %62, 0
+  store i32 %69, i32* %expected, align 4
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i32, i32* %expected, align 4
+  %74 = cmpxchg volatile i32 addrspace(1)* %object, i32 %73, i32 %desired seq_cst monotonic
+  %75 = extractvalue { i32, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i32, i32* %expected, align 4
+  %78 = cmpxchg volatile i32 addrspace(1)* %object, i32 %77, i32 %desired seq_cst acquire
+  %79 = extractvalue { i32, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i32, i32* %expected, align 4
+  %82 = cmpxchg volatile i32 addrspace(1)* %object, i32 %81, i32 %desired seq_cst seq_cst
+  %83 = extractvalue { i32, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i32, i1 } %74, 0
+  store i32 %85, i32* %expected, align 4
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i32, i1 } %78, 0
+  store i32 %89, i32* %expected, align 4
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i32, i1 } %82, 0
+  store i32 %93, i32* %expected, align 4
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z41pocl_atomic_compare_exchange_weak__globalPU8CLglobalVU7_AtomicjPjj12memory_orderS3_12memory_scope(i32 addrspace(1)* %object, i32* nocapture %expected, i32 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i32, i32* %expected, align 4
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i32, i32* %expected, align 4
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i32, i32* %expected, align 4
+  %30 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %29, i32 %desired monotonic monotonic
+  %31 = extractvalue { i32, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i32, i1 } %30, 0
+  store i32 %33, i32* %expected, align 4
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %22, i32 %desired acquire monotonic
+  %38 = extractvalue { i32, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %22, i32 %desired acquire acquire
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i32, i1 } %37, 0
+  store i32 %43, i32* %expected, align 4
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i32, i1 } %40, 0
+  store i32 %47, i32* %expected, align 4
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i32, i32* %expected, align 4
+  %52 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %51, i32 %desired release monotonic
+  %53 = extractvalue { i32, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i32, i1 } %52, 0
+  store i32 %55, i32* %expected, align 4
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %24, i32 %desired acq_rel monotonic
+  %60 = extractvalue { i32, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %24, i32 %desired acq_rel acquire
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i32, i1 } %59, 0
+  store i32 %65, i32* %expected, align 4
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i32, i1 } %62, 0
+  store i32 %69, i32* %expected, align 4
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i32, i32* %expected, align 4
+  %74 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %73, i32 %desired seq_cst monotonic
+  %75 = extractvalue { i32, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i32, i32* %expected, align 4
+  %78 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %77, i32 %desired seq_cst acquire
+  %79 = extractvalue { i32, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i32, i32* %expected, align 4
+  %82 = cmpxchg weak volatile i32 addrspace(1)* %object, i32 %81, i32 %desired seq_cst seq_cst
+  %83 = extractvalue { i32, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i32, i1 } %74, 0
+  store i32 %85, i32* %expected, align 4
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i32, i1 } %78, 0
+  store i32 %89, i32* %expected, align 4
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i32, i1 } %82, 0
+  store i32 %93, i32* %expected, align 4
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_add__globalPU8CLglobalVU7_Atomicjj12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile add i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile add i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile add i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile add i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile add i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_sub__globalPU8CLglobalVU7_Atomicjj12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile sub i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile sub i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile sub i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile sub i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile sub i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_or__globalPU8CLglobalVU7_Atomicjj12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile or i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile or i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile or i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile or i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile or i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_xor__globalPU8CLglobalVU7_Atomicjj12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xor i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xor i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xor i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xor i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xor i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_and__globalPU8CLglobalVU7_Atomicjj12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile and i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile and i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile and i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile and i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile and i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_min__globalPU8CLglobalVU7_Atomicjj12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile umin i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile umin i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile umin i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile umin i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile umin i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z29pocl_atomic_fetch_max__globalPU8CLglobalVU7_Atomicjj12memory_order12memory_scope(i32 addrspace(1)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile umax i32 addrspace(1)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile umax i32 addrspace(1)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile umax i32 addrspace(1)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile umax i32 addrspace(1)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile umax i32 addrspace(1)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z25pocl_atomic_store__globalPU8CLglobalVU7_Atomicff12memory_order12memory_scope(float addrspace(1)* nocapture %object, float %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %5 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+  ]
+
+.thread1:                                         ; preds = %0
+  %1 = bitcast float %desired to i32
+  %2 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  store atomic volatile i32 %1, i32 addrspace(1)* %2 release, align 4
+  br label %13
+
+.thread:                                          ; preds = %0, %0
+  %3 = bitcast float %desired to i32
+  %4 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  br label %9
+
+; <label>:5                                       ; preds = %0
+  %6 = icmp eq i32 %order, 3
+  %7 = bitcast float %desired to i32
+  %8 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  br i1 %6, label %9, label %12
+
+; <label>:9                                       ; preds = %5, %.thread
+  %10 = phi i32 addrspace(1)* [ %4, %.thread ], [ %8, %5 ]
+  %11 = phi i32 [ %3, %.thread ], [ %7, %5 ]
+  store atomic volatile i32 %11, i32 addrspace(1)* %10 monotonic, align 4
+  br label %13
+
+; <label>:12                                      ; preds = %5
+  store atomic volatile i32 %7, i32 addrspace(1)* %8 seq_cst, align 4
+  br label %13
+
+; <label>:13                                      ; preds = %12, %.thread1, %9
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define float @_Z24pocl_atomic_load__globalPU8CLglobalVU7_Atomicf12memory_order12memory_scope(float addrspace(1)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %4 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+  ]
+
+.thread1:                                         ; preds = %0
+  %1 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  %2 = load atomic volatile i32, i32 addrspace(1)* %1 acquire, align 4
+  br label %12
+
+.thread:                                          ; preds = %0, %0
+  %3 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  br label %7
+
+; <label>:4                                       ; preds = %0
+  %5 = icmp eq i32 %order, 3
+  %6 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  br i1 %5, label %7, label %10
+
+; <label>:7                                       ; preds = %4, %.thread
+  %8 = phi i32 addrspace(1)* [ %3, %.thread ], [ %6, %4 ]
+  %9 = load atomic volatile i32, i32 addrspace(1)* %8 monotonic, align 4
+  br label %12
+
+; <label>:10                                      ; preds = %4
+  %11 = load atomic volatile i32, i32 addrspace(1)* %6 seq_cst, align 4
+  br label %12
+
+; <label>:12                                      ; preds = %10, %.thread1, %7
+  %.sroa.0.0 = phi i32 [ %9, %7 ], [ %11, %10 ], [ %2, %.thread1 ]
+  %13 = bitcast i32 %.sroa.0.0 to float
+  ret float %13
+}
+
+; Function Attrs: nounwind uwtable
+define float @_Z28pocl_atomic_exchange__globalPU8CLglobalVU7_Atomicff12memory_order12memory_scope(float addrspace(1)* %object, float %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %10 [
+    i32 0, label %.thread
+    i32 1, label %.thread2
+    i32 2, label %.thread3
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = bitcast float %desired to i32
+  %2 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  %3 = atomicrmw volatile xchg i32 addrspace(1)* %2, i32 %1 monotonic
+  br label %18
+
+.thread2:                                         ; preds = %0
+  %4 = bitcast float %desired to i32
+  %5 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  %6 = atomicrmw volatile xchg i32 addrspace(1)* %5, i32 %4 acquire
+  br label %18
+
+.thread3:                                         ; preds = %0
+  %7 = bitcast float %desired to i32
+  %8 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  %9 = atomicrmw volatile xchg i32 addrspace(1)* %8, i32 %7 release
+  br label %18
+
+; <label>:10                                      ; preds = %0
+  %11 = icmp eq i32 %order, 3
+  %12 = bitcast float %desired to i32
+  %13 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  br i1 %11, label %14, label %16
+
+; <label>:14                                      ; preds = %10
+  %15 = atomicrmw volatile xchg i32 addrspace(1)* %13, i32 %12 acq_rel
+  br label %18
+
+; <label>:16                                      ; preds = %10
+  %17 = atomicrmw volatile xchg i32 addrspace(1)* %13, i32 %12 seq_cst
+  br label %18
+
+; <label>:18                                      ; preds = %16, %14, %.thread3, %.thread2, %.thread
+  %.sroa.0.0 = phi i32 [ %3, %.thread ], [ %17, %16 ], [ %15, %14 ], [ %9, %.thread3 ], [ %6, %.thread2 ]
+  %19 = bitcast i32 %.sroa.0.0 to float
+  ret float %19
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z43pocl_atomic_compare_exchange_strong__globalPU8CLglobalVU7_AtomicfPff12memory_orderS3_12memory_scope(float addrspace(1)* %object, float* nocapture %expected, float %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = bitcast float %desired to i32
+  %12 = icmp eq i32 %failure, 0
+  br i1 %12, label %20, label %13
+
+; <label>:13                                      ; preds = %9
+  %14 = icmp eq i32 %failure, 1
+  br i1 %14, label %20, label %15
+
+; <label>:15                                      ; preds = %13
+  %16 = icmp eq i32 %failure, 2
+  br i1 %16, label %20, label %17
+
+; <label>:17                                      ; preds = %15
+  %18 = icmp eq i32 %failure, 3
+  %19 = select i1 %18, i32 4, i32 5
+  br label %20
+
+; <label>:20                                      ; preds = %13, %15, %17, %9
+  %21 = phi i32 [ 0, %9 ], [ 2, %13 ], [ %19, %17 ], [ 3, %15 ]
+  %22 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  %23 = bitcast float* %expected to i32*
+  switch i32 %10, label %31 [
+    i32 1, label %24
+    i32 2, label %24
+    i32 3, label %53
+    i32 4, label %26
+    i32 5, label %28
+  ]
+
+; <label>:24                                      ; preds = %20, %20
+  %.off = add nsw i32 %21, -1
+  %switch = icmp ult i32 %.off, 2
+  %25 = load i32, i32* %23, align 4
+  br i1 %switch, label %42, label %39
+
+; <label>:26                                      ; preds = %20
+  %.off1 = add nsw i32 %21, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %27 = load i32, i32* %23, align 4
+  br i1 %switch2, label %64, label %61
+
+; <label>:28                                      ; preds = %20
+  switch i32 %21, label %75 [
+    i32 1, label %79
+    i32 2, label %79
+    i32 5, label %83
+  ]
+
+; <label>:29                                      ; preds = %89, %93, %97, %69, %73, %47, %51, %59, %37
+  %.0 = phi i8 [ %38, %37 ], [ %90, %89 ], [ %98, %97 ], [ %94, %93 ], [ %74, %73 ], [ %70, %69 ], [ %60, %59 ], [ %52, %51 ], [ %48, %47 ]
+  %30 = icmp ne i8 %.0, 0
+  ret i1 %30
+
+; <label>:31                                      ; preds = %20
+  %32 = load i32, i32* %23, align 4
+  %33 = cmpxchg volatile i32 addrspace(1)* %22, i32 %32, i32 %11 monotonic monotonic
+  %34 = extractvalue { i32, i1 } %33, 1
+  br i1 %34, label %37, label %35
+
+; <label>:35                                      ; preds = %31
+  %36 = extractvalue { i32, i1 } %33, 0
+  store i32 %36, i32* %23, align 4
+  br label %37
+
+; <label>:37                                      ; preds = %35, %31
+  %38 = zext i1 %34 to i8
+  br label %29
+
+; <label>:39                                      ; preds = %24
+  %40 = cmpxchg volatile i32 addrspace(1)* %22, i32 %25, i32 %11 acquire monotonic
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %47, label %45
+
+; <label>:42                                      ; preds = %24
+  %43 = cmpxchg volatile i32 addrspace(1)* %22, i32 %25, i32 %11 acquire acquire
+  %44 = extractvalue { i32, i1 } %43, 1
+  br i1 %44, label %51, label %49
+
+; <label>:45                                      ; preds = %39
+  %46 = extractvalue { i32, i1 } %40, 0
+  store i32 %46, i32* %23, align 4
+  br label %47
+
+; <label>:47                                      ; preds = %45, %39
+  %48 = zext i1 %41 to i8
+  br label %29
+
+; <label>:49                                      ; preds = %42
+  %50 = extractvalue { i32, i1 } %43, 0
+  store i32 %50, i32* %23, align 4
+  br label %51
+
+; <label>:51                                      ; preds = %49, %42
+  %52 = zext i1 %44 to i8
+  br label %29
+
+; <label>:53                                      ; preds = %20
+  %54 = load i32, i32* %23, align 4
+  %55 = cmpxchg volatile i32 addrspace(1)* %22, i32 %54, i32 %11 release monotonic
+  %56 = extractvalue { i32, i1 } %55, 1
+  br i1 %56, label %59, label %57
+
+; <label>:57                                      ; preds = %53
+  %58 = extractvalue { i32, i1 } %55, 0
+  store i32 %58, i32* %23, align 4
+  br label %59
+
+; <label>:59                                      ; preds = %57, %53
+  %60 = zext i1 %56 to i8
+  br label %29
+
+; <label>:61                                      ; preds = %26
+  %62 = cmpxchg volatile i32 addrspace(1)* %22, i32 %27, i32 %11 acq_rel monotonic
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %69, label %67
+
+; <label>:64                                      ; preds = %26
+  %65 = cmpxchg volatile i32 addrspace(1)* %22, i32 %27, i32 %11 acq_rel acquire
+  %66 = extractvalue { i32, i1 } %65, 1
+  br i1 %66, label %73, label %71
+
+; <label>:67                                      ; preds = %61
+  %68 = extractvalue { i32, i1 } %62, 0
+  store i32 %68, i32* %23, align 4
+  br label %69
+
+; <label>:69                                      ; preds = %67, %61
+  %70 = zext i1 %63 to i8
+  br label %29
+
+; <label>:71                                      ; preds = %64
+  %72 = extractvalue { i32, i1 } %65, 0
+  store i32 %72, i32* %23, align 4
+  br label %73
+
+; <label>:73                                      ; preds = %71, %64
+  %74 = zext i1 %66 to i8
+  br label %29
+
+; <label>:75                                      ; preds = %28
+  %76 = load i32, i32* %23, align 4
+  %77 = cmpxchg volatile i32 addrspace(1)* %22, i32 %76, i32 %11 seq_cst monotonic
+  %78 = extractvalue { i32, i1 } %77, 1
+  br i1 %78, label %89, label %87
+
+; <label>:79                                      ; preds = %28, %28
+  %80 = load i32, i32* %23, align 4
+  %81 = cmpxchg volatile i32 addrspace(1)* %22, i32 %80, i32 %11 seq_cst acquire
+  %82 = extractvalue { i32, i1 } %81, 1
+  br i1 %82, label %93, label %91
+
+; <label>:83                                      ; preds = %28
+  %84 = load i32, i32* %23, align 4
+  %85 = cmpxchg volatile i32 addrspace(1)* %22, i32 %84, i32 %11 seq_cst seq_cst
+  %86 = extractvalue { i32, i1 } %85, 1
+  br i1 %86, label %97, label %95
+
+; <label>:87                                      ; preds = %75
+  %88 = extractvalue { i32, i1 } %77, 0
+  store i32 %88, i32* %23, align 4
+  br label %89
+
+; <label>:89                                      ; preds = %87, %75
+  %90 = zext i1 %78 to i8
+  br label %29
+
+; <label>:91                                      ; preds = %79
+  %92 = extractvalue { i32, i1 } %81, 0
+  store i32 %92, i32* %23, align 4
+  br label %93
+
+; <label>:93                                      ; preds = %91, %79
+  %94 = zext i1 %82 to i8
+  br label %29
+
+; <label>:95                                      ; preds = %83
+  %96 = extractvalue { i32, i1 } %85, 0
+  store i32 %96, i32* %23, align 4
+  br label %97
+
+; <label>:97                                      ; preds = %95, %83
+  %98 = zext i1 %86 to i8
+  br label %29
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z41pocl_atomic_compare_exchange_weak__globalPU8CLglobalVU7_AtomicfPff12memory_orderS3_12memory_scope(float addrspace(1)* %object, float* nocapture %expected, float %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = bitcast float %desired to i32
+  %12 = icmp eq i32 %failure, 0
+  br i1 %12, label %20, label %13
+
+; <label>:13                                      ; preds = %9
+  %14 = icmp eq i32 %failure, 1
+  br i1 %14, label %20, label %15
+
+; <label>:15                                      ; preds = %13
+  %16 = icmp eq i32 %failure, 2
+  br i1 %16, label %20, label %17
+
+; <label>:17                                      ; preds = %15
+  %18 = icmp eq i32 %failure, 3
+  %19 = select i1 %18, i32 4, i32 5
+  br label %20
+
+; <label>:20                                      ; preds = %13, %15, %17, %9
+  %21 = phi i32 [ 0, %9 ], [ 2, %13 ], [ %19, %17 ], [ 3, %15 ]
+  %22 = bitcast float addrspace(1)* %object to i32 addrspace(1)*
+  %23 = bitcast float* %expected to i32*
+  switch i32 %10, label %31 [
+    i32 1, label %24
+    i32 2, label %24
+    i32 3, label %53
+    i32 4, label %26
+    i32 5, label %28
+  ]
+
+; <label>:24                                      ; preds = %20, %20
+  %.off = add nsw i32 %21, -1
+  %switch = icmp ult i32 %.off, 2
+  %25 = load i32, i32* %23, align 4
+  br i1 %switch, label %42, label %39
+
+; <label>:26                                      ; preds = %20
+  %.off1 = add nsw i32 %21, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %27 = load i32, i32* %23, align 4
+  br i1 %switch2, label %64, label %61
+
+; <label>:28                                      ; preds = %20
+  switch i32 %21, label %75 [
+    i32 1, label %79
+    i32 2, label %79
+    i32 5, label %83
+  ]
+
+; <label>:29                                      ; preds = %89, %93, %97, %69, %73, %47, %51, %59, %37
+  %.0 = phi i8 [ %38, %37 ], [ %90, %89 ], [ %98, %97 ], [ %94, %93 ], [ %74, %73 ], [ %70, %69 ], [ %60, %59 ], [ %52, %51 ], [ %48, %47 ]
+  %30 = icmp ne i8 %.0, 0
+  ret i1 %30
+
+; <label>:31                                      ; preds = %20
+  %32 = load i32, i32* %23, align 4
+  %33 = cmpxchg weak volatile i32 addrspace(1)* %22, i32 %32, i32 %11 monotonic monotonic
+  %34 = extractvalue { i32, i1 } %33, 1
+  br i1 %34, label %37, label %35
+
+; <label>:35                                      ; preds = %31
+  %36 = extractvalue { i32, i1 } %33, 0
+  store i32 %36, i32* %23, align 4
+  br label %37
+
+; <label>:37                                      ; preds = %35, %31
+  %38 = zext i1 %34 to i8
+  br label %29
+
+; <label>:39                                      ; preds = %24
+  %40 = cmpxchg weak volatile i32 addrspace(1)* %22, i32 %25, i32 %11 acquire monotonic
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %47, label %45
+
+; <label>:42                                      ; preds = %24
+  %43 = cmpxchg weak volatile i32 addrspace(1)* %22, i32 %25, i32 %11 acquire acquire
+  %44 = extractvalue { i32, i1 } %43, 1
+  br i1 %44, label %51, label %49
+
+; <label>:45                                      ; preds = %39
+  %46 = extractvalue { i32, i1 } %40, 0
+  store i32 %46, i32* %23, align 4
+  br label %47
+
+; <label>:47                                      ; preds = %45, %39
+  %48 = zext i1 %41 to i8
+  br label %29
+
+; <label>:49                                      ; preds = %42
+  %50 = extractvalue { i32, i1 } %43, 0
+  store i32 %50, i32* %23, align 4
+  br label %51
+
+; <label>:51                                      ; preds = %49, %42
+  %52 = zext i1 %44 to i8
+  br label %29
+
+; <label>:53                                      ; preds = %20
+  %54 = load i32, i32* %23, align 4
+  %55 = cmpxchg weak volatile i32 addrspace(1)* %22, i32 %54, i32 %11 release monotonic
+  %56 = extractvalue { i32, i1 } %55, 1
+  br i1 %56, label %59, label %57
+
+; <label>:57                                      ; preds = %53
+  %58 = extractvalue { i32, i1 } %55, 0
+  store i32 %58, i32* %23, align 4
+  br label %59
+
+; <label>:59                                      ; preds = %57, %53
+  %60 = zext i1 %56 to i8
+  br label %29
+
+; <label>:61                                      ; preds = %26
+  %62 = cmpxchg weak volatile i32 addrspace(1)* %22, i32 %27, i32 %11 acq_rel monotonic
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %69, label %67
+
+; <label>:64                                      ; preds = %26
+  %65 = cmpxchg weak volatile i32 addrspace(1)* %22, i32 %27, i32 %11 acq_rel acquire
+  %66 = extractvalue { i32, i1 } %65, 1
+  br i1 %66, label %73, label %71
+
+; <label>:67                                      ; preds = %61
+  %68 = extractvalue { i32, i1 } %62, 0
+  store i32 %68, i32* %23, align 4
+  br label %69
+
+; <label>:69                                      ; preds = %67, %61
+  %70 = zext i1 %63 to i8
+  br label %29
+
+; <label>:71                                      ; preds = %64
+  %72 = extractvalue { i32, i1 } %65, 0
+  store i32 %72, i32* %23, align 4
+  br label %73
+
+; <label>:73                                      ; preds = %71, %64
+  %74 = zext i1 %66 to i8
+  br label %29
+
+; <label>:75                                      ; preds = %28
+  %76 = load i32, i32* %23, align 4
+  %77 = cmpxchg weak volatile i32 addrspace(1)* %22, i32 %76, i32 %11 seq_cst monotonic
+  %78 = extractvalue { i32, i1 } %77, 1
+  br i1 %78, label %89, label %87
+
+; <label>:79                                      ; preds = %28, %28
+  %80 = load i32, i32* %23, align 4
+  %81 = cmpxchg weak volatile i32 addrspace(1)* %22, i32 %80, i32 %11 seq_cst acquire
+  %82 = extractvalue { i32, i1 } %81, 1
+  br i1 %82, label %93, label %91
+
+; <label>:83                                      ; preds = %28
+  %84 = load i32, i32* %23, align 4
+  %85 = cmpxchg weak volatile i32 addrspace(1)* %22, i32 %84, i32 %11 seq_cst seq_cst
+  %86 = extractvalue { i32, i1 } %85, 1
+  br i1 %86, label %97, label %95
+
+; <label>:87                                      ; preds = %75
+  %88 = extractvalue { i32, i1 } %77, 0
+  store i32 %88, i32* %23, align 4
+  br label %89
+
+; <label>:89                                      ; preds = %87, %75
+  %90 = zext i1 %78 to i8
+  br label %29
+
+; <label>:91                                      ; preds = %79
+  %92 = extractvalue { i32, i1 } %81, 0
+  store i32 %92, i32* %23, align 4
+  br label %93
+
+; <label>:93                                      ; preds = %91, %79
+  %94 = zext i1 %82 to i8
+  br label %29
+
+; <label>:95                                      ; preds = %83
+  %96 = extractvalue { i32, i1 } %85, 0
+  store i32 %96, i32* %23, align 4
+  br label %97
+
+; <label>:97                                      ; preds = %95, %83
+  %98 = zext i1 %86 to i8
+  br label %29
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z25pocl_atomic_store__globalPU8CLglobalVU7_Atomicll12memory_order12memory_scope(i64 addrspace(1)* nocapture %object, i64 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %1 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  store atomic volatile i64 %desired, i64 addrspace(1)* %object monotonic, align 8
+  br label %2
+
+.thread1:                                         ; preds = %0
+  store atomic volatile i64 %desired, i64 addrspace(1)* %object release, align 8
+  br label %2
+
+; <label>:1                                       ; preds = %0
+  store atomic volatile i64 %desired, i64 addrspace(1)* %object seq_cst, align 8
+  br label %2
+
+; <label>:2                                       ; preds = %1, %.thread1, %.thread
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z24pocl_atomic_load__globalPU8CLglobalVU7_Atomicl12memory_order12memory_scope(i64 addrspace(1)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %3 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  %1 = load atomic volatile i64, i64 addrspace(1)* %object monotonic, align 8
+  br label %5
+
+.thread1:                                         ; preds = %0
+  %2 = load atomic volatile i64, i64 addrspace(1)* %object acquire, align 8
+  br label %5
+
+; <label>:3                                       ; preds = %0
+  %4 = load atomic volatile i64, i64 addrspace(1)* %object seq_cst, align 8
+  br label %5
+
+; <label>:5                                       ; preds = %3, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %4, %3 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_exchange__globalPU8CLglobalVU7_Atomicll12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xchg i64 addrspace(1)* %object, i64 %desired monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xchg i64 addrspace(1)* %object, i64 %desired acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xchg i64 addrspace(1)* %object, i64 %desired release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xchg i64 addrspace(1)* %object, i64 %desired acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xchg i64 addrspace(1)* %object, i64 %desired seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z43pocl_atomic_compare_exchange_strong__globalPU8CLglobalVU7_AtomiclPll12memory_orderS3_12memory_scope(i64 addrspace(1)* %object, i64* nocapture %expected, i64 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i64, i64* %expected, align 8
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i64, i64* %expected, align 8
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i64, i64* %expected, align 8
+  %30 = cmpxchg volatile i64 addrspace(1)* %object, i64 %29, i64 %desired monotonic monotonic
+  %31 = extractvalue { i64, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i64, i1 } %30, 0
+  store i64 %33, i64* %expected, align 8
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg volatile i64 addrspace(1)* %object, i64 %22, i64 %desired acquire monotonic
+  %38 = extractvalue { i64, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg volatile i64 addrspace(1)* %object, i64 %22, i64 %desired acquire acquire
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i64, i1 } %37, 0
+  store i64 %43, i64* %expected, align 8
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i64, i1 } %40, 0
+  store i64 %47, i64* %expected, align 8
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i64, i64* %expected, align 8
+  %52 = cmpxchg volatile i64 addrspace(1)* %object, i64 %51, i64 %desired release monotonic
+  %53 = extractvalue { i64, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i64, i1 } %52, 0
+  store i64 %55, i64* %expected, align 8
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg volatile i64 addrspace(1)* %object, i64 %24, i64 %desired acq_rel monotonic
+  %60 = extractvalue { i64, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg volatile i64 addrspace(1)* %object, i64 %24, i64 %desired acq_rel acquire
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i64, i1 } %59, 0
+  store i64 %65, i64* %expected, align 8
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i64, i1 } %62, 0
+  store i64 %69, i64* %expected, align 8
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i64, i64* %expected, align 8
+  %74 = cmpxchg volatile i64 addrspace(1)* %object, i64 %73, i64 %desired seq_cst monotonic
+  %75 = extractvalue { i64, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i64, i64* %expected, align 8
+  %78 = cmpxchg volatile i64 addrspace(1)* %object, i64 %77, i64 %desired seq_cst acquire
+  %79 = extractvalue { i64, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i64, i64* %expected, align 8
+  %82 = cmpxchg volatile i64 addrspace(1)* %object, i64 %81, i64 %desired seq_cst seq_cst
+  %83 = extractvalue { i64, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i64, i1 } %74, 0
+  store i64 %85, i64* %expected, align 8
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i64, i1 } %78, 0
+  store i64 %89, i64* %expected, align 8
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i64, i1 } %82, 0
+  store i64 %93, i64* %expected, align 8
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z41pocl_atomic_compare_exchange_weak__globalPU8CLglobalVU7_AtomiclPll12memory_orderS3_12memory_scope(i64 addrspace(1)* %object, i64* nocapture %expected, i64 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i64, i64* %expected, align 8
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i64, i64* %expected, align 8
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i64, i64* %expected, align 8
+  %30 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %29, i64 %desired monotonic monotonic
+  %31 = extractvalue { i64, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i64, i1 } %30, 0
+  store i64 %33, i64* %expected, align 8
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %22, i64 %desired acquire monotonic
+  %38 = extractvalue { i64, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %22, i64 %desired acquire acquire
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i64, i1 } %37, 0
+  store i64 %43, i64* %expected, align 8
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i64, i1 } %40, 0
+  store i64 %47, i64* %expected, align 8
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i64, i64* %expected, align 8
+  %52 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %51, i64 %desired release monotonic
+  %53 = extractvalue { i64, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i64, i1 } %52, 0
+  store i64 %55, i64* %expected, align 8
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %24, i64 %desired acq_rel monotonic
+  %60 = extractvalue { i64, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %24, i64 %desired acq_rel acquire
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i64, i1 } %59, 0
+  store i64 %65, i64* %expected, align 8
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i64, i1 } %62, 0
+  store i64 %69, i64* %expected, align 8
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i64, i64* %expected, align 8
+  %74 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %73, i64 %desired seq_cst monotonic
+  %75 = extractvalue { i64, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i64, i64* %expected, align 8
+  %78 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %77, i64 %desired seq_cst acquire
+  %79 = extractvalue { i64, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i64, i64* %expected, align 8
+  %82 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %81, i64 %desired seq_cst seq_cst
+  %83 = extractvalue { i64, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i64, i1 } %74, 0
+  store i64 %85, i64* %expected, align 8
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i64, i1 } %78, 0
+  store i64 %89, i64* %expected, align 8
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i64, i1 } %82, 0
+  store i64 %93, i64* %expected, align 8
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_add__globalPU8CLglobalVU7_Atomicll12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile add i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile add i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile add i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile add i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile add i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_sub__globalPU8CLglobalVU7_Atomicll12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile sub i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile sub i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile sub i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile sub i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile sub i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_or__globalPU8CLglobalVU7_Atomicll12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile or i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile or i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile or i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile or i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile or i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_xor__globalPU8CLglobalVU7_Atomicll12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xor i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xor i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xor i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xor i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xor i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_and__globalPU8CLglobalVU7_Atomicll12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile and i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile and i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile and i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile and i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile and i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: noreturn nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_min__globalPU8CLglobalVU7_Atomicll12memory_order12memory_scope(i64 addrspace(1)* nocapture readnone %object, i64 %operand, i32 %order, i32 %scope) #1 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile min i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile min i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile min i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile min i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile min i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: noreturn nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_max__globalPU8CLglobalVU7_Atomicll12memory_order12memory_scope(i64 addrspace(1)* nocapture readnone %object, i64 %operand, i32 %order, i32 %scope) #1 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile max i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile max i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile max i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile max i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile max i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z25pocl_atomic_store__globalPU8CLglobalVU7_Atomicmm12memory_order12memory_scope(i64 addrspace(1)* nocapture %object, i64 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %1 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  store atomic volatile i64 %desired, i64 addrspace(1)* %object monotonic, align 8
+  br label %2
+
+.thread1:                                         ; preds = %0
+  store atomic volatile i64 %desired, i64 addrspace(1)* %object release, align 8
+  br label %2
+
+; <label>:1                                       ; preds = %0
+  store atomic volatile i64 %desired, i64 addrspace(1)* %object seq_cst, align 8
+  br label %2
+
+; <label>:2                                       ; preds = %1, %.thread1, %.thread
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z24pocl_atomic_load__globalPU8CLglobalVU7_Atomicm12memory_order12memory_scope(i64 addrspace(1)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %3 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  %1 = load atomic volatile i64, i64 addrspace(1)* %object monotonic, align 8
+  br label %5
+
+.thread1:                                         ; preds = %0
+  %2 = load atomic volatile i64, i64 addrspace(1)* %object acquire, align 8
+  br label %5
+
+; <label>:3                                       ; preds = %0
+  %4 = load atomic volatile i64, i64 addrspace(1)* %object seq_cst, align 8
+  br label %5
+
+; <label>:5                                       ; preds = %3, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %4, %3 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_exchange__globalPU8CLglobalVU7_Atomicmm12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xchg i64 addrspace(1)* %object, i64 %desired monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xchg i64 addrspace(1)* %object, i64 %desired acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xchg i64 addrspace(1)* %object, i64 %desired release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xchg i64 addrspace(1)* %object, i64 %desired acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xchg i64 addrspace(1)* %object, i64 %desired seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z43pocl_atomic_compare_exchange_strong__globalPU8CLglobalVU7_AtomicmPmm12memory_orderS3_12memory_scope(i64 addrspace(1)* %object, i64* nocapture %expected, i64 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i64, i64* %expected, align 8
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i64, i64* %expected, align 8
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i64, i64* %expected, align 8
+  %30 = cmpxchg volatile i64 addrspace(1)* %object, i64 %29, i64 %desired monotonic monotonic
+  %31 = extractvalue { i64, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i64, i1 } %30, 0
+  store i64 %33, i64* %expected, align 8
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg volatile i64 addrspace(1)* %object, i64 %22, i64 %desired acquire monotonic
+  %38 = extractvalue { i64, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg volatile i64 addrspace(1)* %object, i64 %22, i64 %desired acquire acquire
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i64, i1 } %37, 0
+  store i64 %43, i64* %expected, align 8
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i64, i1 } %40, 0
+  store i64 %47, i64* %expected, align 8
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i64, i64* %expected, align 8
+  %52 = cmpxchg volatile i64 addrspace(1)* %object, i64 %51, i64 %desired release monotonic
+  %53 = extractvalue { i64, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i64, i1 } %52, 0
+  store i64 %55, i64* %expected, align 8
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg volatile i64 addrspace(1)* %object, i64 %24, i64 %desired acq_rel monotonic
+  %60 = extractvalue { i64, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg volatile i64 addrspace(1)* %object, i64 %24, i64 %desired acq_rel acquire
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i64, i1 } %59, 0
+  store i64 %65, i64* %expected, align 8
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i64, i1 } %62, 0
+  store i64 %69, i64* %expected, align 8
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i64, i64* %expected, align 8
+  %74 = cmpxchg volatile i64 addrspace(1)* %object, i64 %73, i64 %desired seq_cst monotonic
+  %75 = extractvalue { i64, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i64, i64* %expected, align 8
+  %78 = cmpxchg volatile i64 addrspace(1)* %object, i64 %77, i64 %desired seq_cst acquire
+  %79 = extractvalue { i64, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i64, i64* %expected, align 8
+  %82 = cmpxchg volatile i64 addrspace(1)* %object, i64 %81, i64 %desired seq_cst seq_cst
+  %83 = extractvalue { i64, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i64, i1 } %74, 0
+  store i64 %85, i64* %expected, align 8
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i64, i1 } %78, 0
+  store i64 %89, i64* %expected, align 8
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i64, i1 } %82, 0
+  store i64 %93, i64* %expected, align 8
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z41pocl_atomic_compare_exchange_weak__globalPU8CLglobalVU7_AtomicmPmm12memory_orderS3_12memory_scope(i64 addrspace(1)* %object, i64* nocapture %expected, i64 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i64, i64* %expected, align 8
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i64, i64* %expected, align 8
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i64, i64* %expected, align 8
+  %30 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %29, i64 %desired monotonic monotonic
+  %31 = extractvalue { i64, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i64, i1 } %30, 0
+  store i64 %33, i64* %expected, align 8
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %22, i64 %desired acquire monotonic
+  %38 = extractvalue { i64, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %22, i64 %desired acquire acquire
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i64, i1 } %37, 0
+  store i64 %43, i64* %expected, align 8
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i64, i1 } %40, 0
+  store i64 %47, i64* %expected, align 8
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i64, i64* %expected, align 8
+  %52 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %51, i64 %desired release monotonic
+  %53 = extractvalue { i64, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i64, i1 } %52, 0
+  store i64 %55, i64* %expected, align 8
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %24, i64 %desired acq_rel monotonic
+  %60 = extractvalue { i64, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %24, i64 %desired acq_rel acquire
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i64, i1 } %59, 0
+  store i64 %65, i64* %expected, align 8
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i64, i1 } %62, 0
+  store i64 %69, i64* %expected, align 8
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i64, i64* %expected, align 8
+  %74 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %73, i64 %desired seq_cst monotonic
+  %75 = extractvalue { i64, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i64, i64* %expected, align 8
+  %78 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %77, i64 %desired seq_cst acquire
+  %79 = extractvalue { i64, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i64, i64* %expected, align 8
+  %82 = cmpxchg weak volatile i64 addrspace(1)* %object, i64 %81, i64 %desired seq_cst seq_cst
+  %83 = extractvalue { i64, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i64, i1 } %74, 0
+  store i64 %85, i64* %expected, align 8
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i64, i1 } %78, 0
+  store i64 %89, i64* %expected, align 8
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i64, i1 } %82, 0
+  store i64 %93, i64* %expected, align 8
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_add__globalPU8CLglobalVU7_Atomicmm12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile add i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile add i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile add i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile add i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile add i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_sub__globalPU8CLglobalVU7_Atomicmm12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile sub i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile sub i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile sub i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile sub i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile sub i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_or__globalPU8CLglobalVU7_Atomicmm12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile or i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile or i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile or i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile or i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile or i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_xor__globalPU8CLglobalVU7_Atomicmm12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xor i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xor i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xor i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xor i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xor i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_and__globalPU8CLglobalVU7_Atomicmm12memory_order12memory_scope(i64 addrspace(1)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile and i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile and i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile and i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile and i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile and i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: noreturn nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_min__globalPU8CLglobalVU7_Atomicmm12memory_order12memory_scope(i64 addrspace(1)* nocapture readnone %object, i64 %operand, i32 %order, i32 %scope) #1 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile umin i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile umin i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile umin i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile umin i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile umin i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: noreturn nounwind uwtable
+define i64 @_Z29pocl_atomic_fetch_max__globalPU8CLglobalVU7_Atomicmm12memory_order12memory_scope(i64 addrspace(1)* nocapture readnone %object, i64 %operand, i32 %order, i32 %scope) #1 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile umax i64 addrspace(1)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile umax i64 addrspace(1)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile umax i64 addrspace(1)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile umax i64 addrspace(1)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile umax i64 addrspace(1)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z25pocl_atomic_store__globalPU8CLglobalVU7_Atomicdd12memory_order12memory_scope(double addrspace(1)* nocapture %object, double %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %5 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+  ]
+
+.thread1:                                         ; preds = %0
+  %1 = bitcast double %desired to i64
+  %2 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  store atomic volatile i64 %1, i64 addrspace(1)* %2 release, align 8
+  br label %13
+
+.thread:                                          ; preds = %0, %0
+  %3 = bitcast double %desired to i64
+  %4 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  br label %9
+
+; <label>:5                                       ; preds = %0
+  %6 = icmp eq i32 %order, 3
+  %7 = bitcast double %desired to i64
+  %8 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  br i1 %6, label %9, label %12
+
+; <label>:9                                       ; preds = %5, %.thread
+  %10 = phi i64 addrspace(1)* [ %4, %.thread ], [ %8, %5 ]
+  %11 = phi i64 [ %3, %.thread ], [ %7, %5 ]
+  store atomic volatile i64 %11, i64 addrspace(1)* %10 monotonic, align 8
+  br label %13
+
+; <label>:12                                      ; preds = %5
+  store atomic volatile i64 %7, i64 addrspace(1)* %8 seq_cst, align 8
+  br label %13
+
+; <label>:13                                      ; preds = %12, %.thread1, %9
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define double @_Z24pocl_atomic_load__globalPU8CLglobalVU7_Atomicd12memory_order12memory_scope(double addrspace(1)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %4 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+  ]
+
+.thread1:                                         ; preds = %0
+  %1 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  %2 = load atomic volatile i64, i64 addrspace(1)* %1 acquire, align 8
+  br label %12
+
+.thread:                                          ; preds = %0, %0
+  %3 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  br label %7
+
+; <label>:4                                       ; preds = %0
+  %5 = icmp eq i32 %order, 3
+  %6 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  br i1 %5, label %7, label %10
+
+; <label>:7                                       ; preds = %4, %.thread
+  %8 = phi i64 addrspace(1)* [ %3, %.thread ], [ %6, %4 ]
+  %9 = load atomic volatile i64, i64 addrspace(1)* %8 monotonic, align 8
+  br label %12
+
+; <label>:10                                      ; preds = %4
+  %11 = load atomic volatile i64, i64 addrspace(1)* %6 seq_cst, align 8
+  br label %12
+
+; <label>:12                                      ; preds = %10, %.thread1, %7
+  %.sroa.0.0 = phi i64 [ %9, %7 ], [ %11, %10 ], [ %2, %.thread1 ]
+  %13 = bitcast i64 %.sroa.0.0 to double
+  ret double %13
+}
+
+; Function Attrs: nounwind uwtable
+define double @_Z28pocl_atomic_exchange__globalPU8CLglobalVU7_Atomicdd12memory_order12memory_scope(double addrspace(1)* %object, double %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %10 [
+    i32 0, label %.thread
+    i32 1, label %.thread2
+    i32 2, label %.thread3
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = bitcast double %desired to i64
+  %2 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  %3 = atomicrmw volatile xchg i64 addrspace(1)* %2, i64 %1 monotonic
+  br label %18
+
+.thread2:                                         ; preds = %0
+  %4 = bitcast double %desired to i64
+  %5 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  %6 = atomicrmw volatile xchg i64 addrspace(1)* %5, i64 %4 acquire
+  br label %18
+
+.thread3:                                         ; preds = %0
+  %7 = bitcast double %desired to i64
+  %8 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  %9 = atomicrmw volatile xchg i64 addrspace(1)* %8, i64 %7 release
+  br label %18
+
+; <label>:10                                      ; preds = %0
+  %11 = icmp eq i32 %order, 3
+  %12 = bitcast double %desired to i64
+  %13 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  br i1 %11, label %14, label %16
+
+; <label>:14                                      ; preds = %10
+  %15 = atomicrmw volatile xchg i64 addrspace(1)* %13, i64 %12 acq_rel
+  br label %18
+
+; <label>:16                                      ; preds = %10
+  %17 = atomicrmw volatile xchg i64 addrspace(1)* %13, i64 %12 seq_cst
+  br label %18
+
+; <label>:18                                      ; preds = %16, %14, %.thread3, %.thread2, %.thread
+  %.sroa.0.0 = phi i64 [ %3, %.thread ], [ %17, %16 ], [ %15, %14 ], [ %9, %.thread3 ], [ %6, %.thread2 ]
+  %19 = bitcast i64 %.sroa.0.0 to double
+  ret double %19
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z43pocl_atomic_compare_exchange_strong__globalPU8CLglobalVU7_AtomicdPdd12memory_orderS3_12memory_scope(double addrspace(1)* %object, double* nocapture %expected, double %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = bitcast double %desired to i64
+  %12 = icmp eq i32 %failure, 0
+  br i1 %12, label %20, label %13
+
+; <label>:13                                      ; preds = %9
+  %14 = icmp eq i32 %failure, 1
+  br i1 %14, label %20, label %15
+
+; <label>:15                                      ; preds = %13
+  %16 = icmp eq i32 %failure, 2
+  br i1 %16, label %20, label %17
+
+; <label>:17                                      ; preds = %15
+  %18 = icmp eq i32 %failure, 3
+  %19 = select i1 %18, i32 4, i32 5
+  br label %20
+
+; <label>:20                                      ; preds = %13, %15, %17, %9
+  %21 = phi i32 [ 0, %9 ], [ 2, %13 ], [ %19, %17 ], [ 3, %15 ]
+  %22 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  %23 = bitcast double* %expected to i64*
+  switch i32 %10, label %31 [
+    i32 1, label %24
+    i32 2, label %24
+    i32 3, label %53
+    i32 4, label %26
+    i32 5, label %28
+  ]
+
+; <label>:24                                      ; preds = %20, %20
+  %.off = add nsw i32 %21, -1
+  %switch = icmp ult i32 %.off, 2
+  %25 = load i64, i64* %23, align 8
+  br i1 %switch, label %42, label %39
+
+; <label>:26                                      ; preds = %20
+  %.off1 = add nsw i32 %21, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %27 = load i64, i64* %23, align 8
+  br i1 %switch2, label %64, label %61
+
+; <label>:28                                      ; preds = %20
+  switch i32 %21, label %75 [
+    i32 1, label %79
+    i32 2, label %79
+    i32 5, label %83
+  ]
+
+; <label>:29                                      ; preds = %89, %93, %97, %69, %73, %47, %51, %59, %37
+  %.0 = phi i8 [ %38, %37 ], [ %90, %89 ], [ %98, %97 ], [ %94, %93 ], [ %74, %73 ], [ %70, %69 ], [ %60, %59 ], [ %52, %51 ], [ %48, %47 ]
+  %30 = icmp ne i8 %.0, 0
+  ret i1 %30
+
+; <label>:31                                      ; preds = %20
+  %32 = load i64, i64* %23, align 8
+  %33 = cmpxchg volatile i64 addrspace(1)* %22, i64 %32, i64 %11 monotonic monotonic
+  %34 = extractvalue { i64, i1 } %33, 1
+  br i1 %34, label %37, label %35
+
+; <label>:35                                      ; preds = %31
+  %36 = extractvalue { i64, i1 } %33, 0
+  store i64 %36, i64* %23, align 8
+  br label %37
+
+; <label>:37                                      ; preds = %35, %31
+  %38 = zext i1 %34 to i8
+  br label %29
+
+; <label>:39                                      ; preds = %24
+  %40 = cmpxchg volatile i64 addrspace(1)* %22, i64 %25, i64 %11 acquire monotonic
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %47, label %45
+
+; <label>:42                                      ; preds = %24
+  %43 = cmpxchg volatile i64 addrspace(1)* %22, i64 %25, i64 %11 acquire acquire
+  %44 = extractvalue { i64, i1 } %43, 1
+  br i1 %44, label %51, label %49
+
+; <label>:45                                      ; preds = %39
+  %46 = extractvalue { i64, i1 } %40, 0
+  store i64 %46, i64* %23, align 8
+  br label %47
+
+; <label>:47                                      ; preds = %45, %39
+  %48 = zext i1 %41 to i8
+  br label %29
+
+; <label>:49                                      ; preds = %42
+  %50 = extractvalue { i64, i1 } %43, 0
+  store i64 %50, i64* %23, align 8
+  br label %51
+
+; <label>:51                                      ; preds = %49, %42
+  %52 = zext i1 %44 to i8
+  br label %29
+
+; <label>:53                                      ; preds = %20
+  %54 = load i64, i64* %23, align 8
+  %55 = cmpxchg volatile i64 addrspace(1)* %22, i64 %54, i64 %11 release monotonic
+  %56 = extractvalue { i64, i1 } %55, 1
+  br i1 %56, label %59, label %57
+
+; <label>:57                                      ; preds = %53
+  %58 = extractvalue { i64, i1 } %55, 0
+  store i64 %58, i64* %23, align 8
+  br label %59
+
+; <label>:59                                      ; preds = %57, %53
+  %60 = zext i1 %56 to i8
+  br label %29
+
+; <label>:61                                      ; preds = %26
+  %62 = cmpxchg volatile i64 addrspace(1)* %22, i64 %27, i64 %11 acq_rel monotonic
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %69, label %67
+
+; <label>:64                                      ; preds = %26
+  %65 = cmpxchg volatile i64 addrspace(1)* %22, i64 %27, i64 %11 acq_rel acquire
+  %66 = extractvalue { i64, i1 } %65, 1
+  br i1 %66, label %73, label %71
+
+; <label>:67                                      ; preds = %61
+  %68 = extractvalue { i64, i1 } %62, 0
+  store i64 %68, i64* %23, align 8
+  br label %69
+
+; <label>:69                                      ; preds = %67, %61
+  %70 = zext i1 %63 to i8
+  br label %29
+
+; <label>:71                                      ; preds = %64
+  %72 = extractvalue { i64, i1 } %65, 0
+  store i64 %72, i64* %23, align 8
+  br label %73
+
+; <label>:73                                      ; preds = %71, %64
+  %74 = zext i1 %66 to i8
+  br label %29
+
+; <label>:75                                      ; preds = %28
+  %76 = load i64, i64* %23, align 8
+  %77 = cmpxchg volatile i64 addrspace(1)* %22, i64 %76, i64 %11 seq_cst monotonic
+  %78 = extractvalue { i64, i1 } %77, 1
+  br i1 %78, label %89, label %87
+
+; <label>:79                                      ; preds = %28, %28
+  %80 = load i64, i64* %23, align 8
+  %81 = cmpxchg volatile i64 addrspace(1)* %22, i64 %80, i64 %11 seq_cst acquire
+  %82 = extractvalue { i64, i1 } %81, 1
+  br i1 %82, label %93, label %91
+
+; <label>:83                                      ; preds = %28
+  %84 = load i64, i64* %23, align 8
+  %85 = cmpxchg volatile i64 addrspace(1)* %22, i64 %84, i64 %11 seq_cst seq_cst
+  %86 = extractvalue { i64, i1 } %85, 1
+  br i1 %86, label %97, label %95
+
+; <label>:87                                      ; preds = %75
+  %88 = extractvalue { i64, i1 } %77, 0
+  store i64 %88, i64* %23, align 8
+  br label %89
+
+; <label>:89                                      ; preds = %87, %75
+  %90 = zext i1 %78 to i8
+  br label %29
+
+; <label>:91                                      ; preds = %79
+  %92 = extractvalue { i64, i1 } %81, 0
+  store i64 %92, i64* %23, align 8
+  br label %93
+
+; <label>:93                                      ; preds = %91, %79
+  %94 = zext i1 %82 to i8
+  br label %29
+
+; <label>:95                                      ; preds = %83
+  %96 = extractvalue { i64, i1 } %85, 0
+  store i64 %96, i64* %23, align 8
+  br label %97
+
+; <label>:97                                      ; preds = %95, %83
+  %98 = zext i1 %86 to i8
+  br label %29
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z41pocl_atomic_compare_exchange_weak__globalPU8CLglobalVU7_AtomicdPdd12memory_orderS3_12memory_scope(double addrspace(1)* %object, double* nocapture %expected, double %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = bitcast double %desired to i64
+  %12 = icmp eq i32 %failure, 0
+  br i1 %12, label %20, label %13
+
+; <label>:13                                      ; preds = %9
+  %14 = icmp eq i32 %failure, 1
+  br i1 %14, label %20, label %15
+
+; <label>:15                                      ; preds = %13
+  %16 = icmp eq i32 %failure, 2
+  br i1 %16, label %20, label %17
+
+; <label>:17                                      ; preds = %15
+  %18 = icmp eq i32 %failure, 3
+  %19 = select i1 %18, i32 4, i32 5
+  br label %20
+
+; <label>:20                                      ; preds = %13, %15, %17, %9
+  %21 = phi i32 [ 0, %9 ], [ 2, %13 ], [ %19, %17 ], [ 3, %15 ]
+  %22 = bitcast double addrspace(1)* %object to i64 addrspace(1)*
+  %23 = bitcast double* %expected to i64*
+  switch i32 %10, label %31 [
+    i32 1, label %24
+    i32 2, label %24
+    i32 3, label %53
+    i32 4, label %26
+    i32 5, label %28
+  ]
+
+; <label>:24                                      ; preds = %20, %20
+  %.off = add nsw i32 %21, -1
+  %switch = icmp ult i32 %.off, 2
+  %25 = load i64, i64* %23, align 8
+  br i1 %switch, label %42, label %39
+
+; <label>:26                                      ; preds = %20
+  %.off1 = add nsw i32 %21, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %27 = load i64, i64* %23, align 8
+  br i1 %switch2, label %64, label %61
+
+; <label>:28                                      ; preds = %20
+  switch i32 %21, label %75 [
+    i32 1, label %79
+    i32 2, label %79
+    i32 5, label %83
+  ]
+
+; <label>:29                                      ; preds = %89, %93, %97, %69, %73, %47, %51, %59, %37
+  %.0 = phi i8 [ %38, %37 ], [ %90, %89 ], [ %98, %97 ], [ %94, %93 ], [ %74, %73 ], [ %70, %69 ], [ %60, %59 ], [ %52, %51 ], [ %48, %47 ]
+  %30 = icmp ne i8 %.0, 0
+  ret i1 %30
+
+; <label>:31                                      ; preds = %20
+  %32 = load i64, i64* %23, align 8
+  %33 = cmpxchg weak volatile i64 addrspace(1)* %22, i64 %32, i64 %11 monotonic monotonic
+  %34 = extractvalue { i64, i1 } %33, 1
+  br i1 %34, label %37, label %35
+
+; <label>:35                                      ; preds = %31
+  %36 = extractvalue { i64, i1 } %33, 0
+  store i64 %36, i64* %23, align 8
+  br label %37
+
+; <label>:37                                      ; preds = %35, %31
+  %38 = zext i1 %34 to i8
+  br label %29
+
+; <label>:39                                      ; preds = %24
+  %40 = cmpxchg weak volatile i64 addrspace(1)* %22, i64 %25, i64 %11 acquire monotonic
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %47, label %45
+
+; <label>:42                                      ; preds = %24
+  %43 = cmpxchg weak volatile i64 addrspace(1)* %22, i64 %25, i64 %11 acquire acquire
+  %44 = extractvalue { i64, i1 } %43, 1
+  br i1 %44, label %51, label %49
+
+; <label>:45                                      ; preds = %39
+  %46 = extractvalue { i64, i1 } %40, 0
+  store i64 %46, i64* %23, align 8
+  br label %47
+
+; <label>:47                                      ; preds = %45, %39
+  %48 = zext i1 %41 to i8
+  br label %29
+
+; <label>:49                                      ; preds = %42
+  %50 = extractvalue { i64, i1 } %43, 0
+  store i64 %50, i64* %23, align 8
+  br label %51
+
+; <label>:51                                      ; preds = %49, %42
+  %52 = zext i1 %44 to i8
+  br label %29
+
+; <label>:53                                      ; preds = %20
+  %54 = load i64, i64* %23, align 8
+  %55 = cmpxchg weak volatile i64 addrspace(1)* %22, i64 %54, i64 %11 release monotonic
+  %56 = extractvalue { i64, i1 } %55, 1
+  br i1 %56, label %59, label %57
+
+; <label>:57                                      ; preds = %53
+  %58 = extractvalue { i64, i1 } %55, 0
+  store i64 %58, i64* %23, align 8
+  br label %59
+
+; <label>:59                                      ; preds = %57, %53
+  %60 = zext i1 %56 to i8
+  br label %29
+
+; <label>:61                                      ; preds = %26
+  %62 = cmpxchg weak volatile i64 addrspace(1)* %22, i64 %27, i64 %11 acq_rel monotonic
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %69, label %67
+
+; <label>:64                                      ; preds = %26
+  %65 = cmpxchg weak volatile i64 addrspace(1)* %22, i64 %27, i64 %11 acq_rel acquire
+  %66 = extractvalue { i64, i1 } %65, 1
+  br i1 %66, label %73, label %71
+
+; <label>:67                                      ; preds = %61
+  %68 = extractvalue { i64, i1 } %62, 0
+  store i64 %68, i64* %23, align 8
+  br label %69
+
+; <label>:69                                      ; preds = %67, %61
+  %70 = zext i1 %63 to i8
+  br label %29
+
+; <label>:71                                      ; preds = %64
+  %72 = extractvalue { i64, i1 } %65, 0
+  store i64 %72, i64* %23, align 8
+  br label %73
+
+; <label>:73                                      ; preds = %71, %64
+  %74 = zext i1 %66 to i8
+  br label %29
+
+; <label>:75                                      ; preds = %28
+  %76 = load i64, i64* %23, align 8
+  %77 = cmpxchg weak volatile i64 addrspace(1)* %22, i64 %76, i64 %11 seq_cst monotonic
+  %78 = extractvalue { i64, i1 } %77, 1
+  br i1 %78, label %89, label %87
+
+; <label>:79                                      ; preds = %28, %28
+  %80 = load i64, i64* %23, align 8
+  %81 = cmpxchg weak volatile i64 addrspace(1)* %22, i64 %80, i64 %11 seq_cst acquire
+  %82 = extractvalue { i64, i1 } %81, 1
+  br i1 %82, label %93, label %91
+
+; <label>:83                                      ; preds = %28
+  %84 = load i64, i64* %23, align 8
+  %85 = cmpxchg weak volatile i64 addrspace(1)* %22, i64 %84, i64 %11 seq_cst seq_cst
+  %86 = extractvalue { i64, i1 } %85, 1
+  br i1 %86, label %97, label %95
+
+; <label>:87                                      ; preds = %75
+  %88 = extractvalue { i64, i1 } %77, 0
+  store i64 %88, i64* %23, align 8
+  br label %89
+
+; <label>:89                                      ; preds = %87, %75
+  %90 = zext i1 %78 to i8
+  br label %29
+
+; <label>:91                                      ; preds = %79
+  %92 = extractvalue { i64, i1 } %81, 0
+  store i64 %92, i64* %23, align 8
+  br label %93
+
+; <label>:93                                      ; preds = %91, %79
+  %94 = zext i1 %82 to i8
+  br label %29
+
+; <label>:95                                      ; preds = %83
+  %96 = extractvalue { i64, i1 } %85, 0
+  store i64 %96, i64* %23, align 8
+  br label %97
+
+; <label>:97                                      ; preds = %95, %83
+  %98 = zext i1 %86 to i8
+  br label %29
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z36pocl_atomic_flag_test_and_set__localPVU7CLlocalU7_Atomici12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 1 monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 1 acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 1 release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 1 acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 1 seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  %9 = icmp ne i32 %.0, 0
+  ret i1 %9
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z29pocl_atomic_flag_clear__localPVU7CLlocalU7_Atomici12memory_order12memory_scope(i32 addrspace(2)* nocapture %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %1 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  store atomic volatile i32 0, i32 addrspace(2)* %object monotonic, align 4
+  br label %2
+
+.thread1:                                         ; preds = %0
+  store atomic volatile i32 0, i32 addrspace(2)* %object release, align 4
+  br label %2
+
+; <label>:1                                       ; preds = %0
+  store atomic volatile i32 0, i32 addrspace(2)* %object seq_cst, align 4
+  br label %2
+
+; <label>:2                                       ; preds = %1, %.thread1, %.thread
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z24pocl_atomic_store__localPVU7CLlocalU7_Atomicii12memory_order12memory_scope(i32 addrspace(2)* nocapture %object, i32 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %1 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  store atomic volatile i32 %desired, i32 addrspace(2)* %object monotonic, align 4
+  br label %2
+
+.thread1:                                         ; preds = %0
+  store atomic volatile i32 %desired, i32 addrspace(2)* %object release, align 4
+  br label %2
+
+; <label>:1                                       ; preds = %0
+  store atomic volatile i32 %desired, i32 addrspace(2)* %object seq_cst, align 4
+  br label %2
+
+; <label>:2                                       ; preds = %1, %.thread1, %.thread
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z23pocl_atomic_load__localPVU7CLlocalU7_Atomici12memory_order12memory_scope(i32 addrspace(2)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %3 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  %1 = load atomic volatile i32, i32 addrspace(2)* %object monotonic, align 4
+  br label %5
+
+.thread1:                                         ; preds = %0
+  %2 = load atomic volatile i32, i32 addrspace(2)* %object acquire, align 4
+  br label %5
+
+; <label>:3                                       ; preds = %0
+  %4 = load atomic volatile i32, i32 addrspace(2)* %object seq_cst, align 4
+  br label %5
+
+; <label>:5                                       ; preds = %3, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %4, %3 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z27pocl_atomic_exchange__localPVU7CLlocalU7_Atomicii12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 %desired monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 %desired acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 %desired release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 %desired acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 %desired seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z42pocl_atomic_compare_exchange_strong__localPVU7CLlocalU7_AtomiciPii12memory_orderS3_12memory_scope(i32 addrspace(2)* %object, i32* nocapture %expected, i32 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i32, i32* %expected, align 4
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i32, i32* %expected, align 4
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i32, i32* %expected, align 4
+  %30 = cmpxchg volatile i32 addrspace(2)* %object, i32 %29, i32 %desired monotonic monotonic
+  %31 = extractvalue { i32, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i32, i1 } %30, 0
+  store i32 %33, i32* %expected, align 4
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg volatile i32 addrspace(2)* %object, i32 %22, i32 %desired acquire monotonic
+  %38 = extractvalue { i32, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg volatile i32 addrspace(2)* %object, i32 %22, i32 %desired acquire acquire
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i32, i1 } %37, 0
+  store i32 %43, i32* %expected, align 4
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i32, i1 } %40, 0
+  store i32 %47, i32* %expected, align 4
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i32, i32* %expected, align 4
+  %52 = cmpxchg volatile i32 addrspace(2)* %object, i32 %51, i32 %desired release monotonic
+  %53 = extractvalue { i32, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i32, i1 } %52, 0
+  store i32 %55, i32* %expected, align 4
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg volatile i32 addrspace(2)* %object, i32 %24, i32 %desired acq_rel monotonic
+  %60 = extractvalue { i32, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg volatile i32 addrspace(2)* %object, i32 %24, i32 %desired acq_rel acquire
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i32, i1 } %59, 0
+  store i32 %65, i32* %expected, align 4
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i32, i1 } %62, 0
+  store i32 %69, i32* %expected, align 4
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i32, i32* %expected, align 4
+  %74 = cmpxchg volatile i32 addrspace(2)* %object, i32 %73, i32 %desired seq_cst monotonic
+  %75 = extractvalue { i32, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i32, i32* %expected, align 4
+  %78 = cmpxchg volatile i32 addrspace(2)* %object, i32 %77, i32 %desired seq_cst acquire
+  %79 = extractvalue { i32, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i32, i32* %expected, align 4
+  %82 = cmpxchg volatile i32 addrspace(2)* %object, i32 %81, i32 %desired seq_cst seq_cst
+  %83 = extractvalue { i32, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i32, i1 } %74, 0
+  store i32 %85, i32* %expected, align 4
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i32, i1 } %78, 0
+  store i32 %89, i32* %expected, align 4
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i32, i1 } %82, 0
+  store i32 %93, i32* %expected, align 4
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z40pocl_atomic_compare_exchange_weak__localPVU7CLlocalU7_AtomiciPii12memory_orderS3_12memory_scope(i32 addrspace(2)* %object, i32* nocapture %expected, i32 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i32, i32* %expected, align 4
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i32, i32* %expected, align 4
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i32, i32* %expected, align 4
+  %30 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %29, i32 %desired monotonic monotonic
+  %31 = extractvalue { i32, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i32, i1 } %30, 0
+  store i32 %33, i32* %expected, align 4
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %22, i32 %desired acquire monotonic
+  %38 = extractvalue { i32, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %22, i32 %desired acquire acquire
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i32, i1 } %37, 0
+  store i32 %43, i32* %expected, align 4
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i32, i1 } %40, 0
+  store i32 %47, i32* %expected, align 4
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i32, i32* %expected, align 4
+  %52 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %51, i32 %desired release monotonic
+  %53 = extractvalue { i32, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i32, i1 } %52, 0
+  store i32 %55, i32* %expected, align 4
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %24, i32 %desired acq_rel monotonic
+  %60 = extractvalue { i32, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %24, i32 %desired acq_rel acquire
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i32, i1 } %59, 0
+  store i32 %65, i32* %expected, align 4
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i32, i1 } %62, 0
+  store i32 %69, i32* %expected, align 4
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i32, i32* %expected, align 4
+  %74 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %73, i32 %desired seq_cst monotonic
+  %75 = extractvalue { i32, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i32, i32* %expected, align 4
+  %78 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %77, i32 %desired seq_cst acquire
+  %79 = extractvalue { i32, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i32, i32* %expected, align 4
+  %82 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %81, i32 %desired seq_cst seq_cst
+  %83 = extractvalue { i32, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i32, i1 } %74, 0
+  store i32 %85, i32* %expected, align 4
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i32, i1 } %78, 0
+  store i32 %89, i32* %expected, align 4
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i32, i1 } %82, 0
+  store i32 %93, i32* %expected, align 4
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_add__localPVU7CLlocalU7_Atomicii12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile add i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile add i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile add i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile add i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile add i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_sub__localPVU7CLlocalU7_Atomicii12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile sub i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile sub i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile sub i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile sub i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile sub i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z27pocl_atomic_fetch_or__localPVU7CLlocalU7_Atomicii12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile or i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile or i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile or i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile or i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile or i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_xor__localPVU7CLlocalU7_Atomicii12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xor i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xor i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xor i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xor i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xor i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_and__localPVU7CLlocalU7_Atomicii12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile and i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile and i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile and i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile and i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile and i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_min__localPVU7CLlocalU7_Atomicii12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile min i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile min i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile min i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile min i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile min i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_max__localPVU7CLlocalU7_Atomicii12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile max i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile max i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile max i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile max i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile max i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z24pocl_atomic_store__localPVU7CLlocalU7_Atomicjj12memory_order12memory_scope(i32 addrspace(2)* nocapture %object, i32 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %1 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  store atomic volatile i32 %desired, i32 addrspace(2)* %object monotonic, align 4
+  br label %2
+
+.thread1:                                         ; preds = %0
+  store atomic volatile i32 %desired, i32 addrspace(2)* %object release, align 4
+  br label %2
+
+; <label>:1                                       ; preds = %0
+  store atomic volatile i32 %desired, i32 addrspace(2)* %object seq_cst, align 4
+  br label %2
+
+; <label>:2                                       ; preds = %1, %.thread1, %.thread
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z23pocl_atomic_load__localPVU7CLlocalU7_Atomicj12memory_order12memory_scope(i32 addrspace(2)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %3 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  %1 = load atomic volatile i32, i32 addrspace(2)* %object monotonic, align 4
+  br label %5
+
+.thread1:                                         ; preds = %0
+  %2 = load atomic volatile i32, i32 addrspace(2)* %object acquire, align 4
+  br label %5
+
+; <label>:3                                       ; preds = %0
+  %4 = load atomic volatile i32, i32 addrspace(2)* %object seq_cst, align 4
+  br label %5
+
+; <label>:5                                       ; preds = %3, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %4, %3 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z27pocl_atomic_exchange__localPVU7CLlocalU7_Atomicjj12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 %desired monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 %desired acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 %desired release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 %desired acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xchg i32 addrspace(2)* %object, i32 %desired seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z42pocl_atomic_compare_exchange_strong__localPVU7CLlocalU7_AtomicjPjj12memory_orderS3_12memory_scope(i32 addrspace(2)* %object, i32* nocapture %expected, i32 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i32, i32* %expected, align 4
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i32, i32* %expected, align 4
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i32, i32* %expected, align 4
+  %30 = cmpxchg volatile i32 addrspace(2)* %object, i32 %29, i32 %desired monotonic monotonic
+  %31 = extractvalue { i32, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i32, i1 } %30, 0
+  store i32 %33, i32* %expected, align 4
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg volatile i32 addrspace(2)* %object, i32 %22, i32 %desired acquire monotonic
+  %38 = extractvalue { i32, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg volatile i32 addrspace(2)* %object, i32 %22, i32 %desired acquire acquire
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i32, i1 } %37, 0
+  store i32 %43, i32* %expected, align 4
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i32, i1 } %40, 0
+  store i32 %47, i32* %expected, align 4
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i32, i32* %expected, align 4
+  %52 = cmpxchg volatile i32 addrspace(2)* %object, i32 %51, i32 %desired release monotonic
+  %53 = extractvalue { i32, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i32, i1 } %52, 0
+  store i32 %55, i32* %expected, align 4
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg volatile i32 addrspace(2)* %object, i32 %24, i32 %desired acq_rel monotonic
+  %60 = extractvalue { i32, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg volatile i32 addrspace(2)* %object, i32 %24, i32 %desired acq_rel acquire
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i32, i1 } %59, 0
+  store i32 %65, i32* %expected, align 4
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i32, i1 } %62, 0
+  store i32 %69, i32* %expected, align 4
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i32, i32* %expected, align 4
+  %74 = cmpxchg volatile i32 addrspace(2)* %object, i32 %73, i32 %desired seq_cst monotonic
+  %75 = extractvalue { i32, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i32, i32* %expected, align 4
+  %78 = cmpxchg volatile i32 addrspace(2)* %object, i32 %77, i32 %desired seq_cst acquire
+  %79 = extractvalue { i32, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i32, i32* %expected, align 4
+  %82 = cmpxchg volatile i32 addrspace(2)* %object, i32 %81, i32 %desired seq_cst seq_cst
+  %83 = extractvalue { i32, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i32, i1 } %74, 0
+  store i32 %85, i32* %expected, align 4
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i32, i1 } %78, 0
+  store i32 %89, i32* %expected, align 4
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i32, i1 } %82, 0
+  store i32 %93, i32* %expected, align 4
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z40pocl_atomic_compare_exchange_weak__localPVU7CLlocalU7_AtomicjPjj12memory_orderS3_12memory_scope(i32 addrspace(2)* %object, i32* nocapture %expected, i32 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i32, i32* %expected, align 4
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i32, i32* %expected, align 4
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i32, i32* %expected, align 4
+  %30 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %29, i32 %desired monotonic monotonic
+  %31 = extractvalue { i32, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i32, i1 } %30, 0
+  store i32 %33, i32* %expected, align 4
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %22, i32 %desired acquire monotonic
+  %38 = extractvalue { i32, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %22, i32 %desired acquire acquire
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i32, i1 } %37, 0
+  store i32 %43, i32* %expected, align 4
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i32, i1 } %40, 0
+  store i32 %47, i32* %expected, align 4
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i32, i32* %expected, align 4
+  %52 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %51, i32 %desired release monotonic
+  %53 = extractvalue { i32, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i32, i1 } %52, 0
+  store i32 %55, i32* %expected, align 4
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %24, i32 %desired acq_rel monotonic
+  %60 = extractvalue { i32, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %24, i32 %desired acq_rel acquire
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i32, i1 } %59, 0
+  store i32 %65, i32* %expected, align 4
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i32, i1 } %62, 0
+  store i32 %69, i32* %expected, align 4
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i32, i32* %expected, align 4
+  %74 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %73, i32 %desired seq_cst monotonic
+  %75 = extractvalue { i32, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i32, i32* %expected, align 4
+  %78 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %77, i32 %desired seq_cst acquire
+  %79 = extractvalue { i32, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i32, i32* %expected, align 4
+  %82 = cmpxchg weak volatile i32 addrspace(2)* %object, i32 %81, i32 %desired seq_cst seq_cst
+  %83 = extractvalue { i32, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i32, i1 } %74, 0
+  store i32 %85, i32* %expected, align 4
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i32, i1 } %78, 0
+  store i32 %89, i32* %expected, align 4
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i32, i1 } %82, 0
+  store i32 %93, i32* %expected, align 4
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_add__localPVU7CLlocalU7_Atomicjj12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile add i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile add i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile add i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile add i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile add i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_sub__localPVU7CLlocalU7_Atomicjj12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile sub i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile sub i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile sub i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile sub i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile sub i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z27pocl_atomic_fetch_or__localPVU7CLlocalU7_Atomicjj12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile or i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile or i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile or i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile or i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile or i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_xor__localPVU7CLlocalU7_Atomicjj12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xor i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xor i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xor i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xor i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xor i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_and__localPVU7CLlocalU7_Atomicjj12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile and i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile and i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile and i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile and i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile and i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_min__localPVU7CLlocalU7_Atomicjj12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile umin i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile umin i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile umin i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile umin i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile umin i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @_Z28pocl_atomic_fetch_max__localPVU7CLlocalU7_Atomicjj12memory_order12memory_scope(i32 addrspace(2)* %object, i32 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile umax i32 addrspace(2)* %object, i32 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile umax i32 addrspace(2)* %object, i32 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile umax i32 addrspace(2)* %object, i32 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile umax i32 addrspace(2)* %object, i32 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile umax i32 addrspace(2)* %object, i32 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i32 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i32 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z24pocl_atomic_store__localPVU7CLlocalU7_Atomicff12memory_order12memory_scope(float addrspace(2)* nocapture %object, float %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %5 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+  ]
+
+.thread1:                                         ; preds = %0
+  %1 = bitcast float %desired to i32
+  %2 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  store atomic volatile i32 %1, i32 addrspace(2)* %2 release, align 4
+  br label %13
+
+.thread:                                          ; preds = %0, %0
+  %3 = bitcast float %desired to i32
+  %4 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  br label %9
+
+; <label>:5                                       ; preds = %0
+  %6 = icmp eq i32 %order, 3
+  %7 = bitcast float %desired to i32
+  %8 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  br i1 %6, label %9, label %12
+
+; <label>:9                                       ; preds = %5, %.thread
+  %10 = phi i32 addrspace(2)* [ %4, %.thread ], [ %8, %5 ]
+  %11 = phi i32 [ %3, %.thread ], [ %7, %5 ]
+  store atomic volatile i32 %11, i32 addrspace(2)* %10 monotonic, align 4
+  br label %13
+
+; <label>:12                                      ; preds = %5
+  store atomic volatile i32 %7, i32 addrspace(2)* %8 seq_cst, align 4
+  br label %13
+
+; <label>:13                                      ; preds = %12, %.thread1, %9
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define float @_Z23pocl_atomic_load__localPVU7CLlocalU7_Atomicf12memory_order12memory_scope(float addrspace(2)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %4 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+  ]
+
+.thread1:                                         ; preds = %0
+  %1 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  %2 = load atomic volatile i32, i32 addrspace(2)* %1 acquire, align 4
+  br label %12
+
+.thread:                                          ; preds = %0, %0
+  %3 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  br label %7
+
+; <label>:4                                       ; preds = %0
+  %5 = icmp eq i32 %order, 3
+  %6 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  br i1 %5, label %7, label %10
+
+; <label>:7                                       ; preds = %4, %.thread
+  %8 = phi i32 addrspace(2)* [ %3, %.thread ], [ %6, %4 ]
+  %9 = load atomic volatile i32, i32 addrspace(2)* %8 monotonic, align 4
+  br label %12
+
+; <label>:10                                      ; preds = %4
+  %11 = load atomic volatile i32, i32 addrspace(2)* %6 seq_cst, align 4
+  br label %12
+
+; <label>:12                                      ; preds = %10, %.thread1, %7
+  %.sroa.0.0 = phi i32 [ %9, %7 ], [ %11, %10 ], [ %2, %.thread1 ]
+  %13 = bitcast i32 %.sroa.0.0 to float
+  ret float %13
+}
+
+; Function Attrs: nounwind uwtable
+define float @_Z27pocl_atomic_exchange__localPVU7CLlocalU7_Atomicff12memory_order12memory_scope(float addrspace(2)* %object, float %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %10 [
+    i32 0, label %.thread
+    i32 1, label %.thread2
+    i32 2, label %.thread3
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = bitcast float %desired to i32
+  %2 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  %3 = atomicrmw volatile xchg i32 addrspace(2)* %2, i32 %1 monotonic
+  br label %18
+
+.thread2:                                         ; preds = %0
+  %4 = bitcast float %desired to i32
+  %5 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  %6 = atomicrmw volatile xchg i32 addrspace(2)* %5, i32 %4 acquire
+  br label %18
+
+.thread3:                                         ; preds = %0
+  %7 = bitcast float %desired to i32
+  %8 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  %9 = atomicrmw volatile xchg i32 addrspace(2)* %8, i32 %7 release
+  br label %18
+
+; <label>:10                                      ; preds = %0
+  %11 = icmp eq i32 %order, 3
+  %12 = bitcast float %desired to i32
+  %13 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  br i1 %11, label %14, label %16
+
+; <label>:14                                      ; preds = %10
+  %15 = atomicrmw volatile xchg i32 addrspace(2)* %13, i32 %12 acq_rel
+  br label %18
+
+; <label>:16                                      ; preds = %10
+  %17 = atomicrmw volatile xchg i32 addrspace(2)* %13, i32 %12 seq_cst
+  br label %18
+
+; <label>:18                                      ; preds = %16, %14, %.thread3, %.thread2, %.thread
+  %.sroa.0.0 = phi i32 [ %3, %.thread ], [ %17, %16 ], [ %15, %14 ], [ %9, %.thread3 ], [ %6, %.thread2 ]
+  %19 = bitcast i32 %.sroa.0.0 to float
+  ret float %19
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z42pocl_atomic_compare_exchange_strong__localPVU7CLlocalU7_AtomicfPff12memory_orderS3_12memory_scope(float addrspace(2)* %object, float* nocapture %expected, float %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = bitcast float %desired to i32
+  %12 = icmp eq i32 %failure, 0
+  br i1 %12, label %20, label %13
+
+; <label>:13                                      ; preds = %9
+  %14 = icmp eq i32 %failure, 1
+  br i1 %14, label %20, label %15
+
+; <label>:15                                      ; preds = %13
+  %16 = icmp eq i32 %failure, 2
+  br i1 %16, label %20, label %17
+
+; <label>:17                                      ; preds = %15
+  %18 = icmp eq i32 %failure, 3
+  %19 = select i1 %18, i32 4, i32 5
+  br label %20
+
+; <label>:20                                      ; preds = %13, %15, %17, %9
+  %21 = phi i32 [ 0, %9 ], [ 2, %13 ], [ %19, %17 ], [ 3, %15 ]
+  %22 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  %23 = bitcast float* %expected to i32*
+  switch i32 %10, label %31 [
+    i32 1, label %24
+    i32 2, label %24
+    i32 3, label %53
+    i32 4, label %26
+    i32 5, label %28
+  ]
+
+; <label>:24                                      ; preds = %20, %20
+  %.off = add nsw i32 %21, -1
+  %switch = icmp ult i32 %.off, 2
+  %25 = load i32, i32* %23, align 4
+  br i1 %switch, label %42, label %39
+
+; <label>:26                                      ; preds = %20
+  %.off1 = add nsw i32 %21, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %27 = load i32, i32* %23, align 4
+  br i1 %switch2, label %64, label %61
+
+; <label>:28                                      ; preds = %20
+  switch i32 %21, label %75 [
+    i32 1, label %79
+    i32 2, label %79
+    i32 5, label %83
+  ]
+
+; <label>:29                                      ; preds = %89, %93, %97, %69, %73, %47, %51, %59, %37
+  %.0 = phi i8 [ %38, %37 ], [ %90, %89 ], [ %98, %97 ], [ %94, %93 ], [ %74, %73 ], [ %70, %69 ], [ %60, %59 ], [ %52, %51 ], [ %48, %47 ]
+  %30 = icmp ne i8 %.0, 0
+  ret i1 %30
+
+; <label>:31                                      ; preds = %20
+  %32 = load i32, i32* %23, align 4
+  %33 = cmpxchg volatile i32 addrspace(2)* %22, i32 %32, i32 %11 monotonic monotonic
+  %34 = extractvalue { i32, i1 } %33, 1
+  br i1 %34, label %37, label %35
+
+; <label>:35                                      ; preds = %31
+  %36 = extractvalue { i32, i1 } %33, 0
+  store i32 %36, i32* %23, align 4
+  br label %37
+
+; <label>:37                                      ; preds = %35, %31
+  %38 = zext i1 %34 to i8
+  br label %29
+
+; <label>:39                                      ; preds = %24
+  %40 = cmpxchg volatile i32 addrspace(2)* %22, i32 %25, i32 %11 acquire monotonic
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %47, label %45
+
+; <label>:42                                      ; preds = %24
+  %43 = cmpxchg volatile i32 addrspace(2)* %22, i32 %25, i32 %11 acquire acquire
+  %44 = extractvalue { i32, i1 } %43, 1
+  br i1 %44, label %51, label %49
+
+; <label>:45                                      ; preds = %39
+  %46 = extractvalue { i32, i1 } %40, 0
+  store i32 %46, i32* %23, align 4
+  br label %47
+
+; <label>:47                                      ; preds = %45, %39
+  %48 = zext i1 %41 to i8
+  br label %29
+
+; <label>:49                                      ; preds = %42
+  %50 = extractvalue { i32, i1 } %43, 0
+  store i32 %50, i32* %23, align 4
+  br label %51
+
+; <label>:51                                      ; preds = %49, %42
+  %52 = zext i1 %44 to i8
+  br label %29
+
+; <label>:53                                      ; preds = %20
+  %54 = load i32, i32* %23, align 4
+  %55 = cmpxchg volatile i32 addrspace(2)* %22, i32 %54, i32 %11 release monotonic
+  %56 = extractvalue { i32, i1 } %55, 1
+  br i1 %56, label %59, label %57
+
+; <label>:57                                      ; preds = %53
+  %58 = extractvalue { i32, i1 } %55, 0
+  store i32 %58, i32* %23, align 4
+  br label %59
+
+; <label>:59                                      ; preds = %57, %53
+  %60 = zext i1 %56 to i8
+  br label %29
+
+; <label>:61                                      ; preds = %26
+  %62 = cmpxchg volatile i32 addrspace(2)* %22, i32 %27, i32 %11 acq_rel monotonic
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %69, label %67
+
+; <label>:64                                      ; preds = %26
+  %65 = cmpxchg volatile i32 addrspace(2)* %22, i32 %27, i32 %11 acq_rel acquire
+  %66 = extractvalue { i32, i1 } %65, 1
+  br i1 %66, label %73, label %71
+
+; <label>:67                                      ; preds = %61
+  %68 = extractvalue { i32, i1 } %62, 0
+  store i32 %68, i32* %23, align 4
+  br label %69
+
+; <label>:69                                      ; preds = %67, %61
+  %70 = zext i1 %63 to i8
+  br label %29
+
+; <label>:71                                      ; preds = %64
+  %72 = extractvalue { i32, i1 } %65, 0
+  store i32 %72, i32* %23, align 4
+  br label %73
+
+; <label>:73                                      ; preds = %71, %64
+  %74 = zext i1 %66 to i8
+  br label %29
+
+; <label>:75                                      ; preds = %28
+  %76 = load i32, i32* %23, align 4
+  %77 = cmpxchg volatile i32 addrspace(2)* %22, i32 %76, i32 %11 seq_cst monotonic
+  %78 = extractvalue { i32, i1 } %77, 1
+  br i1 %78, label %89, label %87
+
+; <label>:79                                      ; preds = %28, %28
+  %80 = load i32, i32* %23, align 4
+  %81 = cmpxchg volatile i32 addrspace(2)* %22, i32 %80, i32 %11 seq_cst acquire
+  %82 = extractvalue { i32, i1 } %81, 1
+  br i1 %82, label %93, label %91
+
+; <label>:83                                      ; preds = %28
+  %84 = load i32, i32* %23, align 4
+  %85 = cmpxchg volatile i32 addrspace(2)* %22, i32 %84, i32 %11 seq_cst seq_cst
+  %86 = extractvalue { i32, i1 } %85, 1
+  br i1 %86, label %97, label %95
+
+; <label>:87                                      ; preds = %75
+  %88 = extractvalue { i32, i1 } %77, 0
+  store i32 %88, i32* %23, align 4
+  br label %89
+
+; <label>:89                                      ; preds = %87, %75
+  %90 = zext i1 %78 to i8
+  br label %29
+
+; <label>:91                                      ; preds = %79
+  %92 = extractvalue { i32, i1 } %81, 0
+  store i32 %92, i32* %23, align 4
+  br label %93
+
+; <label>:93                                      ; preds = %91, %79
+  %94 = zext i1 %82 to i8
+  br label %29
+
+; <label>:95                                      ; preds = %83
+  %96 = extractvalue { i32, i1 } %85, 0
+  store i32 %96, i32* %23, align 4
+  br label %97
+
+; <label>:97                                      ; preds = %95, %83
+  %98 = zext i1 %86 to i8
+  br label %29
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z40pocl_atomic_compare_exchange_weak__localPVU7CLlocalU7_AtomicfPff12memory_orderS3_12memory_scope(float addrspace(2)* %object, float* nocapture %expected, float %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = bitcast float %desired to i32
+  %12 = icmp eq i32 %failure, 0
+  br i1 %12, label %20, label %13
+
+; <label>:13                                      ; preds = %9
+  %14 = icmp eq i32 %failure, 1
+  br i1 %14, label %20, label %15
+
+; <label>:15                                      ; preds = %13
+  %16 = icmp eq i32 %failure, 2
+  br i1 %16, label %20, label %17
+
+; <label>:17                                      ; preds = %15
+  %18 = icmp eq i32 %failure, 3
+  %19 = select i1 %18, i32 4, i32 5
+  br label %20
+
+; <label>:20                                      ; preds = %13, %15, %17, %9
+  %21 = phi i32 [ 0, %9 ], [ 2, %13 ], [ %19, %17 ], [ 3, %15 ]
+  %22 = bitcast float addrspace(2)* %object to i32 addrspace(2)*
+  %23 = bitcast float* %expected to i32*
+  switch i32 %10, label %31 [
+    i32 1, label %24
+    i32 2, label %24
+    i32 3, label %53
+    i32 4, label %26
+    i32 5, label %28
+  ]
+
+; <label>:24                                      ; preds = %20, %20
+  %.off = add nsw i32 %21, -1
+  %switch = icmp ult i32 %.off, 2
+  %25 = load i32, i32* %23, align 4
+  br i1 %switch, label %42, label %39
+
+; <label>:26                                      ; preds = %20
+  %.off1 = add nsw i32 %21, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %27 = load i32, i32* %23, align 4
+  br i1 %switch2, label %64, label %61
+
+; <label>:28                                      ; preds = %20
+  switch i32 %21, label %75 [
+    i32 1, label %79
+    i32 2, label %79
+    i32 5, label %83
+  ]
+
+; <label>:29                                      ; preds = %89, %93, %97, %69, %73, %47, %51, %59, %37
+  %.0 = phi i8 [ %38, %37 ], [ %90, %89 ], [ %98, %97 ], [ %94, %93 ], [ %74, %73 ], [ %70, %69 ], [ %60, %59 ], [ %52, %51 ], [ %48, %47 ]
+  %30 = icmp ne i8 %.0, 0
+  ret i1 %30
+
+; <label>:31                                      ; preds = %20
+  %32 = load i32, i32* %23, align 4
+  %33 = cmpxchg weak volatile i32 addrspace(2)* %22, i32 %32, i32 %11 monotonic monotonic
+  %34 = extractvalue { i32, i1 } %33, 1
+  br i1 %34, label %37, label %35
+
+; <label>:35                                      ; preds = %31
+  %36 = extractvalue { i32, i1 } %33, 0
+  store i32 %36, i32* %23, align 4
+  br label %37
+
+; <label>:37                                      ; preds = %35, %31
+  %38 = zext i1 %34 to i8
+  br label %29
+
+; <label>:39                                      ; preds = %24
+  %40 = cmpxchg weak volatile i32 addrspace(2)* %22, i32 %25, i32 %11 acquire monotonic
+  %41 = extractvalue { i32, i1 } %40, 1
+  br i1 %41, label %47, label %45
+
+; <label>:42                                      ; preds = %24
+  %43 = cmpxchg weak volatile i32 addrspace(2)* %22, i32 %25, i32 %11 acquire acquire
+  %44 = extractvalue { i32, i1 } %43, 1
+  br i1 %44, label %51, label %49
+
+; <label>:45                                      ; preds = %39
+  %46 = extractvalue { i32, i1 } %40, 0
+  store i32 %46, i32* %23, align 4
+  br label %47
+
+; <label>:47                                      ; preds = %45, %39
+  %48 = zext i1 %41 to i8
+  br label %29
+
+; <label>:49                                      ; preds = %42
+  %50 = extractvalue { i32, i1 } %43, 0
+  store i32 %50, i32* %23, align 4
+  br label %51
+
+; <label>:51                                      ; preds = %49, %42
+  %52 = zext i1 %44 to i8
+  br label %29
+
+; <label>:53                                      ; preds = %20
+  %54 = load i32, i32* %23, align 4
+  %55 = cmpxchg weak volatile i32 addrspace(2)* %22, i32 %54, i32 %11 release monotonic
+  %56 = extractvalue { i32, i1 } %55, 1
+  br i1 %56, label %59, label %57
+
+; <label>:57                                      ; preds = %53
+  %58 = extractvalue { i32, i1 } %55, 0
+  store i32 %58, i32* %23, align 4
+  br label %59
+
+; <label>:59                                      ; preds = %57, %53
+  %60 = zext i1 %56 to i8
+  br label %29
+
+; <label>:61                                      ; preds = %26
+  %62 = cmpxchg weak volatile i32 addrspace(2)* %22, i32 %27, i32 %11 acq_rel monotonic
+  %63 = extractvalue { i32, i1 } %62, 1
+  br i1 %63, label %69, label %67
+
+; <label>:64                                      ; preds = %26
+  %65 = cmpxchg weak volatile i32 addrspace(2)* %22, i32 %27, i32 %11 acq_rel acquire
+  %66 = extractvalue { i32, i1 } %65, 1
+  br i1 %66, label %73, label %71
+
+; <label>:67                                      ; preds = %61
+  %68 = extractvalue { i32, i1 } %62, 0
+  store i32 %68, i32* %23, align 4
+  br label %69
+
+; <label>:69                                      ; preds = %67, %61
+  %70 = zext i1 %63 to i8
+  br label %29
+
+; <label>:71                                      ; preds = %64
+  %72 = extractvalue { i32, i1 } %65, 0
+  store i32 %72, i32* %23, align 4
+  br label %73
+
+; <label>:73                                      ; preds = %71, %64
+  %74 = zext i1 %66 to i8
+  br label %29
+
+; <label>:75                                      ; preds = %28
+  %76 = load i32, i32* %23, align 4
+  %77 = cmpxchg weak volatile i32 addrspace(2)* %22, i32 %76, i32 %11 seq_cst monotonic
+  %78 = extractvalue { i32, i1 } %77, 1
+  br i1 %78, label %89, label %87
+
+; <label>:79                                      ; preds = %28, %28
+  %80 = load i32, i32* %23, align 4
+  %81 = cmpxchg weak volatile i32 addrspace(2)* %22, i32 %80, i32 %11 seq_cst acquire
+  %82 = extractvalue { i32, i1 } %81, 1
+  br i1 %82, label %93, label %91
+
+; <label>:83                                      ; preds = %28
+  %84 = load i32, i32* %23, align 4
+  %85 = cmpxchg weak volatile i32 addrspace(2)* %22, i32 %84, i32 %11 seq_cst seq_cst
+  %86 = extractvalue { i32, i1 } %85, 1
+  br i1 %86, label %97, label %95
+
+; <label>:87                                      ; preds = %75
+  %88 = extractvalue { i32, i1 } %77, 0
+  store i32 %88, i32* %23, align 4
+  br label %89
+
+; <label>:89                                      ; preds = %87, %75
+  %90 = zext i1 %78 to i8
+  br label %29
+
+; <label>:91                                      ; preds = %79
+  %92 = extractvalue { i32, i1 } %81, 0
+  store i32 %92, i32* %23, align 4
+  br label %93
+
+; <label>:93                                      ; preds = %91, %79
+  %94 = zext i1 %82 to i8
+  br label %29
+
+; <label>:95                                      ; preds = %83
+  %96 = extractvalue { i32, i1 } %85, 0
+  store i32 %96, i32* %23, align 4
+  br label %97
+
+; <label>:97                                      ; preds = %95, %83
+  %98 = zext i1 %86 to i8
+  br label %29
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z24pocl_atomic_store__localPVU7CLlocalU7_Atomicll12memory_order12memory_scope(i64 addrspace(2)* nocapture %object, i64 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %1 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  store atomic volatile i64 %desired, i64 addrspace(2)* %object monotonic, align 8
+  br label %2
+
+.thread1:                                         ; preds = %0
+  store atomic volatile i64 %desired, i64 addrspace(2)* %object release, align 8
+  br label %2
+
+; <label>:1                                       ; preds = %0
+  store atomic volatile i64 %desired, i64 addrspace(2)* %object seq_cst, align 8
+  br label %2
+
+; <label>:2                                       ; preds = %1, %.thread1, %.thread
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z23pocl_atomic_load__localPVU7CLlocalU7_Atomicl12memory_order12memory_scope(i64 addrspace(2)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %3 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  %1 = load atomic volatile i64, i64 addrspace(2)* %object monotonic, align 8
+  br label %5
+
+.thread1:                                         ; preds = %0
+  %2 = load atomic volatile i64, i64 addrspace(2)* %object acquire, align 8
+  br label %5
+
+; <label>:3                                       ; preds = %0
+  %4 = load atomic volatile i64, i64 addrspace(2)* %object seq_cst, align 8
+  br label %5
+
+; <label>:5                                       ; preds = %3, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %4, %3 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z27pocl_atomic_exchange__localPVU7CLlocalU7_Atomicll12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xchg i64 addrspace(2)* %object, i64 %desired monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xchg i64 addrspace(2)* %object, i64 %desired acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xchg i64 addrspace(2)* %object, i64 %desired release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xchg i64 addrspace(2)* %object, i64 %desired acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xchg i64 addrspace(2)* %object, i64 %desired seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z42pocl_atomic_compare_exchange_strong__localPVU7CLlocalU7_AtomiclPll12memory_orderS3_12memory_scope(i64 addrspace(2)* %object, i64* nocapture %expected, i64 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i64, i64* %expected, align 8
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i64, i64* %expected, align 8
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i64, i64* %expected, align 8
+  %30 = cmpxchg volatile i64 addrspace(2)* %object, i64 %29, i64 %desired monotonic monotonic
+  %31 = extractvalue { i64, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i64, i1 } %30, 0
+  store i64 %33, i64* %expected, align 8
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg volatile i64 addrspace(2)* %object, i64 %22, i64 %desired acquire monotonic
+  %38 = extractvalue { i64, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg volatile i64 addrspace(2)* %object, i64 %22, i64 %desired acquire acquire
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i64, i1 } %37, 0
+  store i64 %43, i64* %expected, align 8
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i64, i1 } %40, 0
+  store i64 %47, i64* %expected, align 8
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i64, i64* %expected, align 8
+  %52 = cmpxchg volatile i64 addrspace(2)* %object, i64 %51, i64 %desired release monotonic
+  %53 = extractvalue { i64, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i64, i1 } %52, 0
+  store i64 %55, i64* %expected, align 8
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg volatile i64 addrspace(2)* %object, i64 %24, i64 %desired acq_rel monotonic
+  %60 = extractvalue { i64, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg volatile i64 addrspace(2)* %object, i64 %24, i64 %desired acq_rel acquire
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i64, i1 } %59, 0
+  store i64 %65, i64* %expected, align 8
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i64, i1 } %62, 0
+  store i64 %69, i64* %expected, align 8
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i64, i64* %expected, align 8
+  %74 = cmpxchg volatile i64 addrspace(2)* %object, i64 %73, i64 %desired seq_cst monotonic
+  %75 = extractvalue { i64, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i64, i64* %expected, align 8
+  %78 = cmpxchg volatile i64 addrspace(2)* %object, i64 %77, i64 %desired seq_cst acquire
+  %79 = extractvalue { i64, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i64, i64* %expected, align 8
+  %82 = cmpxchg volatile i64 addrspace(2)* %object, i64 %81, i64 %desired seq_cst seq_cst
+  %83 = extractvalue { i64, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i64, i1 } %74, 0
+  store i64 %85, i64* %expected, align 8
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i64, i1 } %78, 0
+  store i64 %89, i64* %expected, align 8
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i64, i1 } %82, 0
+  store i64 %93, i64* %expected, align 8
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z40pocl_atomic_compare_exchange_weak__localPVU7CLlocalU7_AtomiclPll12memory_orderS3_12memory_scope(i64 addrspace(2)* %object, i64* nocapture %expected, i64 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i64, i64* %expected, align 8
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i64, i64* %expected, align 8
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i64, i64* %expected, align 8
+  %30 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %29, i64 %desired monotonic monotonic
+  %31 = extractvalue { i64, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i64, i1 } %30, 0
+  store i64 %33, i64* %expected, align 8
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %22, i64 %desired acquire monotonic
+  %38 = extractvalue { i64, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %22, i64 %desired acquire acquire
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i64, i1 } %37, 0
+  store i64 %43, i64* %expected, align 8
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i64, i1 } %40, 0
+  store i64 %47, i64* %expected, align 8
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i64, i64* %expected, align 8
+  %52 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %51, i64 %desired release monotonic
+  %53 = extractvalue { i64, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i64, i1 } %52, 0
+  store i64 %55, i64* %expected, align 8
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %24, i64 %desired acq_rel monotonic
+  %60 = extractvalue { i64, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %24, i64 %desired acq_rel acquire
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i64, i1 } %59, 0
+  store i64 %65, i64* %expected, align 8
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i64, i1 } %62, 0
+  store i64 %69, i64* %expected, align 8
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i64, i64* %expected, align 8
+  %74 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %73, i64 %desired seq_cst monotonic
+  %75 = extractvalue { i64, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i64, i64* %expected, align 8
+  %78 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %77, i64 %desired seq_cst acquire
+  %79 = extractvalue { i64, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i64, i64* %expected, align 8
+  %82 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %81, i64 %desired seq_cst seq_cst
+  %83 = extractvalue { i64, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i64, i1 } %74, 0
+  store i64 %85, i64* %expected, align 8
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i64, i1 } %78, 0
+  store i64 %89, i64* %expected, align 8
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i64, i1 } %82, 0
+  store i64 %93, i64* %expected, align 8
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_add__localPVU7CLlocalU7_Atomicll12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile add i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile add i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile add i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile add i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile add i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_sub__localPVU7CLlocalU7_Atomicll12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile sub i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile sub i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile sub i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile sub i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile sub i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z27pocl_atomic_fetch_or__localPVU7CLlocalU7_Atomicll12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile or i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile or i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile or i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile or i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile or i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_xor__localPVU7CLlocalU7_Atomicll12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xor i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xor i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xor i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xor i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xor i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_and__localPVU7CLlocalU7_Atomicll12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile and i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile and i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile and i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile and i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile and i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: noreturn nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_min__localPVU7CLlocalU7_Atomicll12memory_order12memory_scope(i64 addrspace(2)* nocapture readnone %object, i64 %operand, i32 %order, i32 %scope) #1 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile min i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile min i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile min i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile min i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile min i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: noreturn nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_max__localPVU7CLlocalU7_Atomicll12memory_order12memory_scope(i64 addrspace(2)* nocapture readnone %object, i64 %operand, i32 %order, i32 %scope) #1 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile max i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile max i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile max i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile max i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile max i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z24pocl_atomic_store__localPVU7CLlocalU7_Atomicmm12memory_order12memory_scope(i64 addrspace(2)* nocapture %object, i64 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %1 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  store atomic volatile i64 %desired, i64 addrspace(2)* %object monotonic, align 8
+  br label %2
+
+.thread1:                                         ; preds = %0
+  store atomic volatile i64 %desired, i64 addrspace(2)* %object release, align 8
+  br label %2
+
+; <label>:1                                       ; preds = %0
+  store atomic volatile i64 %desired, i64 addrspace(2)* %object seq_cst, align 8
+  br label %2
+
+; <label>:2                                       ; preds = %1, %.thread1, %.thread
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z23pocl_atomic_load__localPVU7CLlocalU7_Atomicm12memory_order12memory_scope(i64 addrspace(2)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %3 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+    i32 3, label %.thread
+  ]
+
+.thread:                                          ; preds = %0, %0, %0
+  %1 = load atomic volatile i64, i64 addrspace(2)* %object monotonic, align 8
+  br label %5
+
+.thread1:                                         ; preds = %0
+  %2 = load atomic volatile i64, i64 addrspace(2)* %object acquire, align 8
+  br label %5
+
+; <label>:3                                       ; preds = %0
+  %4 = load atomic volatile i64, i64 addrspace(2)* %object seq_cst, align 8
+  br label %5
+
+; <label>:5                                       ; preds = %3, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %4, %3 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z27pocl_atomic_exchange__localPVU7CLlocalU7_Atomicmm12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xchg i64 addrspace(2)* %object, i64 %desired monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xchg i64 addrspace(2)* %object, i64 %desired acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xchg i64 addrspace(2)* %object, i64 %desired release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xchg i64 addrspace(2)* %object, i64 %desired acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xchg i64 addrspace(2)* %object, i64 %desired seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z42pocl_atomic_compare_exchange_strong__localPVU7CLlocalU7_AtomicmPmm12memory_orderS3_12memory_scope(i64 addrspace(2)* %object, i64* nocapture %expected, i64 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i64, i64* %expected, align 8
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i64, i64* %expected, align 8
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i64, i64* %expected, align 8
+  %30 = cmpxchg volatile i64 addrspace(2)* %object, i64 %29, i64 %desired monotonic monotonic
+  %31 = extractvalue { i64, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i64, i1 } %30, 0
+  store i64 %33, i64* %expected, align 8
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg volatile i64 addrspace(2)* %object, i64 %22, i64 %desired acquire monotonic
+  %38 = extractvalue { i64, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg volatile i64 addrspace(2)* %object, i64 %22, i64 %desired acquire acquire
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i64, i1 } %37, 0
+  store i64 %43, i64* %expected, align 8
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i64, i1 } %40, 0
+  store i64 %47, i64* %expected, align 8
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i64, i64* %expected, align 8
+  %52 = cmpxchg volatile i64 addrspace(2)* %object, i64 %51, i64 %desired release monotonic
+  %53 = extractvalue { i64, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i64, i1 } %52, 0
+  store i64 %55, i64* %expected, align 8
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg volatile i64 addrspace(2)* %object, i64 %24, i64 %desired acq_rel monotonic
+  %60 = extractvalue { i64, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg volatile i64 addrspace(2)* %object, i64 %24, i64 %desired acq_rel acquire
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i64, i1 } %59, 0
+  store i64 %65, i64* %expected, align 8
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i64, i1 } %62, 0
+  store i64 %69, i64* %expected, align 8
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i64, i64* %expected, align 8
+  %74 = cmpxchg volatile i64 addrspace(2)* %object, i64 %73, i64 %desired seq_cst monotonic
+  %75 = extractvalue { i64, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i64, i64* %expected, align 8
+  %78 = cmpxchg volatile i64 addrspace(2)* %object, i64 %77, i64 %desired seq_cst acquire
+  %79 = extractvalue { i64, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i64, i64* %expected, align 8
+  %82 = cmpxchg volatile i64 addrspace(2)* %object, i64 %81, i64 %desired seq_cst seq_cst
+  %83 = extractvalue { i64, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i64, i1 } %74, 0
+  store i64 %85, i64* %expected, align 8
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i64, i1 } %78, 0
+  store i64 %89, i64* %expected, align 8
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i64, i1 } %82, 0
+  store i64 %93, i64* %expected, align 8
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z40pocl_atomic_compare_exchange_weak__localPVU7CLlocalU7_AtomicmPmm12memory_orderS3_12memory_scope(i64 addrspace(2)* %object, i64* nocapture %expected, i64 %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = icmp eq i32 %failure, 0
+  br i1 %11, label %19, label %12
+
+; <label>:12                                      ; preds = %9
+  %13 = icmp eq i32 %failure, 1
+  br i1 %13, label %19, label %14
+
+; <label>:14                                      ; preds = %12
+  %15 = icmp eq i32 %failure, 2
+  br i1 %15, label %19, label %16
+
+; <label>:16                                      ; preds = %14
+  %17 = icmp eq i32 %failure, 3
+  %18 = select i1 %17, i32 4, i32 5
+  br label %19
+
+; <label>:19                                      ; preds = %12, %14, %16, %9
+  %20 = phi i32 [ 0, %9 ], [ 2, %12 ], [ %18, %16 ], [ 3, %14 ]
+  switch i32 %10, label %28 [
+    i32 1, label %21
+    i32 2, label %21
+    i32 3, label %50
+    i32 4, label %23
+    i32 5, label %25
+  ]
+
+; <label>:21                                      ; preds = %19, %19
+  %.off = add nsw i32 %20, -1
+  %switch = icmp ult i32 %.off, 2
+  %22 = load i64, i64* %expected, align 8
+  br i1 %switch, label %39, label %36
+
+; <label>:23                                      ; preds = %19
+  %.off1 = add nsw i32 %20, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %24 = load i64, i64* %expected, align 8
+  br i1 %switch2, label %61, label %58
+
+; <label>:25                                      ; preds = %19
+  switch i32 %20, label %72 [
+    i32 1, label %76
+    i32 2, label %76
+    i32 5, label %80
+  ]
+
+; <label>:26                                      ; preds = %86, %90, %94, %66, %70, %44, %48, %56, %34
+  %.0 = phi i8 [ %35, %34 ], [ %87, %86 ], [ %95, %94 ], [ %91, %90 ], [ %71, %70 ], [ %67, %66 ], [ %57, %56 ], [ %49, %48 ], [ %45, %44 ]
+  %27 = icmp ne i8 %.0, 0
+  ret i1 %27
+
+; <label>:28                                      ; preds = %19
+  %29 = load i64, i64* %expected, align 8
+  %30 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %29, i64 %desired monotonic monotonic
+  %31 = extractvalue { i64, i1 } %30, 1
+  br i1 %31, label %34, label %32
+
+; <label>:32                                      ; preds = %28
+  %33 = extractvalue { i64, i1 } %30, 0
+  store i64 %33, i64* %expected, align 8
+  br label %34
+
+; <label>:34                                      ; preds = %32, %28
+  %35 = zext i1 %31 to i8
+  br label %26
+
+; <label>:36                                      ; preds = %21
+  %37 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %22, i64 %desired acquire monotonic
+  %38 = extractvalue { i64, i1 } %37, 1
+  br i1 %38, label %44, label %42
+
+; <label>:39                                      ; preds = %21
+  %40 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %22, i64 %desired acquire acquire
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %48, label %46
+
+; <label>:42                                      ; preds = %36
+  %43 = extractvalue { i64, i1 } %37, 0
+  store i64 %43, i64* %expected, align 8
+  br label %44
+
+; <label>:44                                      ; preds = %42, %36
+  %45 = zext i1 %38 to i8
+  br label %26
+
+; <label>:46                                      ; preds = %39
+  %47 = extractvalue { i64, i1 } %40, 0
+  store i64 %47, i64* %expected, align 8
+  br label %48
+
+; <label>:48                                      ; preds = %46, %39
+  %49 = zext i1 %41 to i8
+  br label %26
+
+; <label>:50                                      ; preds = %19
+  %51 = load i64, i64* %expected, align 8
+  %52 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %51, i64 %desired release monotonic
+  %53 = extractvalue { i64, i1 } %52, 1
+  br i1 %53, label %56, label %54
+
+; <label>:54                                      ; preds = %50
+  %55 = extractvalue { i64, i1 } %52, 0
+  store i64 %55, i64* %expected, align 8
+  br label %56
+
+; <label>:56                                      ; preds = %54, %50
+  %57 = zext i1 %53 to i8
+  br label %26
+
+; <label>:58                                      ; preds = %23
+  %59 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %24, i64 %desired acq_rel monotonic
+  %60 = extractvalue { i64, i1 } %59, 1
+  br i1 %60, label %66, label %64
+
+; <label>:61                                      ; preds = %23
+  %62 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %24, i64 %desired acq_rel acquire
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %70, label %68
+
+; <label>:64                                      ; preds = %58
+  %65 = extractvalue { i64, i1 } %59, 0
+  store i64 %65, i64* %expected, align 8
+  br label %66
+
+; <label>:66                                      ; preds = %64, %58
+  %67 = zext i1 %60 to i8
+  br label %26
+
+; <label>:68                                      ; preds = %61
+  %69 = extractvalue { i64, i1 } %62, 0
+  store i64 %69, i64* %expected, align 8
+  br label %70
+
+; <label>:70                                      ; preds = %68, %61
+  %71 = zext i1 %63 to i8
+  br label %26
+
+; <label>:72                                      ; preds = %25
+  %73 = load i64, i64* %expected, align 8
+  %74 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %73, i64 %desired seq_cst monotonic
+  %75 = extractvalue { i64, i1 } %74, 1
+  br i1 %75, label %86, label %84
+
+; <label>:76                                      ; preds = %25, %25
+  %77 = load i64, i64* %expected, align 8
+  %78 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %77, i64 %desired seq_cst acquire
+  %79 = extractvalue { i64, i1 } %78, 1
+  br i1 %79, label %90, label %88
+
+; <label>:80                                      ; preds = %25
+  %81 = load i64, i64* %expected, align 8
+  %82 = cmpxchg weak volatile i64 addrspace(2)* %object, i64 %81, i64 %desired seq_cst seq_cst
+  %83 = extractvalue { i64, i1 } %82, 1
+  br i1 %83, label %94, label %92
+
+; <label>:84                                      ; preds = %72
+  %85 = extractvalue { i64, i1 } %74, 0
+  store i64 %85, i64* %expected, align 8
+  br label %86
+
+; <label>:86                                      ; preds = %84, %72
+  %87 = zext i1 %75 to i8
+  br label %26
+
+; <label>:88                                      ; preds = %76
+  %89 = extractvalue { i64, i1 } %78, 0
+  store i64 %89, i64* %expected, align 8
+  br label %90
+
+; <label>:90                                      ; preds = %88, %76
+  %91 = zext i1 %79 to i8
+  br label %26
+
+; <label>:92                                      ; preds = %80
+  %93 = extractvalue { i64, i1 } %82, 0
+  store i64 %93, i64* %expected, align 8
+  br label %94
+
+; <label>:94                                      ; preds = %92, %80
+  %95 = zext i1 %83 to i8
+  br label %26
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_add__localPVU7CLlocalU7_Atomicmm12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile add i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile add i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile add i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile add i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile add i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_sub__localPVU7CLlocalU7_Atomicmm12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile sub i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile sub i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile sub i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile sub i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile sub i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z27pocl_atomic_fetch_or__localPVU7CLlocalU7_Atomicmm12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile or i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile or i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile or i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile or i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile or i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_xor__localPVU7CLlocalU7_Atomicmm12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile xor i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile xor i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile xor i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile xor i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile xor i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_and__localPVU7CLlocalU7_Atomicmm12memory_order12memory_scope(i64 addrspace(2)* %object, i64 %operand, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile and i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile and i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile and i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile and i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile and i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: noreturn nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_min__localPVU7CLlocalU7_Atomicmm12memory_order12memory_scope(i64 addrspace(2)* nocapture readnone %object, i64 %operand, i32 %order, i32 %scope) #1 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile umin i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile umin i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile umin i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile umin i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile umin i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: noreturn nounwind uwtable
+define i64 @_Z28pocl_atomic_fetch_max__localPVU7CLlocalU7_Atomicmm12memory_order12memory_scope(i64 addrspace(2)* nocapture readnone %object, i64 %operand, i32 %order, i32 %scope) #1 {
+  switch i32 %order, label %6 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread2
+    i32 3, label %4
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = atomicrmw volatile umax i64 addrspace(2)* %object, i64 %operand monotonic
+  br label %8
+
+.thread1:                                         ; preds = %0
+  %2 = atomicrmw volatile umax i64 addrspace(2)* %object, i64 %operand acquire
+  br label %8
+
+.thread2:                                         ; preds = %0
+  %3 = atomicrmw volatile umax i64 addrspace(2)* %object, i64 %operand release
+  br label %8
+
+; <label>:4                                       ; preds = %0
+  %5 = atomicrmw volatile umax i64 addrspace(2)* %object, i64 %operand acq_rel
+  br label %8
+
+; <label>:6                                       ; preds = %0
+  %7 = atomicrmw volatile umax i64 addrspace(2)* %object, i64 %operand seq_cst
+  br label %8
+
+; <label>:8                                       ; preds = %6, %4, %.thread2, %.thread1, %.thread
+  %.0 = phi i64 [ %1, %.thread ], [ %7, %6 ], [ %5, %4 ], [ %3, %.thread2 ], [ %2, %.thread1 ]
+  ret i64 %.0
+}
+
+; Function Attrs: nounwind uwtable
+define void @_Z24pocl_atomic_store__localPVU7CLlocalU7_Atomicdd12memory_order12memory_scope(double addrspace(2)* nocapture %object, double %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %5 [
+    i32 0, label %.thread
+    i32 1, label %.thread
+    i32 2, label %.thread1
+  ]
+
+.thread1:                                         ; preds = %0
+  %1 = bitcast double %desired to i64
+  %2 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  store atomic volatile i64 %1, i64 addrspace(2)* %2 release, align 8
+  br label %13
+
+.thread:                                          ; preds = %0, %0
+  %3 = bitcast double %desired to i64
+  %4 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  br label %9
+
+; <label>:5                                       ; preds = %0
+  %6 = icmp eq i32 %order, 3
+  %7 = bitcast double %desired to i64
+  %8 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  br i1 %6, label %9, label %12
+
+; <label>:9                                       ; preds = %5, %.thread
+  %10 = phi i64 addrspace(2)* [ %4, %.thread ], [ %8, %5 ]
+  %11 = phi i64 [ %3, %.thread ], [ %7, %5 ]
+  store atomic volatile i64 %11, i64 addrspace(2)* %10 monotonic, align 8
+  br label %13
+
+; <label>:12                                      ; preds = %5
+  store atomic volatile i64 %7, i64 addrspace(2)* %8 seq_cst, align 8
+  br label %13
+
+; <label>:13                                      ; preds = %12, %.thread1, %9
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define double @_Z23pocl_atomic_load__localPVU7CLlocalU7_Atomicd12memory_order12memory_scope(double addrspace(2)* nocapture readonly %object, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %4 [
+    i32 0, label %.thread
+    i32 1, label %.thread1
+    i32 2, label %.thread
+  ]
+
+.thread1:                                         ; preds = %0
+  %1 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  %2 = load atomic volatile i64, i64 addrspace(2)* %1 acquire, align 8
+  br label %12
+
+.thread:                                          ; preds = %0, %0
+  %3 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  br label %7
+
+; <label>:4                                       ; preds = %0
+  %5 = icmp eq i32 %order, 3
+  %6 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  br i1 %5, label %7, label %10
+
+; <label>:7                                       ; preds = %4, %.thread
+  %8 = phi i64 addrspace(2)* [ %3, %.thread ], [ %6, %4 ]
+  %9 = load atomic volatile i64, i64 addrspace(2)* %8 monotonic, align 8
+  br label %12
+
+; <label>:10                                      ; preds = %4
+  %11 = load atomic volatile i64, i64 addrspace(2)* %6 seq_cst, align 8
+  br label %12
+
+; <label>:12                                      ; preds = %10, %.thread1, %7
+  %.sroa.0.0 = phi i64 [ %9, %7 ], [ %11, %10 ], [ %2, %.thread1 ]
+  %13 = bitcast i64 %.sroa.0.0 to double
+  ret double %13
+}
+
+; Function Attrs: nounwind uwtable
+define double @_Z27pocl_atomic_exchange__localPVU7CLlocalU7_Atomicdd12memory_order12memory_scope(double addrspace(2)* %object, double %desired, i32 %order, i32 %scope) #0 {
+  switch i32 %order, label %10 [
+    i32 0, label %.thread
+    i32 1, label %.thread2
+    i32 2, label %.thread3
+  ]
+
+.thread:                                          ; preds = %0
+  %1 = bitcast double %desired to i64
+  %2 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  %3 = atomicrmw volatile xchg i64 addrspace(2)* %2, i64 %1 monotonic
+  br label %18
+
+.thread2:                                         ; preds = %0
+  %4 = bitcast double %desired to i64
+  %5 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  %6 = atomicrmw volatile xchg i64 addrspace(2)* %5, i64 %4 acquire
+  br label %18
+
+.thread3:                                         ; preds = %0
+  %7 = bitcast double %desired to i64
+  %8 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  %9 = atomicrmw volatile xchg i64 addrspace(2)* %8, i64 %7 release
+  br label %18
+
+; <label>:10                                      ; preds = %0
+  %11 = icmp eq i32 %order, 3
+  %12 = bitcast double %desired to i64
+  %13 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  br i1 %11, label %14, label %16
+
+; <label>:14                                      ; preds = %10
+  %15 = atomicrmw volatile xchg i64 addrspace(2)* %13, i64 %12 acq_rel
+  br label %18
+
+; <label>:16                                      ; preds = %10
+  %17 = atomicrmw volatile xchg i64 addrspace(2)* %13, i64 %12 seq_cst
+  br label %18
+
+; <label>:18                                      ; preds = %16, %14, %.thread3, %.thread2, %.thread
+  %.sroa.0.0 = phi i64 [ %3, %.thread ], [ %17, %16 ], [ %15, %14 ], [ %9, %.thread3 ], [ %6, %.thread2 ]
+  %19 = bitcast i64 %.sroa.0.0 to double
+  ret double %19
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z42pocl_atomic_compare_exchange_strong__localPVU7CLlocalU7_AtomicdPdd12memory_orderS3_12memory_scope(double addrspace(2)* %object, double* nocapture %expected, double %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = bitcast double %desired to i64
+  %12 = icmp eq i32 %failure, 0
+  br i1 %12, label %20, label %13
+
+; <label>:13                                      ; preds = %9
+  %14 = icmp eq i32 %failure, 1
+  br i1 %14, label %20, label %15
+
+; <label>:15                                      ; preds = %13
+  %16 = icmp eq i32 %failure, 2
+  br i1 %16, label %20, label %17
+
+; <label>:17                                      ; preds = %15
+  %18 = icmp eq i32 %failure, 3
+  %19 = select i1 %18, i32 4, i32 5
+  br label %20
+
+; <label>:20                                      ; preds = %13, %15, %17, %9
+  %21 = phi i32 [ 0, %9 ], [ 2, %13 ], [ %19, %17 ], [ 3, %15 ]
+  %22 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  %23 = bitcast double* %expected to i64*
+  switch i32 %10, label %31 [
+    i32 1, label %24
+    i32 2, label %24
+    i32 3, label %53
+    i32 4, label %26
+    i32 5, label %28
+  ]
+
+; <label>:24                                      ; preds = %20, %20
+  %.off = add nsw i32 %21, -1
+  %switch = icmp ult i32 %.off, 2
+  %25 = load i64, i64* %23, align 8
+  br i1 %switch, label %42, label %39
+
+; <label>:26                                      ; preds = %20
+  %.off1 = add nsw i32 %21, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %27 = load i64, i64* %23, align 8
+  br i1 %switch2, label %64, label %61
+
+; <label>:28                                      ; preds = %20
+  switch i32 %21, label %75 [
+    i32 1, label %79
+    i32 2, label %79
+    i32 5, label %83
+  ]
+
+; <label>:29                                      ; preds = %89, %93, %97, %69, %73, %47, %51, %59, %37
+  %.0 = phi i8 [ %38, %37 ], [ %90, %89 ], [ %98, %97 ], [ %94, %93 ], [ %74, %73 ], [ %70, %69 ], [ %60, %59 ], [ %52, %51 ], [ %48, %47 ]
+  %30 = icmp ne i8 %.0, 0
+  ret i1 %30
+
+; <label>:31                                      ; preds = %20
+  %32 = load i64, i64* %23, align 8
+  %33 = cmpxchg volatile i64 addrspace(2)* %22, i64 %32, i64 %11 monotonic monotonic
+  %34 = extractvalue { i64, i1 } %33, 1
+  br i1 %34, label %37, label %35
+
+; <label>:35                                      ; preds = %31
+  %36 = extractvalue { i64, i1 } %33, 0
+  store i64 %36, i64* %23, align 8
+  br label %37
+
+; <label>:37                                      ; preds = %35, %31
+  %38 = zext i1 %34 to i8
+  br label %29
+
+; <label>:39                                      ; preds = %24
+  %40 = cmpxchg volatile i64 addrspace(2)* %22, i64 %25, i64 %11 acquire monotonic
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %47, label %45
+
+; <label>:42                                      ; preds = %24
+  %43 = cmpxchg volatile i64 addrspace(2)* %22, i64 %25, i64 %11 acquire acquire
+  %44 = extractvalue { i64, i1 } %43, 1
+  br i1 %44, label %51, label %49
+
+; <label>:45                                      ; preds = %39
+  %46 = extractvalue { i64, i1 } %40, 0
+  store i64 %46, i64* %23, align 8
+  br label %47
+
+; <label>:47                                      ; preds = %45, %39
+  %48 = zext i1 %41 to i8
+  br label %29
+
+; <label>:49                                      ; preds = %42
+  %50 = extractvalue { i64, i1 } %43, 0
+  store i64 %50, i64* %23, align 8
+  br label %51
+
+; <label>:51                                      ; preds = %49, %42
+  %52 = zext i1 %44 to i8
+  br label %29
+
+; <label>:53                                      ; preds = %20
+  %54 = load i64, i64* %23, align 8
+  %55 = cmpxchg volatile i64 addrspace(2)* %22, i64 %54, i64 %11 release monotonic
+  %56 = extractvalue { i64, i1 } %55, 1
+  br i1 %56, label %59, label %57
+
+; <label>:57                                      ; preds = %53
+  %58 = extractvalue { i64, i1 } %55, 0
+  store i64 %58, i64* %23, align 8
+  br label %59
+
+; <label>:59                                      ; preds = %57, %53
+  %60 = zext i1 %56 to i8
+  br label %29
+
+; <label>:61                                      ; preds = %26
+  %62 = cmpxchg volatile i64 addrspace(2)* %22, i64 %27, i64 %11 acq_rel monotonic
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %69, label %67
+
+; <label>:64                                      ; preds = %26
+  %65 = cmpxchg volatile i64 addrspace(2)* %22, i64 %27, i64 %11 acq_rel acquire
+  %66 = extractvalue { i64, i1 } %65, 1
+  br i1 %66, label %73, label %71
+
+; <label>:67                                      ; preds = %61
+  %68 = extractvalue { i64, i1 } %62, 0
+  store i64 %68, i64* %23, align 8
+  br label %69
+
+; <label>:69                                      ; preds = %67, %61
+  %70 = zext i1 %63 to i8
+  br label %29
+
+; <label>:71                                      ; preds = %64
+  %72 = extractvalue { i64, i1 } %65, 0
+  store i64 %72, i64* %23, align 8
+  br label %73
+
+; <label>:73                                      ; preds = %71, %64
+  %74 = zext i1 %66 to i8
+  br label %29
+
+; <label>:75                                      ; preds = %28
+  %76 = load i64, i64* %23, align 8
+  %77 = cmpxchg volatile i64 addrspace(2)* %22, i64 %76, i64 %11 seq_cst monotonic
+  %78 = extractvalue { i64, i1 } %77, 1
+  br i1 %78, label %89, label %87
+
+; <label>:79                                      ; preds = %28, %28
+  %80 = load i64, i64* %23, align 8
+  %81 = cmpxchg volatile i64 addrspace(2)* %22, i64 %80, i64 %11 seq_cst acquire
+  %82 = extractvalue { i64, i1 } %81, 1
+  br i1 %82, label %93, label %91
+
+; <label>:83                                      ; preds = %28
+  %84 = load i64, i64* %23, align 8
+  %85 = cmpxchg volatile i64 addrspace(2)* %22, i64 %84, i64 %11 seq_cst seq_cst
+  %86 = extractvalue { i64, i1 } %85, 1
+  br i1 %86, label %97, label %95
+
+; <label>:87                                      ; preds = %75
+  %88 = extractvalue { i64, i1 } %77, 0
+  store i64 %88, i64* %23, align 8
+  br label %89
+
+; <label>:89                                      ; preds = %87, %75
+  %90 = zext i1 %78 to i8
+  br label %29
+
+; <label>:91                                      ; preds = %79
+  %92 = extractvalue { i64, i1 } %81, 0
+  store i64 %92, i64* %23, align 8
+  br label %93
+
+; <label>:93                                      ; preds = %91, %79
+  %94 = zext i1 %82 to i8
+  br label %29
+
+; <label>:95                                      ; preds = %83
+  %96 = extractvalue { i64, i1 } %85, 0
+  store i64 %96, i64* %23, align 8
+  br label %97
+
+; <label>:97                                      ; preds = %95, %83
+  %98 = zext i1 %86 to i8
+  br label %29
+}
+
+; Function Attrs: nounwind uwtable
+define zeroext i1 @_Z40pocl_atomic_compare_exchange_weak__localPVU7CLlocalU7_AtomicdPdd12memory_orderS3_12memory_scope(double addrspace(2)* %object, double* nocapture %expected, double %desired, i32 %success, i32 %failure, i32 %scope) #0 {
+  %1 = icmp eq i32 %success, 0
+  br i1 %1, label %9, label %2
+
+; <label>:2                                       ; preds = %0
+  %3 = icmp eq i32 %success, 1
+  br i1 %3, label %9, label %4
+
+; <label>:4                                       ; preds = %2
+  %5 = icmp eq i32 %success, 2
+  br i1 %5, label %9, label %6
+
+; <label>:6                                       ; preds = %4
+  %7 = icmp eq i32 %success, 3
+  %8 = select i1 %7, i32 4, i32 5
+  br label %9
+
+; <label>:9                                       ; preds = %2, %4, %6, %0
+  %10 = phi i32 [ 0, %0 ], [ 2, %2 ], [ %8, %6 ], [ 3, %4 ]
+  %11 = bitcast double %desired to i64
+  %12 = icmp eq i32 %failure, 0
+  br i1 %12, label %20, label %13
+
+; <label>:13                                      ; preds = %9
+  %14 = icmp eq i32 %failure, 1
+  br i1 %14, label %20, label %15
+
+; <label>:15                                      ; preds = %13
+  %16 = icmp eq i32 %failure, 2
+  br i1 %16, label %20, label %17
+
+; <label>:17                                      ; preds = %15
+  %18 = icmp eq i32 %failure, 3
+  %19 = select i1 %18, i32 4, i32 5
+  br label %20
+
+; <label>:20                                      ; preds = %13, %15, %17, %9
+  %21 = phi i32 [ 0, %9 ], [ 2, %13 ], [ %19, %17 ], [ 3, %15 ]
+  %22 = bitcast double addrspace(2)* %object to i64 addrspace(2)*
+  %23 = bitcast double* %expected to i64*
+  switch i32 %10, label %31 [
+    i32 1, label %24
+    i32 2, label %24
+    i32 3, label %53
+    i32 4, label %26
+    i32 5, label %28
+  ]
+
+; <label>:24                                      ; preds = %20, %20
+  %.off = add nsw i32 %21, -1
+  %switch = icmp ult i32 %.off, 2
+  %25 = load i64, i64* %23, align 8
+  br i1 %switch, label %42, label %39
+
+; <label>:26                                      ; preds = %20
+  %.off1 = add nsw i32 %21, -1
+  %switch2 = icmp ult i32 %.off1, 2
+  %27 = load i64, i64* %23, align 8
+  br i1 %switch2, label %64, label %61
+
+; <label>:28                                      ; preds = %20
+  switch i32 %21, label %75 [
+    i32 1, label %79
+    i32 2, label %79
+    i32 5, label %83
+  ]
+
+; <label>:29                                      ; preds = %89, %93, %97, %69, %73, %47, %51, %59, %37
+  %.0 = phi i8 [ %38, %37 ], [ %90, %89 ], [ %98, %97 ], [ %94, %93 ], [ %74, %73 ], [ %70, %69 ], [ %60, %59 ], [ %52, %51 ], [ %48, %47 ]
+  %30 = icmp ne i8 %.0, 0
+  ret i1 %30
+
+; <label>:31                                      ; preds = %20
+  %32 = load i64, i64* %23, align 8
+  %33 = cmpxchg weak volatile i64 addrspace(2)* %22, i64 %32, i64 %11 monotonic monotonic
+  %34 = extractvalue { i64, i1 } %33, 1
+  br i1 %34, label %37, label %35
+
+; <label>:35                                      ; preds = %31
+  %36 = extractvalue { i64, i1 } %33, 0
+  store i64 %36, i64* %23, align 8
+  br label %37
+
+; <label>:37                                      ; preds = %35, %31
+  %38 = zext i1 %34 to i8
+  br label %29
+
+; <label>:39                                      ; preds = %24
+  %40 = cmpxchg weak volatile i64 addrspace(2)* %22, i64 %25, i64 %11 acquire monotonic
+  %41 = extractvalue { i64, i1 } %40, 1
+  br i1 %41, label %47, label %45
+
+; <label>:42                                      ; preds = %24
+  %43 = cmpxchg weak volatile i64 addrspace(2)* %22, i64 %25, i64 %11 acquire acquire
+  %44 = extractvalue { i64, i1 } %43, 1
+  br i1 %44, label %51, label %49
+
+; <label>:45                                      ; preds = %39
+  %46 = extractvalue { i64, i1 } %40, 0
+  store i64 %46, i64* %23, align 8
+  br label %47
+
+; <label>:47                                      ; preds = %45, %39
+  %48 = zext i1 %41 to i8
+  br label %29
+
+; <label>:49                                      ; preds = %42
+  %50 = extractvalue { i64, i1 } %43, 0
+  store i64 %50, i64* %23, align 8
+  br label %51
+
+; <label>:51                                      ; preds = %49, %42
+  %52 = zext i1 %44 to i8
+  br label %29
+
+; <label>:53                                      ; preds = %20
+  %54 = load i64, i64* %23, align 8
+  %55 = cmpxchg weak volatile i64 addrspace(2)* %22, i64 %54, i64 %11 release monotonic
+  %56 = extractvalue { i64, i1 } %55, 1
+  br i1 %56, label %59, label %57
+
+; <label>:57                                      ; preds = %53
+  %58 = extractvalue { i64, i1 } %55, 0
+  store i64 %58, i64* %23, align 8
+  br label %59
+
+; <label>:59                                      ; preds = %57, %53
+  %60 = zext i1 %56 to i8
+  br label %29
+
+; <label>:61                                      ; preds = %26
+  %62 = cmpxchg weak volatile i64 addrspace(2)* %22, i64 %27, i64 %11 acq_rel monotonic
+  %63 = extractvalue { i64, i1 } %62, 1
+  br i1 %63, label %69, label %67
+
+; <label>:64                                      ; preds = %26
+  %65 = cmpxchg weak volatile i64 addrspace(2)* %22, i64 %27, i64 %11 acq_rel acquire
+  %66 = extractvalue { i64, i1 } %65, 1
+  br i1 %66, label %73, label %71
+
+; <label>:67                                      ; preds = %61
+  %68 = extractvalue { i64, i1 } %62, 0
+  store i64 %68, i64* %23, align 8
+  br label %69
+
+; <label>:69                                      ; preds = %67, %61
+  %70 = zext i1 %63 to i8
+  br label %29
+
+; <label>:71                                      ; preds = %64
+  %72 = extractvalue { i64, i1 } %65, 0
+  store i64 %72, i64* %23, align 8
+  br label %73
+
+; <label>:73                                      ; preds = %71, %64
+  %74 = zext i1 %66 to i8
+  br label %29
+
+; <label>:75                                      ; preds = %28
+  %76 = load i64, i64* %23, align 8
+  %77 = cmpxchg weak volatile i64 addrspace(2)* %22, i64 %76, i64 %11 seq_cst monotonic
+  %78 = extractvalue { i64, i1 } %77, 1
+  br i1 %78, label %89, label %87
+
+; <label>:79                                      ; preds = %28, %28
+  %80 = load i64, i64* %23, align 8
+  %81 = cmpxchg weak volatile i64 addrspace(2)* %22, i64 %80, i64 %11 seq_cst acquire
+  %82 = extractvalue { i64, i1 } %81, 1
+  br i1 %82, label %93, label %91
+
+; <label>:83                                      ; preds = %28
+  %84 = load i64, i64* %23, align 8
+  %85 = cmpxchg weak volatile i64 addrspace(2)* %22, i64 %84, i64 %11 seq_cst seq_cst
+  %86 = extractvalue { i64, i1 } %85, 1
+  br i1 %86, label %97, label %95
+
+; <label>:87                                      ; preds = %75
+  %88 = extractvalue { i64, i1 } %77, 0
+  store i64 %88, i64* %23, align 8
+  br label %89
+
+; <label>:89                                      ; preds = %87, %75
+  %90 = zext i1 %78 to i8
+  br label %29
+
+; <label>:91                                      ; preds = %79
+  %92 = extractvalue { i64, i1 } %81, 0
+  store i64 %92, i64* %23, align 8
+  br label %93
+
+; <label>:93                                      ; preds = %91, %79
+  %94 = zext i1 %82 to i8
+  br label %29
+
+; <label>:95                                      ; preds = %83
+  %96 = extractvalue { i64, i1 } %85, 0
+  store i64 %96, i64* %23, align 8
+  br label %97
+
+; <label>:97                                      ; preds = %95, %83
+  %98 = zext i1 %86 to i8
+  br label %29
+}
+
+attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { noreturn nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { noreturn nounwind }
+
+!llvm.ident = !{!0}
+
+!0 = !{!"Franz clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 40b68b4c02b9d9e1e4138815747adf5589496240) (https://github.com/HSAFoundation/HLC-HSAIL-Development-LLVM.git 183de0bdbefa5664920942fa418d1efefb87faeb) (based on LLVM 3.7.0svn)"}
diff --git a/lib/kernel/write_image.cl b/lib/kernel/write_image.cl
index 8797115..ccf140a 100644
--- a/lib/kernel/write_image.cl
+++ b/lib/kernel/write_image.cl
@@ -33,6 +33,14 @@
 #define ADDRESS_SPACE
 #endif
 
+// 3.9 needs access qualifier
+// TODO: rw images
+#ifdef CLANG_OLDER_THAN_3_9
+#define IMG_WRITE_AQ
+#else
+#define IMG_WRITE_AQ __write_only
+#endif
+
 /* writes pixel to coord in image */
 void pocl_write_pixel (void* color_, ADDRESS_SPACE dev_image_t* dev_image, int4 coord)
 {  
@@ -81,13 +89,14 @@ void pocl_write_pixel (void* color_, ADDRESS_SPACE dev_image_t* dev_image, int4
 */
 #define IMPLEMENT_WRITE_IMAGE_INT_COORD(__IMGTYPE__,__DTYPE__,__POSTFIX__, \
                                         __COORD__)                      \
-  void _CL_OVERLOADABLE write_image##__POSTFIX__ (__IMGTYPE__ image,    \
+  void _CL_OVERLOADABLE write_image##__POSTFIX__ (__write_only __IMGTYPE__ image,    \
                                                   __COORD__ coord,      \
                                                   __DTYPE__ color)      \
   {                                                                     \
-  int4 coord4;                                                          \
-  INITCOORD##__COORD__(coord4, coord);                                  \
-  pocl_write_pixel (&color, *(ADDRESS_SPACE dev_image_t**)&image, coord4);                             \
+    int4 coord4;                                                        \
+    INITCOORD##__COORD__(coord4, coord);                                \
+    global dev_image_t* i_ptr = __builtin_astype (image, global dev_image_t*); \
+    pocl_write_pixel (&color, i_ptr, coord4);                             \
   }                                                                     \
 
 IMPLEMENT_WRITE_IMAGE_INT_COORD(image2d_t, uint4, ui, int2)
diff --git a/lib/llvmopencl/AutomaticLocals.cc b/lib/llvmopencl/AutomaticLocals.cc
index eee1f95..3704b0c 100644
--- a/lib/llvmopencl/AutomaticLocals.cc
+++ b/lib/llvmopencl/AutomaticLocals.cc
@@ -85,23 +85,27 @@ AutomaticLocals::runOnModule(Module &M)
   FunctionMapping kernels;
 
   string ErrorInfo;
-
+  std::vector<Function*> NewFuncs;
   for (Module::iterator mi = M.begin(), me = M.end(); mi != me; ++mi) {
+    // This is to prevent recursion with llvm 3.9. The new kernels are
+    // recognized as kernelsToProcess.
+    if (find(NewFuncs.begin(), NewFuncs.end(), &*mi) != NewFuncs.end())
+      continue;
     if (!Workgroup::isKernelToProcess(*mi))
       continue;
-  
+
     Function *F = &*mi;
 
     Function *new_kernel = ProcessAutomaticLocals(F);
     if (new_kernel != F)
       changed = true;
     kernels[F] = new_kernel;
+    NewFuncs.push_back(new_kernel);
   }
 
   if (changed)
     {
       regenerate_kernel_metadata(M, kernels);
-
       /* Delete the old kernels. */
       for (FunctionMapping::const_iterator i = kernels.begin(),
              e = kernels.end(); i != e; ++i) 
@@ -144,7 +148,7 @@ AutomaticLocals::ProcessAutomaticLocals(Function *F)
     // This kernel fingerprint has not changed.
     return F;
   }
-  
+
   // Create the new function.
   FunctionType *ft = FunctionType::get(F->getReturnType(),
                                        parameters,
diff --git a/lib/llvmopencl/BarrierTailReplication.cc b/lib/llvmopencl/BarrierTailReplication.cc
index 1f059b3..a326d8e 100644
--- a/lib/llvmopencl/BarrierTailReplication.cc
+++ b/lib/llvmopencl/BarrierTailReplication.cc
@@ -375,7 +375,9 @@ BarrierTailReplication::ReplicateBasicBlocks(BasicBlockVector &new_graph,
           
           // Get value for original incoming edge and add new predicate.
           Value *v = phi->getIncomingValueForBlock(b);
-          Value *new_v = reference_map[v];
+          Value *new_v = reference_map.find(v) == reference_map.end() ?
+            NULL : reference_map[v];
+
           if (new_v == NULL) {
             /* This case can happen at least when replicating a latch 
                block in a b-loop. The value produced might be from a common
diff --git a/lib/llvmopencl/LLVMUtils.h b/lib/llvmopencl/LLVMUtils.h
index d0a7bf0..2ac4702 100644
--- a/lib/llvmopencl/LLVMUtils.h
+++ b/lib/llvmopencl/LLVMUtils.h
@@ -58,8 +58,8 @@ is_image_type(const llvm::Type& t)
 {
   if (t.isPointerTy() && t.getPointerElementType()->isStructTy()) {
     llvm::StringRef name = t.getPointerElementType()->getStructName();
-    if (name.startswith("opencl.image2d_t") || name.startswith("opencl.image3d_t") ||
-        name.startswith("opencl.image1d_t") || name.startswith("struct._pocl_image"))
+    if (name.startswith("opencl.image2d_") || name.startswith("opencl.image3d_") ||
+        name.startswith("opencl.image1d_") || name.startswith("struct._pocl_image"))
       return true;
   }
   return false;
diff --git a/lib/llvmopencl/Workgroup.cc b/lib/llvmopencl/Workgroup.cc
index f8859ef..76c2c39 100644
--- a/lib/llvmopencl/Workgroup.cc
+++ b/lib/llvmopencl/Workgroup.cc
@@ -197,7 +197,7 @@ Workgroup::runOnModule(Module &M)
                            NULL));
   BasicBlock *bb = BasicBlock::Create(M.getContext(), "", barrier);
   ReturnInst::Create(M.getContext(), 0, bb);
-  
+
   return true;
 }
 
@@ -627,6 +627,9 @@ Workgroup::isKernelToProcess(const Function &F)
 {
   const Module *m = F.getParent();
 
+  if (F.getMetadata("kernel_arg_access_qual"))
+    return true;
+
   NamedMDNode *kernels = m->getNamedMetadata("opencl.kernels");
   if (kernels == NULL) {
     if (KernelName == "")
@@ -635,15 +638,15 @@ Workgroup::isKernelToProcess(const Function &F)
       return true;
 
     return false;
-  }  
+  }
 
   for (unsigned i = 0, e = kernels->getNumOperands(); i != e; ++i) {
     if (kernels->getOperand(i)->getOperand(0) == NULL)
       continue; // globaldce might have removed uncalled kernels
-    Function *k = 
+    Function *k =
       cast<Function>(
         dyn_cast<ValueAsMetadata>(kernels->getOperand(i)->getOperand(0))
-          ->getValue());
+        ->getValue());
     if (&F == k)
       return true;
   }
diff --git a/tests/kernel/test_bitselect.cl b/tests/kernel/test_bitselect.cl
index f6260e7..85150c2 100644
--- a/tests/kernel/test_bitselect.cl
+++ b/tests/kernel/test_bitselect.cl
@@ -1188,7 +1188,7 @@ DEFINE_BODY_G
      // abs
      equal = true;
      for (int n=0; n<vecsize; ++n) {
-       sgtype signbit = (sgtype)1 << (sgtype)(count_bits(sgtype)-1);
+       sgtype signbit = (sgtype)((sgtype)1 << (sgtype)(count_bits(sgtype)-1));
        // Note: left.s[n] < 0 leads to a compiler warning for unsigned types,
        // so we check the sign bit explicitly
        sugtype absval =
-- 
2.5.5