Index: llvm/trunk/include/llvm/ADT/STLExtras.h =================================================================== --- llvm/trunk/include/llvm/ADT/STLExtras.h +++ llvm/trunk/include/llvm/ADT/STLExtras.h @@ -36,6 +36,10 @@ #include #include +#ifdef EXPENSIVE_CHECKS +#include // for std::mt19937 +#endif + namespace llvm { // Only used by compiler if both template types are the same. Useful when @@ -762,6 +766,10 @@ // behavior with an empty sequence. auto NElts = End - Start; if (NElts <= 1) return; +#ifdef EXPENSIVE_CHECKS + std::mt19937 Generator(std::random_device{}()); + std::shuffle(Start, End, Generator); +#endif qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start)); } @@ -775,10 +783,34 @@ // behavior with an empty sequence. auto NElts = End - Start; if (NElts <= 1) return; +#ifdef EXPENSIVE_CHECKS + std::mt19937 Generator(std::random_device{}()); + std::shuffle(Start, End, Generator); +#endif qsort(&*Start, NElts, sizeof(*Start), reinterpret_cast(Compare)); } +// Provide wrappers to std::sort which shuffle the elements before sorting +// to help uncover non-deterministic behavior (PR35135). +template +inline void sort(IteratorTy Start, IteratorTy End) { +#ifdef EXPENSIVE_CHECKS + std::mt19937 Generator(std::random_device{}()); + std::shuffle(Start, End, Generator); +#endif + std::sort(Start, End); +} + +template +inline void sort(IteratorTy Start, IteratorTy End, Compare Comp) { +#ifdef EXPENSIVE_CHECKS + std::mt19937 Generator(std::random_device{}()); + std::shuffle(Start, End, Generator); +#endif + std::sort(Start, End, Comp); +} + //===----------------------------------------------------------------------===// // Extra additions to //===----------------------------------------------------------------------===//