diff --git a/src/algorithms.hpp b/src/algorithms.hpp
index 43893b3198bcc00591bc4301efbbdcb0159330d6..9a3ecdf7f2197e233fd2c848aa86cf124aef3a41 100644
--- a/src/algorithms.hpp
+++ b/src/algorithms.hpp
@@ -29,7 +29,7 @@ typename util::sequence_traits<C>::value_type
 sum(C const& c)
 {
     using value_type = typename util::sequence_traits<C>::value_type;
-    return std::accumulate(std::begin(c), std::end(c), value_type{0});
+    return std::accumulate(util::cbegin(c), util::cend(c), value_type{0});
 }
 
 template <typename C>
diff --git a/src/util/compat.hpp b/src/util/compat.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c288effefd8c50593ed82750714691b2dc409ba4
--- /dev/null
+++ b/src/util/compat.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+/* Collection of compatibility workarounds to deal with compiler defects */
+
+#include <cstddef>
+#include <cmath>
+
+namespace compat {
+
+// std::end() broken with (at least) xlC 13.1.4.
+
+template <typename T>
+auto end(T& x) -> decltype(x.end()) { return x.end(); }
+
+template <typename T, std::size_t N>
+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
+
+inline void compiler_barrier_if_xlc_leq(unsigned ver) {
+#if defined(__xlC__)
+    if (__xlC__<=ver) {
+        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); }
+
+}
diff --git a/src/util/iterutil.hpp b/src/util/iterutil.hpp
index 8c327d4140c24790ca7576fafb190932508524e6..00e52d628475dde475c4d9e11e849c2df6c38b73 100644
--- a/src/util/iterutil.hpp
+++ b/src/util/iterutil.hpp
@@ -10,6 +10,7 @@
 #include <type_traits>
 #include <utility>
 
+#include <util/compat.hpp>
 #include <util/meta.hpp>
 
 namespace nest {
@@ -78,7 +79,8 @@ auto front(Seq& seq) -> decltype(*std::begin(seq)) {
 
 template <typename Seq>
 auto back(Seq& seq) -> decltype(*std::begin(seq)) {
-    return *upto(std::begin(seq), std::end(seq));
+    // COMPAT: use own `end` implementation to work around xlC 13.1 bug.
+    return *upto(std::begin(seq), compat::end(seq));
 }
 
 /*
diff --git a/src/util/meta.hpp b/src/util/meta.hpp
index 3bc8d9416875af778d77db9d597859a077814b95..34b809bbfe3de94546a743f313f2cee8576e305b 100644
--- a/src/util/meta.hpp
+++ b/src/util/meta.hpp
@@ -6,6 +6,8 @@
 #include <iterator>
 #include <type_traits>
 
+#include <util/compat.hpp>
+
 namespace nest {
 namespace mc {
 namespace util {
@@ -36,8 +38,9 @@ constexpr auto cbegin(const T& c) -> decltype(std::begin(c)) {
 }
 
 template <typename T>
-constexpr auto cend(const T& c) -> decltype(std::end(c)) {
-    return std::end(c);
+constexpr auto cend(const T& c) -> decltype(compat::end(c)) {
+    // COMPAT: use own `end` implementation to work around xlC 13.1 bug.
+    return compat::end(c);
 }
 
 template <typename T>
diff --git a/src/util/uninitialized.hpp b/src/util/uninitialized.hpp
index a13842acb3fa796a86a7c76e924c779fb6e0383a..f9c1bf3685a98c5f405a3f0c0fe929adf8a182b9 100644
--- a/src/util/uninitialized.hpp
+++ b/src/util/uninitialized.hpp
@@ -12,6 +12,7 @@
 #include <type_traits>
 #include <utility>
 
+#include "util/compat.hpp"
 #include "util/meta.hpp"
 
 namespace nest {
@@ -33,8 +34,18 @@ public:
     using reference = X&;
     using const_reference= const X&;
 
-    pointer ptr() { return static_cast<X*>(static_cast<void*>(&data)); }
-    const_pointer cptr() const { return static_cast<const X*>(static_cast<const void*>(&data)); }
+    pointer ptr() {
+        // COMPAT: xlC 13.1.4 workaround:
+        // should be equivalent to `return reinterpret_cast<X*>(&data)`.
+        compat::compiler_barrier_if_xlc_leq(0x0d01);
+        return static_cast<X*>(static_cast<void*>(&data));
+    }
+    const_pointer cptr() const {
+        // COMPAT: xlC 13.1.4 workaround:
+        // should be equivalent to `return reinterpret_cast<const X*>(&data)`
+        compat::compiler_barrier_if_xlc_leq(0x0d01);
+        return static_cast<const X*>(static_cast<const void*>(&data));
+    }
 
     reference ref() { return *ptr(); }
     const_reference cref() const { return *cptr(); }
diff --git a/tests/unit/test_math.cpp b/tests/unit/test_math.cpp
index 2bae462d10e2b2a797e6cd3eb0e7ffd52f5e0dac..1a5f442f2bba5a1b04db8fd64d1c39897ac6f8f0 100644
--- a/tests/unit/test_math.cpp
+++ b/tests/unit/test_math.cpp
@@ -2,7 +2,9 @@
 #include <limits>
 
 #include "../gtest.h"
+
 #include <math.hpp>
+#include <util/compat.hpp>
 
 using namespace nest::mc::math;
 
@@ -82,17 +84,20 @@ TEST(math, infinity) {
     // check values for float, double, long double
     auto finf = infinity<float>();
     EXPECT_TRUE((std::is_same<float, decltype(finf)>::value));
-    EXPECT_TRUE(std::isinf(finf));
+    // COMPAT: use compatibility wrapper for isinf() thanks to xlC 13.1 bug.
+    EXPECT_TRUE(compat::isinf(finf));
     EXPECT_GT(finf, 0.f);
 
     auto dinf = infinity<double>();
     EXPECT_TRUE((std::is_same<double, decltype(dinf)>::value));
-    EXPECT_TRUE(std::isinf(dinf));
+    // COMPAT: use compatibility wrapper for isinf() thanks to xlC 13.1 bug.
+    EXPECT_TRUE(compat::isinf(dinf));
     EXPECT_GT(dinf, 0.0);
 
     auto ldinf = infinity<long double>();
     EXPECT_TRUE((std::is_same<long double, decltype(ldinf)>::value));
-    EXPECT_TRUE(std::isinf(ldinf));
+    // COMPAT: use compatibility wrapper for isinf() thanks to xlC 13.1 bug.
+    EXPECT_TRUE(compat::isinf(ldinf));
     EXPECT_GT(ldinf, 0.0l);
 
     // check default value promotes correctly (i.e., acts like INFINITY)