From bb19add030b7600773f95f677117fd107e37f5fb Mon Sep 17 00:00:00 2001
From: Sam Yates <yates@cscs.ch>
Date: Thu, 4 May 2017 09:49:15 +0200
Subject: [PATCH] Apply different, simpler work-around for icc bug. (#251)

Refer to issue #247 and pr #248.

* Replace `compat::sink()` usage with a simpler `compat::barrier_if_icc_leq`, as the icc bug also could be tickled depending on how the `sink()` code was structured.
---
 src/compartment.hpp |  2 +-
 src/util/compat.hpp | 34 +++++++++++-----------------------
 2 files changed, 12 insertions(+), 24 deletions(-)

diff --git a/src/compartment.hpp b/src/compartment.hpp
index 10c26fd1..fae0ad88 100644
--- a/src/compartment.hpp
+++ b/src/compartment.hpp
@@ -185,7 +185,7 @@ public:
         using namespace util;
 
         segs_ = make_partition(offsets_, lengths);
-        compat::sink_if_icc_leq(20160415u, segs_.bounds());
+        compat::compiler_barrier_if_icc_leq(20160415u);
 
         nseg_ = size(segs_);
         scale_ = segs_.bounds().second/n;
diff --git a/src/util/compat.hpp b/src/util/compat.hpp
index a10e8cc1..6c12be4e 100644
--- a/src/util/compat.hpp
+++ b/src/util/compat.hpp
@@ -18,7 +18,7 @@ T* end(T (&x)[N]) { return &x[0]+N; }
 template <typename T, std::size_t N>
 const T* end(const T (&x)[N]) { return &x[0]+N; }
 
-// workaround bad optimization reordering in xlC 13.1.4
+// Work-around bad optimization reordering in xlC 13.1.4.
 
 inline void compiler_barrier_if_xlc_leq(unsigned ver) {
 #if defined(__xlC__)
@@ -28,33 +28,21 @@ inline void compiler_barrier_if_xlc_leq(unsigned ver) {
 #endif
 }
 
-// Work around bad ordering of std::isinf() (sometimes) within switch, xlC 13.1.4;
-// wrapping the call within another function appears to be sufficient.
-
-template <typename X>
-inline constexpr bool isinf(X x) { return std::isinf(x); }
-
-// Work around a bad inlining-related optimization with icpc 16.0.3 and -xMIC-AVX512,
-// by forcing a computation.
-
-template <typename X>
-inline void sink(const X& x) {
-    char buf[sizeof x];
-    volatile char* bufptr = buf;
-    const char* xptr = reinterpret_cast<const char*>(&x);
-
-    for (std::size_t i = 0; i<sizeof buf; ++i) {
-        *bufptr++ = *xptr++;
-    }
-}
+// Work-around a bad inlining-related optimization with icpc 16.0.3 and -xMIC-AVX512,
 
-template <typename X>
-inline void sink_if_icc_leq(unsigned ver, const X& x) {
+inline void compiler_barrier_if_icc_leq(unsigned ver) {
 #if defined(__INTEL_COMPILER_BUILD_DATE)
     if (__INTEL_COMPILER_BUILD_DATE<=ver) {
-        sink(x);
+        asm volatile ("" ::: "memory");
     }
 #endif
 }
 
+// Work-around bad ordering of std::isinf() (sometimes) within switch, xlC 13.1.4;
+// wrapping the call within another function appears to be sufficient.
+
+template <typename X>
+inline constexpr bool isinf(X x) { return std::isinf(x); }
+
+
 } // namespace compat
-- 
GitLab